build.rs

  1use serde::Deserialize;
  2use std::{env, path::PathBuf, process::Command};
  3
  4#[derive(Debug, Deserialize)]
  5#[serde(rename_all = "camelCase")]
  6pub struct SwiftTargetInfo {
  7    pub triple: String,
  8    pub unversioned_triple: String,
  9    pub module_triple: String,
 10    pub swift_runtime_compatibility_version: String,
 11    #[serde(rename = "librariesRequireRPath")]
 12    pub libraries_require_rpath: bool,
 13}
 14
 15#[derive(Debug, Deserialize)]
 16#[serde(rename_all = "camelCase")]
 17pub struct SwiftPaths {
 18    pub runtime_library_paths: Vec<String>,
 19    pub runtime_library_import_paths: Vec<String>,
 20    pub runtime_resource_path: String,
 21}
 22
 23#[derive(Debug, Deserialize)]
 24pub struct SwiftTarget {
 25    pub target: SwiftTargetInfo,
 26    pub paths: SwiftPaths,
 27}
 28
 29const MACOS_TARGET_VERSION: &str = "12";
 30
 31fn main() {
 32    let swift_target = get_swift_target();
 33
 34    build_bridge(&swift_target);
 35    link_swift_stdlib(&swift_target);
 36    link_webrtc_framework(&swift_target);
 37}
 38
 39fn build_bridge(swift_target: &SwiftTarget) {
 40    println!("cargo:rerun-if-changed={}/Sources", SWIFT_PACKAGE_NAME);
 41    println!(
 42        "cargo:rerun-if-changed={}/Package.swift",
 43        SWIFT_PACKAGE_NAME
 44    );
 45    let swift_package_root = swift_package_root();
 46    if !Command::new("swift")
 47        .args(&["build", "-c", &env::var("PROFILE").unwrap()])
 48        .current_dir(&swift_package_root)
 49        .status()
 50        .unwrap()
 51        .success()
 52    {
 53        panic!(
 54            "Failed to compile swift package in {}",
 55            swift_package_root.display()
 56        );
 57    }
 58
 59    println!(
 60        "cargo:rustc-link-search=native={}",
 61        swift_target.out_dir_path().display()
 62    );
 63    println!("cargo:rustc-link-lib=static={}", SWIFT_PACKAGE_NAME);
 64}
 65
 66fn link_swift_stdlib(swift_target: &SwiftTarget) {
 67    if swift_target.target.libraries_require_rpath {
 68        panic!("Libraries require RPath! Change minimum MacOS value to fix.")
 69    }
 70
 71    swift_target
 72        .paths
 73        .runtime_library_paths
 74        .iter()
 75        .for_each(|path| {
 76            println!("cargo:rustc-link-search=native={}", path);
 77        });
 78}
 79
 80fn link_webrtc_framework(swift_target: &SwiftTarget) {
 81    let swift_out_dir_path = swift_target.out_dir_path();
 82    println!("cargo:rustc-link-lib=framework=WebRTC");
 83    println!(
 84        "cargo:rustc-link-search=framework={}",
 85        swift_out_dir_path.display()
 86    );
 87
 88    let source_path = swift_out_dir_path.join("WebRTC.framework");
 89    let target_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("../../../WebRTC.framework");
 90    assert!(
 91        Command::new("cp")
 92            .arg("-r")
 93            .args(&[&source_path, &target_path])
 94            .status()
 95            .unwrap()
 96            .success(),
 97        "could not copy WebRTC.framework from {:?} to {:?}",
 98        source_path,
 99        target_path
100    );
101}
102
103fn get_swift_target() -> SwiftTarget {
104    let mut arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
105    if arch == "aarch64" {
106        arch = "arm64".into();
107    }
108    let target = format!("{}-apple-macosx{}", arch, MACOS_TARGET_VERSION);
109
110    let swift_target_info_str = Command::new("swift")
111        .args(&["-target", &target, "-print-target-info"])
112        .output()
113        .unwrap()
114        .stdout;
115
116    serde_json::from_slice(&swift_target_info_str).unwrap()
117}
118
119const SWIFT_PACKAGE_NAME: &'static str = "LiveKitBridge";
120
121fn swift_package_root() -> PathBuf {
122    env::current_dir().unwrap().join(SWIFT_PACKAGE_NAME)
123}
124
125impl SwiftTarget {
126    fn out_dir_path(&self) -> PathBuf {
127        swift_package_root()
128            .join(".build")
129            .join(&self.target.unversioned_triple)
130            .join(env::var("PROFILE").unwrap())
131    }
132}