{{ generated_header }}
use std::collections::BTreeSet;
use std::path::PathBuf;
fn main() {
let out_dir = PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR unset"));
let crate_name = std::env::var("CARGO_PKG_NAME").expect("CARGO_PKG_NAME unset");
let bridges = vec!["src/lib.rs"];
let generated = swift_bridge_build::parse_bridges(bridges);
if std::env::var("CARGO_CFG_TARGET_VENDOR").as_deref() == Ok("apple") {
let swift = generated.concat_swift();
// Swift owns these exports, which are linked after Cargo builds the cdylib. ~keep
for name in swift_callback_exports(&swift) {
println!("cargo:rustc-cdylib-link-arg=-Wl,-U,_{name}");
}
}
generated.write_all_concatenated(out_dir, &crate_name);
println!("cargo:rerun-if-changed=src/lib.rs");
}
fn swift_callback_exports(swift: &str) -> BTreeSet<&str> {
let mut names = BTreeSet::new();
for line in swift.lines().map(str::trim).filter(|line| line.starts_with("@_cdecl")) {
let name = line
.strip_prefix("@_cdecl(\"")
.and_then(|rest| rest.strip_suffix("\")"))
.expect("malformed swift-bridge @_cdecl export");
assert!(
!name.is_empty()
&& !name.chars().any(|character| {
character.is_control() || character.is_whitespace() || matches!(character, ',' | '"' | '\\')
}),
"invalid Swift callback export symbol"
);
assert!(names.insert(name), "duplicate Swift callback export symbol");
}
names
}