diff --git a/Makefile.uk b/Makefile.uk index 0141947..b59b6de 100644 --- a/Makefile.uk +++ b/Makefile.uk @@ -39,6 +39,15 @@ endif APPELFLOADER_RUST_LIB := \ $(APPELFLOADER_RUST_OUT)/$(APPELFLOADER_RUST_TARGET)/release/libelfloader_rs.a +# Kconfig symbols the Rust side needs at *compile* time, because they decide +# which C the archive is allowed to reference. CONFIG_APPELFLOADER_ELF_BINFMT +# guards the `uk_binfmt_loader_args` accessors in glue/shim.c, so `binfmt.rs` +# has to be compiled out with them. +APPELFLOADER_RUST_FEATURES-$(CONFIG_APPELFLOADER_ELF_BINFMT) += binfmt + +APPELFLOADER_RUST_FEATURE_FLAGS := $(if $(APPELFLOADER_RUST_FEATURES-y), \ + --features $(subst $(space),$(comma),$(strip $(APPELFLOADER_RUST_FEATURES-y)))) + APPELFLOADER_RUST_SRCS := \ $(wildcard $(APPELFLOADER_RUST_DIR)/src/*.rs) \ $(APPELFLOADER_RUST_DIR)/Cargo.toml \ @@ -61,6 +70,7 @@ $(APPELFLOADER_RUST_LIB): $(APPELFLOADER_RUST_SRCS) --manifest-path $(APPELFLOADER_RUST_DIR)/Cargo.toml \ --target $(APPELFLOADER_RUST_TARGET) \ --target-dir $(APPELFLOADER_RUST_OUT) \ + $(APPELFLOADER_RUST_FEATURE_FLAGS) \ --release --locked --offline) APPELFLOADER_ALIBS-y += $(APPELFLOADER_RUST_LIB) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index b1e4ae0..01eac02 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -12,6 +12,12 @@ name = "elfloader_rs" # the modules that talk to Unikraft are gated on `not(test)`. crate-type = ["staticlib"] +[features] +# Compile the `libukbinfmt` loader. Mirrors CONFIG_APPELFLOADER_ELF_BINFMT, +# which is what guards the matching accessors in `glue/shim.c`; the two must +# agree or the archive references C functions that were never compiled. +binfmt = [] + [dependencies] [profile.release] diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 3dc621f..46e019b 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -45,7 +45,11 @@ mod testutil; #[cfg(not(test))] mod app; -#[cfg(not(test))] +// The accessors this module calls live behind `#if CONFIG_APPELFLOADER_ELF_BINFMT` +// in `glue/shim.c`, so compiling it when that option is off leaves the archive +// with undefined references to C that was never built. `Makefile.uk` turns the +// feature on from the same Kconfig symbol that guards the C side. +#[cfg(all(not(test), feature = "binfmt"))] mod binfmt; #[cfg(not(test))] mod rt;