Skip to content

Commit bbdae3f

Browse files
authored
symblib-capi: fix static linking with musl (open-telemetry#438)
Signed-off-by: Florian Lehner <[email protected]>
1 parent ead430a commit bbdae3f

File tree

5 files changed

+124
-4
lines changed

5 files changed

+124
-4
lines changed

Cargo.lock

Lines changed: 49 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust-crates/symblib-capi/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ symblib.path = "../symblib"
1313

1414
fallible-iterator.workspace = true
1515
thiserror.workspace = true
16+
17+
[build-dependencies]
18+
serde_json = "1.0.140"

rust-crates/symblib-capi/build.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use std::{env, path::PathBuf, process::Command};
2+
3+
fn main() {
4+
// Fetch the cargo build manifest.
5+
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
6+
let output = Command::new("cargo")
7+
.args(&["metadata", "--format-version=1", "--no-deps"])
8+
.current_dir(&manifest_dir)
9+
.output()
10+
.expect("Failed to execute cargo metadata");
11+
12+
if !output.status.success() {
13+
println!("cargo:warning=Failed to get cargo metadata");
14+
return;
15+
}
16+
17+
let metadata: serde_json::Value =
18+
serde_json::from_slice(&output.stdout).expect("Failed to parse cargo metadata");
19+
20+
let pkg_name = env::var("CARGO_PKG_NAME").unwrap();
21+
let packages = metadata["packages"].as_array().unwrap();
22+
let current_package = packages
23+
.iter()
24+
.find(|p| p["name"].as_str().unwrap() == pkg_name)
25+
.expect("Could not find current package in metadata");
26+
27+
let targets = current_package["targets"].as_array().unwrap();
28+
let has_staticlib_target = targets.iter().any(|t| {
29+
let kinds = t["kind"].as_array().unwrap();
30+
kinds.iter().any(|k| k.as_str().unwrap() == "staticlib")
31+
});
32+
33+
if !has_staticlib_target {
34+
return;
35+
}
36+
37+
let target = match env::var("TARGET") {
38+
Ok(t) => t,
39+
Err(_) => return,
40+
};
41+
42+
if !target.contains("-linux-musl") {
43+
return;
44+
}
45+
46+
let out_dir = env::var("OUT_DIR").unwrap();
47+
48+
// Get the target-libdir for the specified target
49+
// $(shell rustc --target $(RUST_TARGET) --print target-libdir)/self-contained/libunwind.a
50+
let output = Command::new("rustc")
51+
.args(&["--target", &target, "--print", "target-libdir"])
52+
.output()
53+
.expect("failed to execute rustc");
54+
55+
if output.status.success() {
56+
let target_libdir_str = String::from_utf8_lossy(&output.stdout).trim().to_string();
57+
let libunwind_path = PathBuf::from(target_libdir_str)
58+
.join("self-contained")
59+
.join("libunwind.a");
60+
61+
if libunwind_path.exists() {
62+
std::fs::copy(libunwind_path, format!("{}/libunwind.a", out_dir)).unwrap();
63+
64+
println!("cargo:rustc-link-search=native={}", out_dir);
65+
println!("cargo:rustc-link-lib=static=unwind");
66+
} else {
67+
println!("cargo:warning={:?} does not exist", libunwind_path);
68+
}
69+
} else {
70+
println!("cargo:warning=failed to identify target-libdir for libunwind.a");
71+
}
72+
}
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)