From 59610dd604de82f0fb980a82425f5ed8894d3f9f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 12 Aug 2025 18:45:20 +0200 Subject: [PATCH 1/4] igvm_c: fix Makefile rules Do not include the .h files on the command line; do not include the library twice, once via $^ and once via -ligvm. Signed-off-by: Paolo Bonzini --- igvm_c/Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/igvm_c/Makefile b/igvm_c/Makefile index ace990e..e80e6a6 100644 --- a/igvm_c/Makefile +++ b/igvm_c/Makefile @@ -25,6 +25,7 @@ CARGO=CARGO_TARGET_DIR=$(IGVM_DIR)/$(TARGET_DIR) cargo FEATURES = "igvm-c" RUST_SOURCE := $(IGVM_DIR)/igvm/src/c_api.rs $(IGVM_DIR)/igvm/src/lib.rs $(IGVM_DIR)/igvm_defs/src/lib.rs +LIBIGVM = $(LIB_PATH)/libigvm.a # Determine igvm crate version from Cargo.toml VERSION = $(shell grep -oP "(?<=version = \").+(?=\")" $(IGVM_DIR)/igvm/Cargo.toml) @@ -35,7 +36,7 @@ all: build test build: $(API_DIR)/include/igvm.h $(TARGET_PATH)/dump_igvm -$(TARGET_PATH)/libigvm.a: +$(LIBIGVM): $(CARGO) build --features $(FEATURES) $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm/Cargo.toml $(TARGET_PATH)/libigvm_defs.rlib: @@ -49,11 +50,11 @@ $(API_DIR)/include/igvm.h: $(RUST_SOURCE) cbindgen -q -c $(API_DIR)/cbindgen_igvm_defs.toml $(IGVM_DIR)/igvm_defs -o "$(API_DIR)/include/igvm_defs.h" $(API_DIR)/scripts/post_process.sh "$(API_DIR)/include" -$(TARGET_PATH)/dump_igvm: $(API_DIR)/include/igvm.h $(API_DIR)/sample/dump_igvm.c $(TARGET_PATH)/libigvm.a - $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $^ -ligvm -ldl -pthread -lutil -lrt $(LDFLAGS) +$(TARGET_PATH)/dump_igvm: $(API_DIR)/sample/dump_igvm.c $(API_DIR)/include/igvm.h $(LIBIGVM) + $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $< $(LIBIGVM) -ldl -pthread -lutil -lrt $(LDFLAGS) -$(TARGET_PATH)/igvm_test: $(API_DIR)/include/igvm.h $(API_DIR)/tests/igvm_test.c $(TARGET_PATH)/libigvm.a - $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $^ -ligvm -lcunit -ldl -pthread -lm -lutil -lrt $(LDFLAGS) +$(TARGET_PATH)/igvm_test: $(API_DIR)/tests/igvm_test.c $(API_DIR)/include/igvm.h $(LIBIGVM) + $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $< $(LIBIGVM) -lcunit -ldl -pthread -lutil -lrt $(LDFLAGS) $(TARGET_PATH)/igvm.bin: $(TARGET_PATH)/test_data $(TARGET_PATH)/test_data $(TARGET_PATH)/igvm.bin From 41cb1276d355cb81d6fd37acd535a78ee5b80b0a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 12 Aug 2025 17:43:37 +0200 Subject: [PATCH 2/4] igvm-c: switch to cargo-c cargo-c is able to generate a shared library and takes care of creating the .pc file as well. The main change that is needed for the Makefile is that libraries are placed in a subdirectory of the CARGO_TARGET_DIR. Signed-off-by: Paolo Bonzini --- .github/workflows/rust.yml | 2 ++ igvm/Cargo.toml | 5 +++++ igvm_c/Makefile | 21 ++++++++------------- igvm_c/igvm.pc.in | 13 ------------- 4 files changed, 15 insertions(+), 26 deletions(-) delete mode 100644 igvm_c/igvm.pc.in diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 73d6606..28aa99e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -50,6 +50,8 @@ jobs: toolchain: ${{ env.RUST_TOOLCHAIN }} - name: Install cbindgen run: cargo install cbindgen + - name: Install cargo-c + run: cargo install --locked cargo-c@0.10.14+cargo-0.89.0 - name: Install build dependencies run: sudo apt-get install -y libcunit1-dev - name: Build and test diff --git a/igvm/Cargo.toml b/igvm/Cargo.toml index 350d0a3..974300b 100644 --- a/igvm/Cargo.toml +++ b/igvm/Cargo.toml @@ -12,6 +12,10 @@ repository = "https://github.com/microsoft/igvm" keywords = ["virtualization"] categories = ["virtualization", "parser-implementations"] +[package.metadata.capi.header] +# cbindgen is handled from igvm_c/Makefile +enabled = false + [package.metadata.docs.rs] # Document all features all-features = true @@ -40,4 +44,5 @@ static_assertions.workspace = true [features] default = [] +capi = ["igvm-c"] igvm-c = [] # Add exports that allow the library to be used from C diff --git a/igvm_c/Makefile b/igvm_c/Makefile index e80e6a6..8d7b688 100644 --- a/igvm_c/Makefile +++ b/igvm_c/Makefile @@ -8,12 +8,6 @@ API_DIR:=$(realpath $(shell dirname $(firstword $(MAKEFILE_LIST)))) IGVM_DIR := $(API_DIR)/.. TARGET_DIR ?= target_c -ifdef RELEASE -TARGET_PATH="$(IGVM_DIR)/$(TARGET_DIR)/$(CARGO_BUILD_TARGET)/release" -else -TARGET_PATH="$(IGVM_DIR)/$(TARGET_DIR)/$(CARGO_BUILD_TARGET)/debug" -endif - PREFIX ?= /usr DESTDIR ?= @@ -21,8 +15,13 @@ CFLAGS ?= -g3 -O0 LDFLAGS += -L $(TARGET_PATH) CARGO=CARGO_TARGET_DIR=$(IGVM_DIR)/$(TARGET_DIR) cargo +CARGO_BUILD_HOST := $(shell $(CARGO) -Vv | sed -n 's,^host: ,,p') FEATURES = "igvm-c" +PROFILE = $(if $(RELEASE),release,debug) + +TARGET_PATH = "$(IGVM_DIR)/$(TARGET_DIR)/$(CARGO_BUILD_TARGET)/$(PROFILE)" +LIB_PATH = "$(IGVM_DIR)/$(TARGET_DIR)/$(or $(CARGO_BUILD_TARGET),$(CARGO_BUILD_HOST))/$(PROFILE)" RUST_SOURCE := $(IGVM_DIR)/igvm/src/c_api.rs $(IGVM_DIR)/igvm/src/lib.rs $(IGVM_DIR)/igvm_defs/src/lib.rs LIBIGVM = $(LIB_PATH)/libigvm.a @@ -37,7 +36,7 @@ all: build test build: $(API_DIR)/include/igvm.h $(TARGET_PATH)/dump_igvm $(LIBIGVM): - $(CARGO) build --features $(FEATURES) $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm/Cargo.toml + $(CARGO) cbuild --prefix $(PREFIX) --features $(FEATURES) $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm/Cargo.toml $(TARGET_PATH)/libigvm_defs.rlib: $(CARGO) build $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm_defs/Cargo.toml @@ -68,13 +67,9 @@ clean: $(CARGO) clean $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm_defs/Cargo.toml rm -f $(API_DIR)/include/igvm.h $(API_DIR)/include/igvm_defs.h $(TARGET_PATH)/dump_igvm $(TARGET_PATH)/test_data $(TARGET_PATH)/igvm.bin -install: +install: build mkdir -p $(DESTDIR)/$(PREFIX)/include/igvm - mkdir -p $(DESTDIR)/$(PREFIX)/lib64/pkgconfig - install -m 644 $(TARGET_PATH)/libigvm.a $(DESTDIR)/$(PREFIX)/lib64 install -m 644 $(IGVM_DIR)/igvm_c/include/* $(DESTDIR)/$(PREFIX)/include/igvm + $(CARGO) cinstall --destdir "$(DESTDIR)" --prefix "$(PREFIX)" --features $(FEATURES) $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm/Cargo.toml mkdir -p $(DESTDIR)/$(PREFIX)/bin/ install -m 755 $(TARGET_PATH)/dump_igvm $(DESTDIR)/$(PREFIX)/bin/ - VERSION=$(VERSION) PREFIX=$(PREFIX) envsubst '$$VERSION $$PREFIX' \ - < $(IGVM_DIR)/igvm_c/igvm.pc.in \ - > $(DESTDIR)/$(PREFIX)/lib64/pkgconfig/igvm.pc diff --git a/igvm_c/igvm.pc.in b/igvm_c/igvm.pc.in deleted file mode 100644 index 2f92404..0000000 --- a/igvm_c/igvm.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=$PREFIX -exec_prefix=${prefix} -libdir=${prefix}/lib64 -sharedlibdir=${libdir} -includedir=${prefix}/include - -Name: igvm -Description: igvm library -Version: $VERSION - -Requires: -Libs: -L${libdir} -L${sharedlibdir} -ligvm -Cflags: -I${includedir} From 24e901ff98fd2b79581ba26ab82ee24c5aa34917 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 12 Aug 2025 18:35:08 +0200 Subject: [PATCH 3/4] igvm-c: grab Rust runtime dependencies from .pc file The Rust runtime dependencies may vary depending on the target. cargo-c is able to place them in the .pc file, and also builds a .pc file that can be used before installation. This fixes cross compilation under Windows, which can be done with make -C igvm_c CARGO_BUILD_TARGET=x86_64-pc-windows-gnu EXTRA_PARAMS="--target x86_64-pc-windows-gnu" CC=x86_64-w64-mingw32-gcc Signed-off-by: Paolo Bonzini --- igvm_c/Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/igvm_c/Makefile b/igvm_c/Makefile index 8d7b688..bcf886c 100644 --- a/igvm_c/Makefile +++ b/igvm_c/Makefile @@ -12,7 +12,6 @@ PREFIX ?= /usr DESTDIR ?= CFLAGS ?= -g3 -O0 -LDFLAGS += -L $(TARGET_PATH) CARGO=CARGO_TARGET_DIR=$(IGVM_DIR)/$(TARGET_DIR) cargo CARGO_BUILD_HOST := $(shell $(CARGO) -Vv | sed -n 's,^host: ,,p') @@ -25,6 +24,9 @@ LIB_PATH = "$(IGVM_DIR)/$(TARGET_DIR)/$(or $(CARGO_BUILD_TARGET),$(CARGO_BUILD_H RUST_SOURCE := $(IGVM_DIR)/igvm/src/c_api.rs $(IGVM_DIR)/igvm/src/lib.rs $(IGVM_DIR)/igvm_defs/src/lib.rs LIBIGVM = $(LIB_PATH)/libigvm.a +UNINSTALLED_PC = $(LIB_PATH)/igvm-uninstalled.pc +IGVM_LIBS = $(shell pkg-config --libs --static $(UNINSTALLED_PC)) +IGVM_LIBS_STATIC = $(subst $(IGVM_LIBS), -ligvm, $(LIBIGVM)) # Determine igvm crate version from Cargo.toml VERSION = $(shell grep -oP "(?<=version = \").+(?=\")" $(IGVM_DIR)/igvm/Cargo.toml) @@ -50,10 +52,10 @@ $(API_DIR)/include/igvm.h: $(RUST_SOURCE) $(API_DIR)/scripts/post_process.sh "$(API_DIR)/include" $(TARGET_PATH)/dump_igvm: $(API_DIR)/sample/dump_igvm.c $(API_DIR)/include/igvm.h $(LIBIGVM) - $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $< $(LIBIGVM) -ldl -pthread -lutil -lrt $(LDFLAGS) + $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $< $(IGVM_LIBS) $(LDFLAGS) $(TARGET_PATH)/igvm_test: $(API_DIR)/tests/igvm_test.c $(API_DIR)/include/igvm.h $(LIBIGVM) - $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $< $(LIBIGVM) -lcunit -ldl -pthread -lutil -lrt $(LDFLAGS) + $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $< -lcunit $(IGVM_LIBS_STATIC) $(LDFLAGS) $(TARGET_PATH)/igvm.bin: $(TARGET_PATH)/test_data $(TARGET_PATH)/test_data $(TARGET_PATH)/igvm.bin From a79cb6165d4251f9651bc3540861d5b25770077a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 12 Aug 2025 19:05:37 +0200 Subject: [PATCH 4/4] igvm_c: add variable for .exe suffix This finally makes it possible to *install* a cross-compiled Windows build, albeit with a manual "EXE=.exe" on the command line. Signed-off-by: Paolo Bonzini --- igvm_c/Makefile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/igvm_c/Makefile b/igvm_c/Makefile index bcf886c..1796e07 100644 --- a/igvm_c/Makefile +++ b/igvm_c/Makefile @@ -7,6 +7,7 @@ API_DIR:=$(realpath $(shell dirname $(firstword $(MAKEFILE_LIST)))) IGVM_DIR := $(API_DIR)/.. TARGET_DIR ?= target_c +EXE = PREFIX ?= /usr DESTDIR ?= @@ -35,7 +36,7 @@ VERSION = $(shell grep -oP "(?<=version = \").+(?=\")" $(IGVM_DIR)/igvm/Cargo.to all: build test -build: $(API_DIR)/include/igvm.h $(TARGET_PATH)/dump_igvm +build: $(API_DIR)/include/igvm.h $(TARGET_PATH)/dump_igvm$(EXE) $(LIBIGVM): $(CARGO) cbuild --prefix $(PREFIX) --features $(FEATURES) $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm/Cargo.toml @@ -43,7 +44,7 @@ $(LIBIGVM): $(TARGET_PATH)/libigvm_defs.rlib: $(CARGO) build $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm_defs/Cargo.toml -$(TARGET_PATH)/test_data: +$(TARGET_PATH)/test_data$(EXE): $(CARGO) build $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm_c/test_data/Cargo.toml $(API_DIR)/include/igvm.h: $(RUST_SOURCE) @@ -51,27 +52,27 @@ $(API_DIR)/include/igvm.h: $(RUST_SOURCE) cbindgen -q -c $(API_DIR)/cbindgen_igvm_defs.toml $(IGVM_DIR)/igvm_defs -o "$(API_DIR)/include/igvm_defs.h" $(API_DIR)/scripts/post_process.sh "$(API_DIR)/include" -$(TARGET_PATH)/dump_igvm: $(API_DIR)/sample/dump_igvm.c $(API_DIR)/include/igvm.h $(LIBIGVM) +$(TARGET_PATH)/dump_igvm$(EXE): $(API_DIR)/sample/dump_igvm.c $(API_DIR)/include/igvm.h $(LIBIGVM) $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $< $(IGVM_LIBS) $(LDFLAGS) -$(TARGET_PATH)/igvm_test: $(API_DIR)/tests/igvm_test.c $(API_DIR)/include/igvm.h $(LIBIGVM) +$(TARGET_PATH)/igvm_test$(EXE): $(API_DIR)/tests/igvm_test.c $(API_DIR)/include/igvm.h $(LIBIGVM) $(CC) $(CFLAGS) -I $(API_DIR) -o $@ $< -lcunit $(IGVM_LIBS_STATIC) $(LDFLAGS) -$(TARGET_PATH)/igvm.bin: $(TARGET_PATH)/test_data +$(TARGET_PATH)/igvm.bin: $(TARGET_PATH)/test_data$(EXE) $(TARGET_PATH)/test_data $(TARGET_PATH)/igvm.bin -test: $(TARGET_PATH)/igvm_test $(TARGET_PATH)/igvm.bin +test: $(TARGET_PATH)/igvm_test$(EXE) $(TARGET_PATH)/igvm.bin $(TARGET_PATH)/igvm_test $(TARGET_PATH)/igvm.bin $(CARGO) test --features $(FEATURES) $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm/Cargo.toml clean: $(CARGO) clean $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm/Cargo.toml $(CARGO) clean $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm_defs/Cargo.toml - rm -f $(API_DIR)/include/igvm.h $(API_DIR)/include/igvm_defs.h $(TARGET_PATH)/dump_igvm $(TARGET_PATH)/test_data $(TARGET_PATH)/igvm.bin + rm -f $(API_DIR)/include/igvm.h $(API_DIR)/include/igvm_defs.h $(TARGET_PATH)/dump_igvm$(EXE) $(TARGET_PATH)/test_data$(EXE) $(TARGET_PATH)/igvm.bin install: build mkdir -p $(DESTDIR)/$(PREFIX)/include/igvm install -m 644 $(IGVM_DIR)/igvm_c/include/* $(DESTDIR)/$(PREFIX)/include/igvm $(CARGO) cinstall --destdir "$(DESTDIR)" --prefix "$(PREFIX)" --features $(FEATURES) $(EXTRA_PARAMS) --manifest-path=$(IGVM_DIR)/igvm/Cargo.toml mkdir -p $(DESTDIR)/$(PREFIX)/bin/ - install -m 755 $(TARGET_PATH)/dump_igvm $(DESTDIR)/$(PREFIX)/bin/ + install -m 755 $(TARGET_PATH)/dump_igvm$(EXE) $(DESTDIR)/$(PREFIX)/bin/