use std::env;
use std::process::Command;
fn detect_sdk_major_version() -> Option<u32> {
let output = Command::new("xcrun")
.args(["--show-sdk-version"])
.output()
.ok()?;
if !output.status.success() {
return None;
}
let version_str = String::from_utf8_lossy(&output.stdout);
let major = version_str.trim().split('.').next()?;
major.parse().ok()
}
fn main() {
println!("cargo:rustc-link-lib=framework=ScreenCaptureKit");
let swift_dir = "swift-bridge";
let out_dir = env::var("OUT_DIR").unwrap();
let swift_build_dir = format!("{out_dir}/swift-build");
println!("cargo:rerun-if-changed={swift_dir}");
if let Ok(output) = Command::new("swiftlint")
.args(["lint"])
.current_dir(swift_dir)
.output()
{
if !output.status.success() {
eprintln!(
"SwiftLint warnings:\n{}",
String::from_utf8_lossy(&output.stdout)
);
}
}
let sdk_version = detect_sdk_major_version();
let sdk_at_least = |min: u32| sdk_version.is_some_and(|v| v >= min);
let mut swift_args = vec![
"build",
"-c",
"release",
"--package-path",
swift_dir,
"--scratch-path",
&swift_build_dir,
];
if env::var("CARGO_FEATURE_MACOS_15_0").is_ok() {
if sdk_at_least(15) {
swift_args.extend(["-Xswiftc", "-DSCREENCAPTUREKIT_HAS_MACOS15_SDK"]);
} else {
println!(
"cargo:warning=Feature macos_15_0 enabled but SDK version ({}) < 15; \
macOS 15+ APIs will be stubbed out",
sdk_version.map_or_else(|| "unknown".to_string(), |v| v.to_string())
);
}
}
if env::var("CARGO_FEATURE_MACOS_26_0").is_ok() {
if sdk_at_least(26) {
swift_args.extend(["-Xswiftc", "-DSCREENCAPTUREKIT_HAS_MACOS26_SDK"]);
} else {
println!(
"cargo:warning=Feature macos_26_0 enabled but SDK version ({}) < 26; \
macOS 26+ APIs will be stubbed out",
sdk_version.map_or_else(|| "unknown".to_string(), |v| v.to_string())
);
}
}
let output = Command::new("swift")
.args(&swift_args)
.output()
.expect("Failed to build Swift bridge");
if !output.status.success() {
eprintln!(
"Swift build STDOUT:\n{}",
String::from_utf8_lossy(&output.stdout)
);
eprintln!(
"Swift build STDERR:\n{}",
String::from_utf8_lossy(&output.stderr)
);
panic!(
"Swift build failed with exit code: {:?}",
output.status.code()
);
}
println!("cargo:rustc-link-search=native={swift_build_dir}/release");
println!("cargo:rustc-link-lib=static=ScreenCaptureKitBridge");
println!("cargo:rustc-link-lib=framework=Foundation");
println!("cargo:rustc-link-lib=framework=CoreGraphics");
println!("cargo:rustc-link-lib=framework=CoreMedia");
println!("cargo:rustc-link-lib=framework=IOSurface");
println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/lib/swift");
if let Ok(output) = Command::new("xcode-select").arg("-p").output() {
if output.status.success() {
let xcode_path = String::from_utf8_lossy(&output.stdout).trim().to_string();
let swift_lib_path = format!(
"{xcode_path}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.5/macosx"
);
println!("cargo:rustc-link-arg=-Wl,-rpath,{swift_lib_path}");
let swift_lib_path_new =
format!("{xcode_path}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx");
println!("cargo:rustc-link-arg=-Wl,-rpath,{swift_lib_path_new}");
}
}
}