fn main() { link_swift(); link_swift_package("highlight-swift", "./highlight-swift/"); let target = get_swift_target_info(); // on linux we need to tell it to link against the swift stdlib, // because the --static-swift-stdlib on swift build doesn't work for static libraries // on macos, it all magically works if target.target.unversioned_triple.contains("linux") { // include the swift runtime library path in the rpath target.paths.runtime_library_paths.iter().for_each(|path| { println!("cargo:rustc-link-arg=-Wl,-rpath={}", path); }); // link in swiftrt.o, which initializes the swift runtime let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); println!( "cargo:rustc-link-arg={}/linux/{}/swiftrt.o", &target.paths.runtime_resource_path, arch ); // link against the swift stdlib and all th supporting pieces println!("cargo:rustc-link-lib=dylib=BlocksRuntime"); println!("cargo:rustc-link-lib=dylib=dispatch"); println!("cargo:rustc-link-lib=dylib=FoundationEssentials"); println!("cargo:rustc-link-lib=dylib=FoundationNetworking"); println!("cargo:rustc-link-lib=dylib=Foundation"); println!("cargo:rustc-link-lib=dylib=FoundationXML"); println!("cargo:rustc-link-lib=dylib=icudataswift"); println!("cargo:rustc-link-lib=dylib=icui18nswift"); println!("cargo:rustc-link-lib=dylib=icuucswift"); println!("cargo:rustc-link-lib=dylib=_InternalSwiftScan"); println!("cargo:rustc-link-lib=dylib=_InternalSwiftStaticMirror"); println!("cargo:rustc-link-lib=dylib=swift_Concurrency"); println!("cargo:rustc-link-lib=dylib=swiftCore"); println!("cargo:rustc-link-lib=dylib=swift_Differentiation"); println!("cargo:rustc-link-lib=dylib=swiftDispatch"); println!("cargo:rustc-link-lib=dylib=swiftDistributed"); println!("cargo:rustc-link-lib=dylib=swiftGlibc"); println!("cargo:rustc-link-lib=dylib=swiftRegexBuilder"); println!("cargo:rustc-link-lib=dylib=swift_RegexParser"); println!("cargo:rustc-link-lib=dylib=swiftRemoteMirror"); println!("cargo:rustc-link-lib=dylib=swift_StringProcessing"); println!("cargo:rustc-link-lib=dylib=swiftSwiftOnoneSupport"); println!("cargo:rustc-link-lib=dylib=XCTest"); } } // Copied from https://github.com/Brendonovich/swift-rs // With get_swift_target_info changed to print the current target // rather than always trying for the macosx target. use std::{env, process::Command}; use serde::Deserialize; #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SwiftTargetInfo { pub unversioned_triple: String, #[serde(rename = "librariesRequireRPath")] pub libraries_require_rpath: bool, } #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SwiftPaths { pub runtime_library_paths: Vec, pub runtime_resource_path: String, } #[derive(Debug, Deserialize)] pub struct SwiftTarget { pub target: SwiftTargetInfo, pub paths: SwiftPaths, } pub fn get_swift_target_info() -> SwiftTarget { let swift_target_info_str = Command::new("swift") .args(&["-print-target-info"]) .output() .unwrap() .stdout; serde_json::from_slice(&swift_target_info_str).unwrap() } pub fn link_swift() { let swift_target_info = get_swift_target_info(); if swift_target_info.target.libraries_require_rpath { panic!("Libraries require RPath! Change minimum MacOS value to fix.") } swift_target_info .paths .runtime_library_paths .iter() .for_each(|path| { println!("cargo:rustc-link-search=native={}", path); }); } pub fn link_swift_package(package_name: &str, package_root: &str) { let profile = env::var("PROFILE").unwrap(); dbg!(&profile); if !Command::new("swift") .args(&["build", "-c", &profile]) .current_dir(package_root) .status() .unwrap() .success() { panic!("Failed to compile swift package {}", package_name); } let swift_target_info = get_swift_target_info(); println!( "cargo:rustc-link-search=native={}.build/{}/{}", package_root, swift_target_info.target.unversioned_triple, profile ); println!("cargo:rustc-link-lib=static={}", package_name); }