Skip to content

Commit

Permalink
uplink-sys(build): Fix cross-compilation
Browse files Browse the repository at this point in the history
This fixes cross-compilation by setting the Go `GOOS` and `GOARCH` flags
for `uplink-c`.
  • Loading branch information
GodTamIt committed Jan 2, 2025
1 parent 4fb6132 commit 6563ac9
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 3 deletions.
40 changes: 40 additions & 0 deletions .github/workflows/uplink-sys-cross-aarch64-linux.yml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion .github/workflows/uplink-sys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: uplink-sys

on:
push:
branches: main
branches: ["main"]
paths:
- 'uplink-sys/**'
- 'Cargo.lock'
Expand Down
51 changes: 50 additions & 1 deletion uplink-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,54 @@ 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 && !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
Expand All @@ -22,6 +69,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.");
Expand Down Expand Up @@ -83,7 +132,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");
}

Expand Down
2 changes: 1 addition & 1 deletion uplink-sys/uplink-c
Submodule uplink-c updated 6 files
+25 −7 GNUmakefile
+1 −0 Jenkinsfile
+1 −1 go.mod
+2 −2 go.sum
+110 −0 scripts/build-lib
+4 −5 scripts/version

0 comments on commit 6563ac9

Please sign in to comment.