Skip to content

Commit 44fe919

Browse files
committed
Makefile: cross-compile init.c on macOS with clang, lld and an auto-generated sysroot
Signed-off-by: Jan Noha <nohajc@gmail.com>
1 parent 8b52118 commit 44fe919

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ examples/nitro
1717
examples/consoles
1818
examples/rootfs_fedora
1919
test-prefix
20+
/linux-sysroot

Makefile

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ ifeq ($(TIMESYNC),1)
8282
endif
8383

8484
OS = $(shell uname -s)
85+
ARCH = $(shell uname -m)
86+
DEBIAN_DIST ?= bookworm
87+
ROOTFS_DIR = linux-sysroot
8588

8689
KRUN_BINARY_Linux = libkrun$(VARIANT).so.$(FULL_VERSION)
8790
KRUN_SONAME_Linux = libkrun$(VARIANT).so.$(ABI_VERSION)
@@ -103,22 +106,70 @@ ifeq ($(PREFIX),)
103106
PREFIX := /usr/local
104107
endif
105108

106-
.PHONY: install clean test test-prefix $(LIBRARY_RELEASE_$(OS)) $(LIBRARY_DEBUG_$(OS)) libkrun.pc
109+
.PHONY: install clean test test-prefix $(LIBRARY_RELEASE_$(OS)) $(LIBRARY_DEBUG_$(OS)) libkrun.pc clean-sysroot clean-all
107110

108111
all: $(LIBRARY_RELEASE_$(OS)) libkrun.pc
109112

110113
debug: $(LIBRARY_DEBUG_$(OS)) libkrun.pc
111114

115+
ifeq ($(OS),Darwin)
116+
# If SYSROOT_LINUX is not set and we're on macOS, generate sysroot automatically
117+
ifeq ($(SYSROOT_LINUX),)
118+
SYSROOT_LINUX = $(ROOTFS_DIR)
119+
SYSROOT_TARGET = $(ROOTFS_DIR)/.sysroot_ready
120+
else
121+
SYSROOT_TARGET =
122+
endif
123+
# Cross-compile on macOS with the LLVM linker (brew install lld)
124+
CC_LINUX=/usr/bin/clang -target $(ARCH)-linux-gnu -fuse-ld=lld -Wl,-strip-debug --sysroot $(SYSROOT_LINUX) -Wno-c23-extensions
125+
else
126+
# Build on Linux host
127+
CC_LINUX=$(CC)
128+
SYSROOT_TARGET =
129+
endif
130+
112131
ifeq ($(BUILD_INIT),1)
113132
INIT_BINARY = init/init
114-
$(INIT_BINARY): $(INIT_SRC)
115-
$(CC) -O2 -static -Wall $(INIT_DEFS) -o $@ $(INIT_SRC) $(INIT_DEFS)
133+
$(INIT_BINARY): $(INIT_SRC) $(SYSROOT_TARGET)
134+
$(CC_LINUX) -O2 -static -Wall $(INIT_DEFS) -o $@ $(INIT_SRC) $(INIT_DEFS)
116135
endif
117136

118137
NITRO_INIT_BINARY= init/nitro/init
119138
$(NITRO_INIT_BINARY): $(NITRO_INIT_SRC)
120139
$(CC) -O2 -static -Wall $(NITRO_INIT_LD_FLAGS) -o $@ $(NITRO_INIT_SRC) $(NITRO_INIT_LD_FLAGS)
121140

141+
# Sysroot preparation rules for cross-compilation on macOS
142+
DEBIAN_PACKAGES = libc6 libc6-dev libgcc-12-dev linux-libc-dev
143+
ROOTFS_TMP = $(ROOTFS_DIR)/.tmp
144+
PACKAGES_FILE = $(ROOTFS_TMP)/Packages.xz
145+
146+
.INTERMEDIATE: $(PACKAGES_FILE)
147+
148+
$(ROOTFS_DIR)/.sysroot_ready: $(PACKAGES_FILE)
149+
@echo "Extracting Debian packages to $(ROOTFS_DIR)..."
150+
@for pkg in $(DEBIAN_PACKAGES); do \
151+
DEB_PATH=$$(xzcat $(PACKAGES_FILE) | sed '1,/Package: '$$pkg'$$/d' | grep Filename: | sed 's/^Filename: //' | head -n1); \
152+
DEB_URL="https://deb.debian.org/debian/$$DEB_PATH"; \
153+
DEB_NAME=$$(basename "$$DEB_PATH"); \
154+
if [ ! -f "$(ROOTFS_TMP)/$$DEB_NAME" ]; then \
155+
echo "Downloading $$DEB_URL"; \
156+
curl -fL -o "$(ROOTFS_TMP)/$$DEB_NAME" "$$DEB_URL"; \
157+
fi; \
158+
cd $(ROOTFS_TMP) && ar x "$$DEB_NAME" && cd ../..; \
159+
tar xf $(ROOTFS_TMP)/data.tar.* -C $(ROOTFS_DIR); \
160+
rm -f $(ROOTFS_TMP)/*.deb $(ROOTFS_TMP)/data.tar.* $(ROOTFS_TMP)/control.tar.* $(ROOTFS_TMP)/debian-binary; \
161+
done
162+
@touch $@
163+
164+
$(PACKAGES_FILE):
165+
@echo "Downloading Debian package index for $(DEBIAN_DIST)/$(ARCH)..."
166+
@mkdir -p $(ROOTFS_TMP)
167+
@curl -fL -o $@ https://deb.debian.org/debian/dists/$(DEBIAN_DIST)/main/binary-$(ARCH)/Packages.xz
168+
169+
clean-sysroot:
170+
rm -rf $(ROOTFS_DIR)
171+
172+
122173
$(LIBRARY_RELEASE_$(OS)): $(INIT_BINARY)
123174
cargo build --release $(FEATURE_FLAGS)
124175
ifeq ($(SEV),1)
@@ -175,6 +226,8 @@ clean:
175226
rm -rf test-prefix
176227
cd tests; cargo clean
177228

229+
clean-all: clean clean-sysroot
230+
178231
test-prefix/lib64/libkrun.pc: $(LIBRARY_RELEASE_$(OS))
179232
mkdir -p test-prefix
180233
PREFIX="$$(realpath test-prefix)" make install

0 commit comments

Comments
 (0)