const MISSING_SHIM_WARNING: &str = "cargo:warning=mysql-handler shim staticlib not produced — the resulting cdylib will be missing C++ shim symbols and cannot be loaded by mysqld. Set MYSQL_HANDLER_FROM_SOURCE=1 or MYSQL_HANDLER_ARCHIVE=<path> to enable shim linking.";
pub fn configure() {
let target = std::env::var("TARGET").expect("TARGET is always set by cargo");
let shim_dir = std::env::var("DEP_HA_RUSTY_SHIM_STATICLIB_DIR").ok();
for line in directives(&target, shim_dir.as_deref()) {
println!("{line}");
}
}
fn directives(target: &str, shim_dir: Option<&str>) -> Vec<String> {
let mut out = Vec::new();
match shim_dir {
Some(dir) => {
out.push(format!("cargo:rustc-link-search=native={dir}"));
out.push("cargo:rustc-link-lib=static=ha_rusty_shim".into());
}
None => out.push(MISSING_SHIM_WARNING.into()),
}
if target.contains("apple") {
out.push("cargo:rustc-link-lib=dylib=c++".into());
out.push("cargo:rustc-link-arg=-Wl,-undefined,dynamic_lookup".into());
} else if target.contains("linux") {
out.push("cargo:rustc-link-lib=dylib=stdc++".into());
}
out
}
#[cfg(test)]
mod tests {
use super::{MISSING_SHIM_WARNING, directives};
#[test]
fn apple_with_shim_dir_emits_static_cpp_and_dynamic_lookup() {
let lines = directives("aarch64-apple-darwin", Some("/tmp/shim"));
assert!(
lines
.iter()
.any(|l| l == "cargo:rustc-link-search=native=/tmp/shim")
);
assert!(
lines
.iter()
.any(|l| l == "cargo:rustc-link-lib=static=ha_rusty_shim")
);
assert!(lines.iter().any(|l| l == "cargo:rustc-link-lib=dylib=c++"));
assert!(
lines
.iter()
.any(|l| l == "cargo:rustc-link-arg=-Wl,-undefined,dynamic_lookup")
);
assert!(!lines.iter().any(|l| l.starts_with("cargo:warning=")));
}
#[test]
fn linux_with_shim_dir_emits_static_and_stdcpp() {
let lines = directives("x86_64-unknown-linux-gnu", Some("/var/cache/shim"));
assert!(
lines
.iter()
.any(|l| l == "cargo:rustc-link-search=native=/var/cache/shim")
);
assert!(
lines
.iter()
.any(|l| l == "cargo:rustc-link-lib=static=ha_rusty_shim")
);
assert!(
lines
.iter()
.any(|l| l == "cargo:rustc-link-lib=dylib=stdc++")
);
assert!(!lines.iter().any(|l| l.contains("dynamic_lookup")));
assert!(!lines.iter().any(|l| l.starts_with("cargo:warning=")));
}
#[test]
fn missing_shim_dir_emits_warning_and_no_static_link() {
let lines = directives("aarch64-apple-darwin", None);
assert!(lines.iter().any(|l| l == MISSING_SHIM_WARNING));
assert!(
!lines
.iter()
.any(|l| l.starts_with("cargo:rustc-link-search"))
);
assert!(!lines.iter().any(|l| l.contains("static=ha_rusty_shim")));
assert!(lines.iter().any(|l| l == "cargo:rustc-link-lib=dylib=c++"));
}
#[test]
fn unknown_target_skips_cpp_runtime() {
let lines = directives("wasm32-unknown-unknown", Some("/x"));
assert!(!lines.iter().any(|l| l.contains("c++")));
assert!(!lines.iter().any(|l| l.contains("stdc++")));
assert!(!lines.iter().any(|l| l.contains("dynamic_lookup")));
}
}