-
Notifications
You must be signed in to change notification settings - Fork 2
/
build.rs
139 lines (114 loc) · 3.36 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// https://haim.dev/posts/2020-09-10-linking-swift-code-into-rust-app/
use serde::Deserialize;
use std::{env, str};
use std::process::Command;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct SwiftPaths {
runtime_library_paths: Vec<String>,
}
#[derive(Debug, Deserialize)]
struct SwiftTargetInfo {
paths: SwiftPaths,
}
fn profile() -> String {
env::var("PROFILE").unwrap()
}
fn out_dir() -> String {
env::var("OUT_DIR").unwrap()
}
fn manifest_dir() -> String {
env::var("CARGO_MANIFEST_DIR").unwrap()
}
fn target_arch() -> String {
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
match arch.as_str() {
"aarch64" => "arm64".to_owned(),
_ => arch,
}
}
fn target_os() -> String {
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
match os.as_str() {
"macos" => "macosx".to_owned(),
"ios" => "ios".to_owned(),
_ => os,
}
}
fn target_os_version() -> String {
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
match os.as_str() {
"macos" => "14".to_owned(),
"ios" => "17.0".to_owned(),
_ => os,
}
}
fn target_sdk() -> String {
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
match os.as_str() {
"macos" => "macosx".to_owned(),
"ios" => "iphoneos".to_owned(),
_ => os,
}
}
fn target_vendor() -> String {
env::var("CARGO_CFG_TARGET_VENDOR").unwrap()
}
fn target() -> String {
format!("{}-{}-{}", target_arch(), target_vendor(), target_os())
}
fn target_with_version() -> String {
format!("{}{}", target(), target_os_version())
}
fn find_swift_runtime_libs() {
let target_with_version = target_with_version();
let raw_target_info = Command::new("swift")
.args(["-target", &target_with_version, "-print-target-info"])
.output()
.unwrap()
.stdout;
let target_info: SwiftTargetInfo = serde_json::from_slice(&raw_target_info)
.expect("Could not parse Swift target info");
for path in target_info.paths.runtime_library_paths {
println!("cargo:rustc-link-search=native={path}");
}
}
fn build_nuit_bridge_swiftui() {
let out_dir = out_dir();
let profile = profile();
let target = target();
let sdk = target_sdk();
let sdk_path = str::from_utf8(
&Command::new("xcrun")
.args(["--sdk", &sdk, "--show-sdk-path"])
.output()
.unwrap()
.stdout
).unwrap().trim().to_owned();
let build_succeeded = Command::new("xcrun")
.args([
// We have to make sure that we always use the macOS version of the
// Swift Package Manager, even when cross-compiling for iOS.
"--sdk", "macosx",
"swift",
"build",
"--sdk", &sdk_path,
"--triple", &target,
"--build-path", &out_dir,
"-c", &profile,
])
.status()
.unwrap()
.success();
assert!(build_succeeded, "Swift build failed");
let root = manifest_dir();
println!("cargo:rustc-link-search=native={out_dir}/{target}/{profile}");
println!("cargo:rustc-link-lib=static=nuit-bridge-swiftui");
println!("cargo:rerun-if-changed={root}/Sources/**/*.swift");
}
fn main() {
if target_vendor() == "apple" {
find_swift_runtime_libs();
build_nuit_bridge_swiftui();
}
}