atagen

matrix-rust-sdk

public
Star0
Watch0
ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk.git

Blame: bindings/matrix-sdk-ffi/build.rs

7ff8adafe9e4atagen2026-10-22 12:30 UTC1
// Copyright 2025 The Matrix.org Foundation C.I.C.
7ff8adafe9e4atagen2026-10-22 12:30 UTC2
//
7ff8adafe9e4atagen2026-10-22 12:30 UTC3
// Licensed under the Apache License, Version 2.0 (the "License");
7ff8adafe9e4atagen2026-10-22 12:30 UTC4
// you may not use this file except in compliance with the License.
7ff8adafe9e4atagen2026-10-22 12:30 UTC5
// You may obtain a copy of the License at
7ff8adafe9e4atagen2026-10-22 12:30 UTC6
//
7ff8adafe9e4atagen2026-10-22 12:30 UTC7
//     http://www.apache.org/licenses/LICENSE-2.0
7ff8adafe9e4atagen2026-10-22 12:30 UTC8
//
7ff8adafe9e4atagen2026-10-22 12:30 UTC9
// Unless required by applicable law or agreed to in writing, software
7ff8adafe9e4atagen2026-10-22 12:30 UTC10
// distributed under the License is distributed on an "AS IS" BASIS,
7ff8adafe9e4atagen2026-10-22 12:30 UTC11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7ff8adafe9e4atagen2026-10-22 12:30 UTC12
// See the License for that specific language governing permissions and
7ff8adafe9e4atagen2026-10-22 12:30 UTC13
// limitations under the License.
7ff8adafe9e4atagen2026-10-22 12:30 UTC14
7ff8adafe9e4atagen2026-10-22 12:30 UTC15
use std::{
7ff8adafe9e4atagen2026-10-22 12:30 UTC16
    env,
7ff8adafe9e4atagen2026-10-22 12:30 UTC17
    error::Error,
7ff8adafe9e4atagen2026-10-22 12:30 UTC18
    path::{Path, PathBuf},
7ff8adafe9e4atagen2026-10-22 12:30 UTC19
    process::Command,
7ff8adafe9e4atagen2026-10-22 12:30 UTC20
};
7ff8adafe9e4atagen2026-10-22 12:30 UTC21
7ff8adafe9e4atagen2026-10-22 12:30 UTC22
use vergen_gitcl::{Emitter, GitclBuilder};
7ff8adafe9e4atagen2026-10-22 12:30 UTC23
7ff8adafe9e4atagen2026-10-22 12:30 UTC24
/// Adds a temporary workaround for an issue with the Rust compiler and Android
7ff8adafe9e4atagen2026-10-22 12:30 UTC25
/// in x86_64 devices: https://github.com/rust-lang/rust/issues/109717.
7ff8adafe9e4atagen2026-10-22 12:30 UTC26
/// The workaround is based on: https://github.com/mozilla/application-services/pull/5442
7ff8adafe9e4atagen2026-10-22 12:30 UTC27
///
7ff8adafe9e4atagen2026-10-22 12:30 UTC28
/// TODO: I think this is obsolete with cargo-ndk 4.0.0:
7ff8adafe9e4atagen2026-10-22 12:30 UTC29
/// https://github.com/bbqsrc/cargo-ndk/commit/03c738653f935416580803b82fc6ad72c10dbebc
7ff8adafe9e4atagen2026-10-22 12:30 UTC30
///
7ff8adafe9e4atagen2026-10-22 12:30 UTC31
/// IMPORTANT: if you modify this, make sure to modify
7ff8adafe9e4atagen2026-10-22 12:30 UTC32
/// [../matrix-sdk-crypto-ffi/build.rs] too!
7ff8adafe9e4atagen2026-10-22 12:30 UTC33
fn setup_x86_64_android_workaround() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC34
    let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not set");
7ff8adafe9e4atagen2026-10-22 12:30 UTC35
    let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not set");
7ff8adafe9e4atagen2026-10-22 12:30 UTC36
    if target_arch == "x86_64" && target_os == "android" {
7ff8adafe9e4atagen2026-10-22 12:30 UTC37
        // Configure rust to statically link against the `libclang_rt.builtins` supplied
7ff8adafe9e4atagen2026-10-22 12:30 UTC38
        // with clang.
7ff8adafe9e4atagen2026-10-22 12:30 UTC39
7ff8adafe9e4atagen2026-10-22 12:30 UTC40
        // cargo-ndk sets CC_x86_64-linux-android to the path to `clang`, within the
7ff8adafe9e4atagen2026-10-22 12:30 UTC41
        // Android NDK.
7ff8adafe9e4atagen2026-10-22 12:30 UTC42
        let clang_path = PathBuf::from(
7ff8adafe9e4atagen2026-10-22 12:30 UTC43
            env::var("CC_x86_64-linux-android").expect("CC_x86_64-linux-android not set"),
7ff8adafe9e4atagen2026-10-22 12:30 UTC44
        );
7ff8adafe9e4atagen2026-10-22 12:30 UTC45
7ff8adafe9e4atagen2026-10-22 12:30 UTC46
        // clang_path should now look something like
7ff8adafe9e4atagen2026-10-22 12:30 UTC47
        // `.../sdk/ndk/28.0.12674087/toolchains/llvm/prebuilt/linux-x86_64/bin/clang`.
7ff8adafe9e4atagen2026-10-22 12:30 UTC48
        // We strip `/bin/clang` from the end to get the toolchain path.
7ff8adafe9e4atagen2026-10-22 12:30 UTC49
        let toolchain_path = clang_path
7ff8adafe9e4atagen2026-10-22 12:30 UTC50
            .ancestors()
7ff8adafe9e4atagen2026-10-22 12:30 UTC51
            .nth(2)
7ff8adafe9e4atagen2026-10-22 12:30 UTC52
            .expect("could not find NDK toolchain path")
7ff8adafe9e4atagen2026-10-22 12:30 UTC53
            .to_str()
7ff8adafe9e4atagen2026-10-22 12:30 UTC54
            .expect("NDK toolchain path is not valid UTF-8");
7ff8adafe9e4atagen2026-10-22 12:30 UTC55
7ff8adafe9e4atagen2026-10-22 12:30 UTC56
        let clang_version = get_clang_major_version(&clang_path);
7ff8adafe9e4atagen2026-10-22 12:30 UTC57
7ff8adafe9e4atagen2026-10-22 12:30 UTC58
        println!("cargo:rustc-link-search={toolchain_path}/lib/clang/{clang_version}/lib/linux/");
7ff8adafe9e4atagen2026-10-22 12:30 UTC59
        println!("cargo:rustc-link-lib=static=clang_rt.builtins-x86_64-android");
7ff8adafe9e4atagen2026-10-22 12:30 UTC60
7ff8adafe9e4atagen2026-10-22 12:30 UTC61
        // Ensure we re-run this build script if the location of the toolchain changes.
7ff8adafe9e4atagen2026-10-22 12:30 UTC62
        println!("cargo:rerun-if-env-changed=CC_x86_64-linux-android");
7ff8adafe9e4atagen2026-10-22 12:30 UTC63
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC64
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC65
7ff8adafe9e4atagen2026-10-22 12:30 UTC66
/// Adds a workaround for watchOS simulator builds to manually link against the
7ff8adafe9e4atagen2026-10-22 12:30 UTC67
/// CoreFoundation framework in order to avoid linker errors. Otherwise, errors
7ff8adafe9e4atagen2026-10-22 12:30 UTC68
/// like the following may occur:
7ff8adafe9e4atagen2026-10-22 12:30 UTC69
///
7ff8adafe9e4atagen2026-10-22 12:30 UTC70
///   = note: Undefined symbols for architecture arm64:
7ff8adafe9e4atagen2026-10-22 12:30 UTC71
///             "_CFArrayCreate", referenced from:
7ff8adafe9e4atagen2026-10-22 12:30 UTC72
///             "_CFDataCreate", referenced from:
7ff8adafe9e4atagen2026-10-22 12:30 UTC73
///             "_CFRelease", referenced from:
7ff8adafe9e4atagen2026-10-22 12:30 UTC74
///             etc.
7ff8adafe9e4atagen2026-10-22 12:30 UTC75
fn setup_watchos_simulator_workaround() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC76
    let target = env::var("TARGET").expect("TARGET not set");
7ff8adafe9e4atagen2026-10-22 12:30 UTC77
    if target.ends_with("watchos-sim") {
7ff8adafe9e4atagen2026-10-22 12:30 UTC78
        println!("cargo:rustc-link-arg=-framework");
7ff8adafe9e4atagen2026-10-22 12:30 UTC79
        println!("cargo:rustc-link-arg=CoreFoundation");
7ff8adafe9e4atagen2026-10-22 12:30 UTC80
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC81
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC82
7ff8adafe9e4atagen2026-10-22 12:30 UTC83
/// Run the clang binary at `clang_path`, and return its major version number
7ff8adafe9e4atagen2026-10-22 12:30 UTC84
fn get_clang_major_version(clang_path: &Path) -> String {
7ff8adafe9e4atagen2026-10-22 12:30 UTC85
    let clang_output =
7ff8adafe9e4atagen2026-10-22 12:30 UTC86
        Command::new(clang_path).arg("-dumpversion").output().expect("failed to start clang");
7ff8adafe9e4atagen2026-10-22 12:30 UTC87
7ff8adafe9e4atagen2026-10-22 12:30 UTC88
    if !clang_output.status.success() {
7ff8adafe9e4atagen2026-10-22 12:30 UTC89
        panic!("failed to run clang: {}", String::from_utf8_lossy(&clang_output.stderr));
7ff8adafe9e4atagen2026-10-22 12:30 UTC90
    }
7ff8adafe9e4atagen2026-10-22 12:30 UTC91
7ff8adafe9e4atagen2026-10-22 12:30 UTC92
    let clang_version = String::from_utf8(clang_output.stdout).expect("clang output is not utf8");
7ff8adafe9e4atagen2026-10-22 12:30 UTC93
    clang_version.split('.').next().expect("could not parse clang output").to_owned()
7ff8adafe9e4atagen2026-10-22 12:30 UTC94
}
7ff8adafe9e4atagen2026-10-22 12:30 UTC95
7ff8adafe9e4atagen2026-10-22 12:30 UTC96
fn main() -> Result<(), Box<dyn Error>> {
7ff8adafe9e4atagen2026-10-22 12:30 UTC97
    setup_x86_64_android_workaround();
7ff8adafe9e4atagen2026-10-22 12:30 UTC98
    setup_watchos_simulator_workaround();
7ff8adafe9e4atagen2026-10-22 12:30 UTC99
    uniffi::generate_scaffolding("./src/api.udl").expect("Building the UDL file failed");
7ff8adafe9e4atagen2026-10-22 12:30 UTC100
7ff8adafe9e4atagen2026-10-22 12:30 UTC101
    let git_config = GitclBuilder::default().sha(true).build()?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC102
    Emitter::default().add_instructions(&git_config)?.emit()?;
7ff8adafe9e4atagen2026-10-22 12:30 UTC103
7ff8adafe9e4atagen2026-10-22 12:30 UTC104
    Ok(())
7ff8adafe9e4atagen2026-10-22 12:30 UTC105
}