Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: rust-binary-calls-swift-package build on Linux #297

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 76 additions & 34 deletions examples/rust-binary-calls-swift-package/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,48 +17,90 @@ fn main() {
swift_library_static_lib_dir().to_str().unwrap()
);

// Without this we will get warnings about not being able to find dynamic libraries, and then
// we won't be able to compile since the Swift static libraries depend on them:
// For example:
// ld: warning: Could not find or use auto-linked library 'swiftCompatibility51'
// ld: warning: Could not find or use auto-linked library 'swiftCompatibility50'
// ld: warning: Could not find or use auto-linked library 'swiftCompatibilityDynamicReplacements'
// ld: warning: Could not find or use auto-linked library 'swiftCompatibilityConcurrency'
let xcode_path = if let Ok(output) = std::process::Command::new("xcode-select")
.arg("--print-path")
.output()
// This fix is for macOS only
#[cfg(target_os = "macos")]
Comment on lines +20 to +21
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this is also required for other Apple platforms?

{
String::from_utf8(output.stdout.as_slice().into())
.unwrap()
.trim()
.to_string()
} else {
"/Applications/Xcode.app/Contents/Developer".to_string()
};
println!(
"cargo:rustc-link-search={}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/",
&xcode_path
);
println!("cargo:rustc-link-search={}", "/usr/lib/swift");
// Without this we will get warnings about not being able to find dynamic libraries, and then
// we won't be able to compile since the Swift static libraries depend on them:
// For example:
// ld: warning: Could not find or use auto-linked library 'swiftCompatibility51'
// ld: warning: Could not find or use auto-linked library 'swiftCompatibility50'
// ld: warning: Could not find or use auto-linked library 'swiftCompatibilityDynamicReplacements'
// ld: warning: Could not find or use auto-linked library 'swiftCompatibilityConcurrency'
let xcode_path = if let Ok(output) = std::process::Command::new("xcode-select")
.arg("--print-path")
.output()
{
String::from_utf8(output.stdout.as_slice().into())
.unwrap()
.trim()
.to_string()
} else {
"/Applications/Xcode.app/Contents/Developer".to_string()
};
println!(
"cargo:rustc-link-search={}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/",
&xcode_path
);
println!("cargo:rustc-link-search={}", "/usr/lib/swift");
}

// This fix is for Linux only
#[cfg(target_os = "linux")]
{
// Without this there will be a lot of missing symbols when linking to the Swift library.
let swift_lib_path = get_swift_lib_path().unwrap();
println!("cargo:rustc-link-search={}", swift_lib_path);
println!("cargo:rustc-link-lib=swiftCore");
println!("cargo:rustc-link-lib=stdc++");
println!("cargo:rustc-link-lib=swiftSwiftOnoneSupport");
}
}

fn get_swift_lib_path() -> Result<String, String> {
let output = Command::new("which")
.arg("swift")
.output()
.map_err(|e| format!("Failed to execute `which swift`: {}", e))?;

if !output.status.success() {
return Err(format!(
"`which swift` failed with stderr: {}",
String::from_utf8_lossy(&output.stderr)
));
}

let swift_path = String::from_utf8(output.stdout)
.map_err(|e| format!("Failed to parse `which swift` output: {}", e))?
.trim()
.to_string();

let swift_lib_path = PathBuf::from(swift_path)
.parent()
.and_then(|p| p.parent())
.map(|p| p.join("lib/swift_static/linux"))
.ok_or("Failed to determine Swift library path")?;

swift_lib_path
.to_str()
.map(|s| s.to_string())
.ok_or("Failed to convert Swift library path to string".to_string())
}

fn compile_swift() {
let swift_package_dir = manifest_dir().join("swift-library");

let mut cmd = Command::new("swift");

cmd.current_dir(swift_package_dir)
.arg("build")
.args(&["-Xswiftc", "-static"])
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this because the Package.swift already defines this as a static library.

.args(&[
"-Xswiftc",
"-import-objc-header",
"-Xswiftc",
swift_source_dir()
.join("bridging-header.h")
.to_str()
.unwrap(),
]);
cmd.current_dir(swift_package_dir).arg("build").args(&[
"-Xswiftc",
"-import-objc-header",
"-Xswiftc",
swift_source_dir()
.join("bridging-header.h")
.to_str()
.unwrap(),
]);

if is_release_build() {
cmd.args(&["-c", "release"]);
Expand Down