@@ -82,6 +82,9 @@ ifeq ($(TIMESYNC),1)
8282endif
8383
8484OS = $(shell uname -s)
85+ ARCH = $(shell uname -m)
86+ DEBIAN_DIST ?= bookworm
87+ ROOTFS_DIR = linux-sysroot
8588
8689KRUN_BINARY_Linux = libkrun$(VARIANT ) .so.$(FULL_VERSION )
8790KRUN_SONAME_Linux = libkrun$(VARIANT ) .so.$(ABI_VERSION )
@@ -103,22 +106,70 @@ ifeq ($(PREFIX),)
103106 PREFIX := /usr/local
104107endif
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
108111all : $(LIBRARY_RELEASE_$(OS ) ) libkrun.pc
109112
110113debug : $(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+
112131ifeq ($(BUILD_INIT ) ,1)
113132INIT_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 )
116135endif
117136
118137NITRO_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 )
124175ifeq ($(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+
178231test-prefix/lib64/libkrun.pc : $(LIBRARY_RELEASE_$(OS ) )
179232 mkdir -p test-prefix
180233 PREFIX=" $$ (realpath test-prefix)" make install
0 commit comments