Skip to content

Commit a4aae9c

Browse files
committed
devices: build init binary as part of build script
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 <deso@posteo.net>
1 parent a68a626 commit a4aae9c

3 files changed

Lines changed: 49 additions & 22 deletions

File tree

.github/workflows/code-quality.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ jobs:
5858

5959
- name: Clippy (efi+gpu)
6060
run: cargo clippy --locked --features efi,gpu -- -D warnings
61+
env:
62+
KRUN_INIT_BINARY_PATH: ${{ github.workspace }}/init/init
6163

6264
code-quality-examples:
6365
name: ${{ matrix.name }}

Makefile

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LIBRARY_HEADER_INPUT = include/libkrun_input.h
55
ABI_VERSION=1
66
FULL_VERSION=1.17.3
77

8-
INIT_SRC = init/init.c
98
AWS_NITRO_INIT_SRC = \
109
init/aws-nitro/include/* \
1110
init/aws-nitro/main.c \
@@ -21,17 +20,13 @@ AWS_NITRO_INIT_SRC = \
2120

2221
AWS_NITRO_INIT_LD_FLAGS = -larchive -lnsm
2322

24-
BUILD_INIT = 1
25-
INIT_DEFS =
2623
ifeq ($(SEV),1)
2724
VARIANT = -sev
2825
FEATURE_FLAGS := --features amd-sev
29-
BUILD_INIT = 0
3026
endif
3127
ifeq ($(TDX),1)
3228
VARIANT = -tdx
3329
FEATURE_FLAGS := --features tdx
34-
BUILD_INIT = 0
3530
endif
3631
ifeq ($(VIRGL_RESOURCE_MAP2),1)
3732
FEATURE_FLAGS += --features virgl_resource_map2
@@ -45,7 +40,6 @@ endif
4540
ifeq ($(EFI),1)
4641
VARIANT = -efi
4742
FEATURE_FLAGS := --features efi # EFI Implies blk and net
48-
BUILD_INIT = 0
4943
endif
5044
ifeq ($(GPU),1)
5145
FEATURE_FLAGS += --features gpu
@@ -59,11 +53,6 @@ endif
5953
ifeq ($(AWS_NITRO),1)
6054
VARIANT = -awsnitro
6155
FEATURE_FLAGS := --features aws-nitro,net
62-
BUILD_INIT = 0
63-
endif
64-
65-
ifeq ($(TIMESYNC),1)
66-
INIT_DEFS += -D__TIMESYNC__
6756
endif
6857

6958
OS = $(shell uname -s)
@@ -113,11 +102,8 @@ else
113102
SYSROOT_TARGET =
114103
endif
115104

116-
ifeq ($(BUILD_INIT),1)
117-
INIT_BINARY = init/init
118-
$(INIT_BINARY): $(INIT_SRC) $(SYSROOT_TARGET)
119-
$(CC_LINUX) -O2 -static -Wall $(INIT_DEFS) -o $@ $(INIT_SRC) $(INIT_DEFS)
120-
endif
105+
# Make the variable available to Rust build scripts.
106+
export CC_LINUX
121107

122108
AWS_NITRO_INIT_BINARY= init/aws-nitro/init
123109
$(AWS_NITRO_INIT_BINARY): $(AWS_NITRO_INIT_SRC)
@@ -155,7 +141,7 @@ clean-sysroot:
155141
rm -rf $(ROOTFS_DIR)
156142

157143

158-
$(LIBRARY_RELEASE_$(OS)): $(INIT_BINARY)
144+
$(LIBRARY_RELEASE_$(OS)): $(INIT_BINARY) $(SYSROOT_TARGET)
159145
cargo build --release $(FEATURE_FLAGS)
160146
ifeq ($(SEV),1)
161147
mv target/release/libkrun.so target/release/$(KRUN_BASE_$(OS))
@@ -174,7 +160,7 @@ endif
174160
endif
175161
cp target/release/$(KRUN_BASE_$(OS)) $(LIBRARY_RELEASE_$(OS))
176162

177-
$(LIBRARY_DEBUG_$(OS)): $(INIT_BINARY)
163+
$(LIBRARY_DEBUG_$(OS)): $(INIT_BINARY) $(SYSROOT_TARGET)
178164
cargo build $(FEATURE_FLAGS)
179165
ifeq ($(SEV),1)
180166
mv target/debug/libkrun.so target/debug/$(KRUN_BASE_$(OS))

src/devices/build.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,51 @@
1+
use std::ffi::OsStr;
12
use std::path::PathBuf;
3+
use std::process::Command;
4+
5+
fn build_default_init() -> PathBuf {
6+
let manifest_dir = PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap());
7+
let libkrun_root = manifest_dir.join("../..");
8+
let init_src = libkrun_root.join("init/init.c");
9+
let init_bin = libkrun_root.join("init/init");
10+
11+
println!("cargo:rerun-if-env-changed=CC_LINUX");
12+
println!("cargo:rerun-if-env-changed=CC");
13+
println!("cargo:rerun-if-env-changed=TIMESYNC");
14+
println!("cargo:rerun-if-changed={}", init_src.display());
15+
println!(
16+
"cargo:rerun-if-changed={}",
17+
libkrun_root.join("init/jsmn.h").display()
18+
);
19+
20+
let mut init_cc_flags = vec!["-O2", "-static", "-Wall"];
21+
if std::env::var_os("TIMESYNC").as_deref() == Some(OsStr::new("1")) {
22+
init_cc_flags.push("-D__TIMESYNC__");
23+
}
24+
25+
let cc_value = std::env::var("CC_LINUX")
26+
.or_else(|_| std::env::var("CC"))
27+
.unwrap_or_else(|_| "cc".to_string());
28+
let mut cc_parts = cc_value.split_ascii_whitespace();
29+
let cc = cc_parts.next().expect("CC_LINUX/CC must not be empty");
30+
let status = Command::new(cc)
31+
.args(cc_parts)
32+
.args(&init_cc_flags)
33+
.arg("-o")
34+
.arg(&init_bin)
35+
.arg(&init_src)
36+
.status()
37+
.unwrap_or_else(|e| panic!("failed to execute {cc}: {e}"));
38+
39+
if !status.success() {
40+
panic!("failed to compile init/init.c: {status}");
41+
}
42+
init_bin
43+
}
244

345
fn main() {
446
let init_binary_path = std::env::var_os("KRUN_INIT_BINARY_PATH")
547
.map(PathBuf::from)
6-
.unwrap_or_else(|| {
7-
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
8-
manifest_dir.join("../../init/init")
9-
});
48+
.unwrap_or_else(build_default_init);
1049
println!(
1150
"cargo:rustc-env=KRUN_INIT_BINARY_PATH={}",
1251
init_binary_path.display()

0 commit comments

Comments
 (0)