Skip to content

Commit

Permalink
ffi: update build script
Browse files Browse the repository at this point in the history
Signed-off-by: Yuki Kishimoto <[email protected]>
  • Loading branch information
yukibtc committed Jan 4, 2025
1 parent ddacb06 commit bd0848a
Showing 1 changed file with 52 additions and 25 deletions.
77 changes: 52 additions & 25 deletions bindings/nostr-sdk-ffi/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
// Distributed under the MIT software license

use std::env;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::process::Command;

const DEFAULT_CLANG_VERSION: &str = "17";

fn main() {
if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
if let Ok(git_hash) = String::from_utf8(output.stdout) {
Expand All @@ -22,30 +20,59 @@ fn main() {
/// Adds a temporary workaround for an issue with the Rust compiler and Android
/// in x86_64 devices: https://github.com/rust-lang/rust/issues/109717.
/// The workaround comes from: https://github.com/mozilla/application-services/pull/5442
/// This below code is inspired by: https://github.com/matrix-org/matrix-rust-sdk/blob/f18e0b18a1ea757921bcae07c29600a9839fdc97/bindings/matrix-sdk-ffi/build.rs
fn setup_x86_64_android_workaround() {
let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set");
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");
// Get target OS and arch
let target_os: String = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set");
let target_arch: String =
env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");

// Check if match x86_64-android
if target_arch == "x86_64" && target_os == "android" {
let android_ndk_home = env::var("ANDROID_NDK_HOME").expect("ANDROID_NDK_HOME not set");
let build_os = match env::consts::OS {
"linux" => "linux",
"macos" => "darwin",
"windows" => "windows",
_ => panic!(
"Unsupported OS. You must use either Linux, MacOS or Windows to build the crate."
),
};
let clang_version =
env::var("NDK_CLANG_VERSION").unwrap_or_else(|_| DEFAULT_CLANG_VERSION.to_owned());
let linux_x86_64_lib_dir = format!(
"toolchains/llvm/prebuilt/{build_os}-x86_64/lib/clang/{clang_version}/lib/linux/"
// Configure rust to statically link against the `libclang_rt.builtins` supplied
// with clang.

// cargo-ndk sets CC_x86_64-linux-android to the path to `clang`, within the
// Android NDK.
let clang_path = PathBuf::from(
env::var("CC_x86_64-linux-android").expect("CC_x86_64-linux-android not set"),
);
let linkpath = format!("{android_ndk_home}/{linux_x86_64_lib_dir}");
if Path::new(&linkpath).exists() {
println!("cargo:rustc-link-search={android_ndk_home}/{linux_x86_64_lib_dir}");
println!("cargo:rustc-link-lib=static=clang_rt.builtins-x86_64-android");
} else {
panic!("Path {linkpath} not exists");
}

// clang_path should now look something like
// `.../sdk/ndk/28.0.12674087/toolchains/llvm/prebuilt/linux-x86_64/bin/clang`.
// We strip `/bin/clang` from the end to get the toolchain path.
let toolchain_path = clang_path
.ancestors()
.nth(2)
.expect("could not find NDK toolchain path")
.to_str()
.expect("NDK toolchain path is not valid UTF-8");

let clang_version = get_clang_major_version(&clang_path);

println!("cargo:rustc-link-search={toolchain_path}/lib/clang/{clang_version}/lib/linux/");
println!("cargo:rustc-link-lib=static=clang_rt.builtins-x86_64-android");
}
}

/// Run the clang binary at `clang_path`, and return its major version number
fn get_clang_major_version(clang_path: &Path) -> String {
let clang_output = Command::new(clang_path)
.arg("-dumpversion")
.output()
.expect("failed to start clang");

if !clang_output.status.success() {
panic!(
"failed to run clang: {}",
String::from_utf8_lossy(&clang_output.stderr)
);
}

let clang_version = String::from_utf8(clang_output.stdout).expect("clang output is not utf8");
clang_version
.split('.')
.next()
.expect("could not parse clang output")
.to_owned()
}

0 comments on commit bd0848a

Please sign in to comment.