diff --git a/.github/workflows/uplink-sys-cross-aarch64-linux.yml b/.github/workflows/uplink-sys-cross-aarch64-linux.yml new file mode 100644 index 0000000..2f5e106 --- /dev/null +++ b/.github/workflows/uplink-sys-cross-aarch64-linux.yml @@ -0,0 +1,40 @@ +name: Cross-compile uplink-sys to aarch64 Linux + +on: + push: + branches: ["main"] + paths: + - 'uplink-sys/**' + - 'Cargo.lock' + - 'Cargo.toml' + - 'docker-compose.yaml' + - 'Makefile' + pull_request: + branches: ["main"] + paths: + - 'uplink-sys/**' + - 'Cargo.lock' + - 'Cargo.toml' + - 'docker-compose.yaml' + - 'Makefile' +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: ubuntu-latest + env: + CARGO_BUILD_TARGET: aarch64-unknown-linux-gnu + BINDGEN_EXTRA_CLANG_ARGS: "--sysroot=/usr/aarch64-linux-gnu" + + steps: + - uses: actions/checkout@v4 + + - name: Set up `aarch64-unknown-linux-gnu` Rust target + run: rustup target add aarch64-unknown-linux-gnu + + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends clang libclang-dev libc6-dev-arm64-cross && sudo snap install zig --classic --beta + + - name: Build + run: make -C uplink-sys build diff --git a/.github/workflows/uplink-sys.yml b/.github/workflows/uplink-sys.yml index dd3216b..1d51251 100644 --- a/.github/workflows/uplink-sys.yml +++ b/.github/workflows/uplink-sys.yml @@ -2,7 +2,7 @@ name: uplink-sys on: push: - branches: main + branches: ["main"] paths: - 'uplink-sys/**' - 'Cargo.lock' diff --git a/uplink-sys/build.rs b/uplink-sys/build.rs index 2c9bb97..f32bee0 100644 --- a/uplink-sys/build.rs +++ b/uplink-sys/build.rs @@ -4,7 +4,57 @@ use std::env; use std::path::PathBuf; use std::process::Command; +/// Converts Rust's architecture name to Go's architecture name. +fn rust_arch_to_go_arch(rust_arch: &str) -> &str { + match rust_arch { + "x86" => "386", + "x86_64" => "amd64", + "arm" => "arm", + "aarch64" => "arm64", + "riscv32" => "riscv", + "riscv64" => "riscv64", + "loongarch64" => "loong64", + "mips" => "mips", + "mipsel" => "mipsle", + "mips64" => "mips64", + "mips64el" => "mips64le", + "powerpc" => "ppc", + "powerpc64" => "ppc64", + "wasm64" => "wasm", + _ => panic!("Unsupported architecture: {rust_arch}"), + } +} + +fn rust_os_to_go_os<'a>(rust_arch: &str, rust_os: &'a str) -> &'a str { + if rust_arch.starts_with("wasm") { + return "js"; + } + + match rust_os { + "macos" => "darwin", + _ => rust_os, + } +} + fn main() { + // Set the environment variables for `go` compilation, so that cross-compilation works. + let host_triple = env::var("HOST").expect("HOST not defined"); + let target_triple = env::var("TARGET").expect("TARGET not defined"); + let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS not defined"); + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH not defined"); + let go_arch = rust_arch_to_go_arch(&target_arch); + let go_os = rust_os_to_go_os(&target_arch, &target_os); + + // If cross-compiling, suggest to the user that they will need to set their sysroot properly. + if target_triple != host_triple { + if !env::var("BINDGEN_EXTRA_CLANG_ARGS") + .unwrap_or_default() + .contains("sysroot") + { + panic!("Environment variable `BINDGEN_EXTRA_CLANG_ARGS` should contain `--sysroot=/path/to/target/sysroot` when cross-compiling"); + } + } + let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not defined")); // Directory containing uplink-c project source @@ -22,6 +72,8 @@ fn main() { // parent tree directory and with the same depth. Command::new("make") .arg("build") + .env("GOOS", go_os) + .env("GOARCH", go_arch) .current_dir(&uplink_c_src) .status() .expect("Failed to run make command from build.rs."); @@ -83,7 +135,7 @@ fn main() { // // N.B.: `CARGO_CFG_TARGET_OS` should be read instead of `cfg(target_os = "macos")`. The latter // detects the host OS that is building the `build.rs` script, not the target OS. - if env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS is not defined") == "macos" { + if target_os == "macos" { println!("cargo:rustc-flags=-l framework=CoreFoundation -l framework=Security"); } diff --git a/uplink-sys/uplink-c b/uplink-sys/uplink-c index 4ecaa42..056e11d 160000 --- a/uplink-sys/uplink-c +++ b/uplink-sys/uplink-c @@ -1 +1 @@ -Subproject commit 4ecaa42f90a18b243ebacbc0a035ac62e17ecdca +Subproject commit 056e11d3e9ac0e8b2f1f435eb8a9e6de8c660408