diff --git a/Cargo.lock b/Cargo.lock index 381f47901..6f203b610 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -233,6 +233,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + [[package]] name = "jobserver" version = "0.1.31" @@ -339,9 +345,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -456,6 +462,44 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "sha2" version = "0.10.8" @@ -508,15 +552,16 @@ name = "symblib-capi" version = "0.0.0" dependencies = [ "fallible-iterator", + "serde_json", "symblib", "thiserror", ] [[package]] name = "syn" -version = "2.0.77" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", diff --git a/rust-crates/symblib-capi/Cargo.toml b/rust-crates/symblib-capi/Cargo.toml index 0ab380bb5..3b5d3824f 100644 --- a/rust-crates/symblib-capi/Cargo.toml +++ b/rust-crates/symblib-capi/Cargo.toml @@ -13,3 +13,6 @@ symblib.path = "../symblib" fallible-iterator.workspace = true thiserror.workspace = true + +[build-dependencies] +serde_json = "1.0.140" diff --git a/rust-crates/symblib-capi/build.rs b/rust-crates/symblib-capi/build.rs new file mode 100644 index 000000000..1adf94adf --- /dev/null +++ b/rust-crates/symblib-capi/build.rs @@ -0,0 +1,72 @@ +use std::{env, path::PathBuf, process::Command}; + +fn main() { + // Fetch the cargo build manifest. + let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let output = Command::new("cargo") + .args(&["metadata", "--format-version=1", "--no-deps"]) + .current_dir(&manifest_dir) + .output() + .expect("Failed to execute cargo metadata"); + + if !output.status.success() { + println!("cargo:warning=Failed to get cargo metadata"); + return; + } + + let metadata: serde_json::Value = + serde_json::from_slice(&output.stdout).expect("Failed to parse cargo metadata"); + + let pkg_name = env::var("CARGO_PKG_NAME").unwrap(); + let packages = metadata["packages"].as_array().unwrap(); + let current_package = packages + .iter() + .find(|p| p["name"].as_str().unwrap() == pkg_name) + .expect("Could not find current package in metadata"); + + let targets = current_package["targets"].as_array().unwrap(); + let has_staticlib_target = targets.iter().any(|t| { + let kinds = t["kind"].as_array().unwrap(); + kinds.iter().any(|k| k.as_str().unwrap() == "staticlib") + }); + + if !has_staticlib_target { + return; + } + + let target = match env::var("TARGET") { + Ok(t) => t, + Err(_) => return, + }; + + if !target.contains("-linux-musl") { + return; + } + + let out_dir = env::var("OUT_DIR").unwrap(); + + // Get the target-libdir for the specified target + // $(shell rustc --target $(RUST_TARGET) --print target-libdir)/self-contained/libunwind.a + let output = Command::new("rustc") + .args(&["--target", &target, "--print", "target-libdir"]) + .output() + .expect("failed to execute rustc"); + + if output.status.success() { + let target_libdir_str = String::from_utf8_lossy(&output.stdout).trim().to_string(); + let libunwind_path = PathBuf::from(target_libdir_str) + .join("self-contained") + .join("libunwind.a"); + + if libunwind_path.exists() { + std::fs::copy(libunwind_path, format!("{}/libunwind.a", out_dir)).unwrap(); + + println!("cargo:rustc-link-search=native={}", out_dir); + println!("cargo:rustc-link-lib=static=unwind"); + } else { + println!("cargo:warning={:?} does not exist", libunwind_path); + } + } else { + println!("cargo:warning=failed to identify target-libdir for libunwind.a"); + } +} diff --git a/target/aarch64-unknown-linux-musl/release/libsymblib_capi.a b/target/aarch64-unknown-linux-musl/release/libsymblib_capi.a index 9512dfb24..9d10122eb 100644 Binary files a/target/aarch64-unknown-linux-musl/release/libsymblib_capi.a and b/target/aarch64-unknown-linux-musl/release/libsymblib_capi.a differ diff --git a/target/x86_64-unknown-linux-musl/release/libsymblib_capi.a b/target/x86_64-unknown-linux-musl/release/libsymblib_capi.a index aad2e1d41..cf645c218 100644 Binary files a/target/x86_64-unknown-linux-musl/release/libsymblib_capi.a and b/target/x86_64-unknown-linux-musl/release/libsymblib_capi.a differ