From 2fffaec5cfb3056f2abb9b5999f51a022c8216c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Sat, 7 Mar 2026 06:12:05 -0800 Subject: [PATCH 1/3] devices: work with proper paths in build script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We shouldn't stringify paths, because not all paths are valid UTF-8 strings, meaning we could fail operations spuriously. Work with proper Rust paths to not run into such issues. Signed-off-by: Daniel Müller --- src/devices/build.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/devices/build.rs b/src/devices/build.rs index 1f9d16132..229c2a269 100644 --- a/src/devices/build.rs +++ b/src/devices/build.rs @@ -1,10 +1,15 @@ +use std::path::PathBuf; + fn main() { - let init_binary_path = std::env::var("KRUN_INIT_BINARY_PATH").unwrap_or_else(|_| { - format!( - "{}/../../init/init", - std::env::var("CARGO_MANIFEST_DIR").unwrap() - ) - }); - println!("cargo:rustc-env=KRUN_INIT_BINARY_PATH={init_binary_path}"); + let init_binary_path = std::env::var_os("KRUN_INIT_BINARY_PATH") + .map(PathBuf::from) + .unwrap_or_else(|| { + let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); + manifest_dir.join("../../init/init") + }); + println!( + "cargo:rustc-env=KRUN_INIT_BINARY_PATH={}", + init_binary_path.display() + ); println!("cargo:rerun-if-env-changed=KRUN_INIT_BINARY_PATH"); } From b22a7163b217974150662224166ad1ac9ed525e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Tue, 10 Mar 2026 09:04:26 -0700 Subject: [PATCH 2/3] devices: simplify Makefile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the SEV or TDX environment variables are 1, we set BUILD_INIT to 0. Unless BUILD_INIT is 1, we don't actually build the init binary, which is the only part of the Makefile that uses INIT_DEFS and INIT_SRC. As such, there seems to be no point in setting both INIT_DEFS and INIT_SRC from the code paths used when SEV or TDX are 1. Remove these assignments. That in turn also allows us to remove the KBS_INIT_SRC, KBS_LD_FLAGS, and SNP_INIT_SRC variables. TDX_INIT_SRC seems to have been unused all along. Signed-off-by: Daniel Müller --- Makefile | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 4af236b01..7f09e7ba2 100644 --- a/Makefile +++ b/Makefile @@ -6,17 +6,6 @@ ABI_VERSION=1 FULL_VERSION=1.17.3 INIT_SRC = init/init.c -KBS_INIT_SRC = init/tee/kbs/kbs.h \ - init/tee/kbs/kbs_util.c \ - init/tee/kbs/kbs_types.c \ - init/tee/kbs/kbs_curl.c \ - init/tee/kbs/kbs_crypto.c \ - -SNP_INIT_SRC = init/tee/snp_attest.c \ - init/tee/snp_attest.h \ - $(KBS_INIT_SRC) \ - -TDX_INIT_SRC = $(KBS_INIT_SRC) AWS_NITRO_INIT_SRC = \ init/aws-nitro/include/* \ init/aws-nitro/main.c \ @@ -30,9 +19,6 @@ AWS_NITRO_INIT_SRC = \ init/aws-nitro/device/net_tap_afvsock.c \ init/aws-nitro/device/signal.c \ -KBS_LD_FLAGS = -lcurl -lidn2 -lssl -lcrypto -lzstd -lz -lbrotlidec-static \ - -lbrotlicommon-static - AWS_NITRO_INIT_LD_FLAGS = -larchive -lnsm BUILD_INIT = 1 @@ -40,17 +26,11 @@ INIT_DEFS = ifeq ($(SEV),1) VARIANT = -sev FEATURE_FLAGS := --features amd-sev - INIT_DEFS += -DSEV=1 - INIT_DEFS += $(KBS_LD_FLAGS) - INIT_SRC += $(SNP_INIT_SRC) - BUILD_INIT = 0 + BUILD_INIT = 0 endif ifeq ($(TDX),1) VARIANT = -tdx FEATURE_FLAGS := --features tdx - INIT_DEFS += -DTDX=1 - INIT_DEFS += $(KBS_LD_FLAGS) - INIT_SRC += $(KBS_INIT_SRC) BUILD_INIT = 0 endif ifeq ($(VIRGL_RESOURCE_MAP2),1) From 205dadac5f3f0d18ebe8e3caa9e2e31c51c1cc9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Tue, 10 Mar 2026 09:18:17 -0700 Subject: [PATCH 3/3] devices: build init binary as part of build script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build the default init binary automatically from a Rust build script, instead of from the Makefile. Doing so is a stepping stone to consuming the crate from Cargo. We do build the init binary unconditionally compared to before to not duplicate the logic overly much. But I would think that's not an issue. We keep supporting cross-compilation from MacOS when using the Makefile as before. Signed-off-by: Daniel Müller --- .github/workflows/code-quality.yml | 2 ++ Makefile | 23 +++------------ src/devices/build.rs | 47 +++++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 23 deletions(-) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index b6a29db2e..d79b440ae 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -58,6 +58,8 @@ jobs: - name: Clippy (efi+gpu) run: cargo clippy --locked --features efi,gpu -- -D warnings + env: + KRUN_INIT_BINARY_PATH: ${{ github.workspace }}/init/init code-quality-examples: name: ${{ matrix.name }} diff --git a/Makefile b/Makefile index 7f09e7ba2..bc5aaf726 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,6 @@ LIBRARY_HEADER_INPUT = include/libkrun_input.h ABI_VERSION=1 FULL_VERSION=1.17.3 -INIT_SRC = init/init.c AWS_NITRO_INIT_SRC = \ init/aws-nitro/include/* \ init/aws-nitro/main.c \ @@ -21,17 +20,13 @@ AWS_NITRO_INIT_SRC = \ AWS_NITRO_INIT_LD_FLAGS = -larchive -lnsm -BUILD_INIT = 1 -INIT_DEFS = ifeq ($(SEV),1) VARIANT = -sev FEATURE_FLAGS := --features amd-sev - BUILD_INIT = 0 endif ifeq ($(TDX),1) VARIANT = -tdx FEATURE_FLAGS := --features tdx - BUILD_INIT = 0 endif ifeq ($(VIRGL_RESOURCE_MAP2),1) FEATURE_FLAGS += --features virgl_resource_map2 @@ -45,7 +40,6 @@ endif ifeq ($(EFI),1) VARIANT = -efi FEATURE_FLAGS := --features efi # EFI Implies blk and net - BUILD_INIT = 0 endif ifeq ($(GPU),1) FEATURE_FLAGS += --features gpu @@ -59,11 +53,6 @@ endif ifeq ($(AWS_NITRO),1) VARIANT = -awsnitro FEATURE_FLAGS := --features aws-nitro,net - BUILD_INIT = 0 -endif - -ifeq ($(TIMESYNC),1) - INIT_DEFS += -D__TIMESYNC__ endif OS = $(shell uname -s) @@ -113,11 +102,8 @@ else SYSROOT_TARGET = endif -ifeq ($(BUILD_INIT),1) -INIT_BINARY = init/init -$(INIT_BINARY): $(INIT_SRC) $(SYSROOT_TARGET) - $(CC_LINUX) -O2 -static -Wall $(INIT_DEFS) -o $@ $(INIT_SRC) $(INIT_DEFS) -endif +# Make the variable available to Rust build scripts. +export CC_LINUX AWS_NITRO_INIT_BINARY= init/aws-nitro/init $(AWS_NITRO_INIT_BINARY): $(AWS_NITRO_INIT_SRC) @@ -155,7 +141,7 @@ clean-sysroot: rm -rf $(ROOTFS_DIR) -$(LIBRARY_RELEASE_$(OS)): $(INIT_BINARY) +$(LIBRARY_RELEASE_$(OS)): $(SYSROOT_TARGET) cargo build --release $(FEATURE_FLAGS) ifeq ($(SEV),1) mv target/release/libkrun.so target/release/$(KRUN_BASE_$(OS)) @@ -174,7 +160,7 @@ endif endif cp target/release/$(KRUN_BASE_$(OS)) $(LIBRARY_RELEASE_$(OS)) -$(LIBRARY_DEBUG_$(OS)): $(INIT_BINARY) +$(LIBRARY_DEBUG_$(OS)): $(SYSROOT_TARGET) cargo build $(FEATURE_FLAGS) ifeq ($(SEV),1) mv target/debug/libkrun.so target/debug/$(KRUN_BASE_$(OS)) @@ -206,7 +192,6 @@ install: libkrun.pc cd $(DESTDIR)$(PREFIX)/$(LIBDIR_$(OS))/ ; ln -sf $(KRUN_BINARY_$(OS)) $(KRUN_SONAME_$(OS)) ; ln -sf $(KRUN_SONAME_$(OS)) $(KRUN_BASE_$(OS)) clean: - rm -f $(INIT_BINARY) cargo clean rm -rf test-prefix cd tests; cargo clean diff --git a/src/devices/build.rs b/src/devices/build.rs index 229c2a269..813d76f41 100644 --- a/src/devices/build.rs +++ b/src/devices/build.rs @@ -1,12 +1,51 @@ +use std::ffi::OsStr; use std::path::PathBuf; +use std::process::Command; + +fn build_default_init() -> PathBuf { + let manifest_dir = PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let libkrun_root = manifest_dir.join("../.."); + let init_src = libkrun_root.join("init/init.c"); + let init_bin = libkrun_root.join("init/init"); + + println!("cargo:rerun-if-env-changed=CC_LINUX"); + println!("cargo:rerun-if-env-changed=CC"); + println!("cargo:rerun-if-env-changed=TIMESYNC"); + println!("cargo:rerun-if-changed={}", init_src.display()); + println!( + "cargo:rerun-if-changed={}", + libkrun_root.join("init/jsmn.h").display() + ); + + let mut init_cc_flags = vec!["-O2", "-static", "-Wall"]; + if std::env::var_os("TIMESYNC").as_deref() == Some(OsStr::new("1")) { + init_cc_flags.push("-D__TIMESYNC__"); + } + + let cc_value = std::env::var("CC_LINUX") + .or_else(|_| std::env::var("CC")) + .unwrap_or_else(|_| "cc".to_string()); + let mut cc_parts = cc_value.split_ascii_whitespace(); + let cc = cc_parts.next().expect("CC_LINUX/CC must not be empty"); + let status = Command::new(cc) + .args(cc_parts) + .args(&init_cc_flags) + .arg("-o") + .arg(&init_bin) + .arg(&init_src) + .status() + .unwrap_or_else(|e| panic!("failed to execute {cc}: {e}")); + + if !status.success() { + panic!("failed to compile init/init.c: {status}"); + } + init_bin +} fn main() { let init_binary_path = std::env::var_os("KRUN_INIT_BINARY_PATH") .map(PathBuf::from) - .unwrap_or_else(|| { - let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()); - manifest_dir.join("../../init/init") - }); + .unwrap_or_else(build_default_init); println!( "cargo:rustc-env=KRUN_INIT_BINARY_PATH={}", init_binary_path.display()