diff --git a/.github/workflows/ksuinit.yml b/.github/workflows/ksuinit.yml index b25aaebc416e..0e834adfae82 100644 --- a/.github/workflows/ksuinit.yml +++ b/.github/workflows/ksuinit.yml @@ -26,11 +26,8 @@ jobs: - name: Build ksuinit run: | - LLVM_BIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin - export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER="$LLVM_BIN/aarch64-linux-android26-clang" - export RUSTFLAGS="-C link-arg=-no-pie" - cd userspace/ksuinit - cargo build --target=aarch64-unknown-linux-musl --release + cd userspace + cargo build-ksuinit - name: Upload ksuinit artifact uses: actions/upload-artifact@v6 diff --git a/userspace/.cargo/config.toml b/userspace/.cargo/config.toml new file mode 100644 index 000000000000..b93128b5613f --- /dev/null +++ b/userspace/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +build-ksuinit = "run --manifest-path tools/Cargo.toml --bin build-ksuinit --" diff --git a/userspace/ksuinit/.cargo/config.example.toml b/userspace/ksuinit/.cargo/config.example.toml new file mode 100644 index 000000000000..f18a254a344f --- /dev/null +++ b/userspace/ksuinit/.cargo/config.example.toml @@ -0,0 +1,3 @@ +[build] +# uncomment below if you need rust-analyzer +# target = "aarch64-unknown-linux-musl" diff --git a/userspace/ksuinit/.gitignore b/userspace/ksuinit/.gitignore index 92d4c73b9a5c..823be7e85ce9 100644 --- a/userspace/ksuinit/.gitignore +++ b/userspace/ksuinit/.gitignore @@ -1,3 +1,3 @@ /target /.idea -.cargo +.cargo/config.toml diff --git a/userspace/tools/.gitignore b/userspace/tools/.gitignore new file mode 100644 index 000000000000..eb5a316cbd19 --- /dev/null +++ b/userspace/tools/.gitignore @@ -0,0 +1 @@ +target diff --git a/userspace/tools/Cargo.lock b/userspace/tools/Cargo.lock new file mode 100644 index 000000000000..d665baeb82ad --- /dev/null +++ b/userspace/tools/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "tools" +version = "0.1.0" diff --git a/userspace/tools/Cargo.toml b/userspace/tools/Cargo.toml new file mode 100644 index 000000000000..7ee5b6eef1c3 --- /dev/null +++ b/userspace/tools/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "tools" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "build-ksuinit" +path = "src/bin/build-ksuinit.rs" + +[dependencies] diff --git a/userspace/tools/src/bin/build-ksuinit.rs b/userspace/tools/src/bin/build-ksuinit.rs new file mode 100644 index 000000000000..14863e1d15b7 --- /dev/null +++ b/userspace/tools/src/bin/build-ksuinit.rs @@ -0,0 +1,91 @@ +use std::env; +use std::path::{Path, PathBuf}; +use std::process::{Command, ExitCode}; + +const TARGET: &str = "aarch64-unknown-linux-musl"; + +fn host_tag() -> &'static str { + match env::consts::OS { + "windows" => "windows", + "linux" => "linux", + "macos" => "darwin", + other => { + eprintln!("Unsupported host OS: {other}"); + std::process::exit(2); + } + } +} + +fn find_linker(ndk_home: &Path) -> PathBuf { + let base = ndk_home + .join("toolchains") + .join("llvm") + .join("prebuilt") + .join(format!("{}-x86_64", host_tag())) + .join("bin"); + + let linker = if cfg!(windows) { + let cmd = base.join("aarch64-linux-android26-clang.cmd"); + if cmd.exists() { + cmd + } else { + base.join("aarch64-linux-android26-clang") + } + } else { + base.join("aarch64-linux-android26-clang") + }; + + if !linker.exists() { + eprintln!("Linker not found: {}", linker.display()); + std::process::exit(2); + } + + linker +} + +fn main() -> ExitCode { + let ndk_home = match env::var("ANDROID_NDK_HOME") { + Ok(v) if !v.trim().is_empty() => v, + _ => { + eprintln!("ANDROID_NDK_HOME is required"); + return ExitCode::from(2); + } + }; + + let linker = find_linker(Path::new(&ndk_home)); + let rustflags = match env::var("RUSTFLAGS") { + Ok(existing) if !existing.trim().is_empty() => format!("{existing} -C link-arg=-no-pie"), + _ => "-C link-arg=-no-pie".to_string(), + }; + + let mut cmd = Command::new("cargo"); + cmd.arg("build") + .arg("--target") + .arg(TARGET) + .arg("--release") + .current_dir(Path::new(env!("CARGO_MANIFEST_DIR")).join("../ksuinit")) + .env( + "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER", + linker.as_os_str(), + ) + .env("RUSTFLAGS", rustflags); + + // Allow users to append extra build flags after `--`. + for arg in env::args().skip(1) { + cmd.arg(arg); + } + + let status = match cmd.status() { + Ok(s) => s, + Err(e) => { + eprintln!("Failed to execute cargo build: {e}"); + return ExitCode::from(1); + } + }; + + if status.success() { + ExitCode::SUCCESS + } else { + ExitCode::from(1) + } +}