Skip to content

feat: support cross-compiling to aarch64-linux-android#5196

Draft
eval-exec wants to merge 1 commit intonervosnetwork:developfrom
eval-exec:ckb.aarch64-linux-android
Draft

feat: support cross-compiling to aarch64-linux-android#5196
eval-exec wants to merge 1 commit intonervosnetwork:developfrom
eval-exec:ckb.aarch64-linux-android

Conversation

@eval-exec
Copy link
Copy Markdown
Collaborator

What problem does this PR solve?

CKB has not been buildable for aarch64-linux-android. Cross-compiling out of the box fails on:

  • daemonize-me (referenced by ckb-bin) does not support target_os = "android" — its FFIPasswd struct is gated to linux/macos/freebsd/openbsd/netbsd only.
  • ckb-librocksdb-sys's build_detect_platform script unconditionally adds x86 SSE/AVX/BMI/PCLMUL flags when the probing compiler accepts them, which breaks the NDK aarch64 clang during the C++ build.
  • bindgen for rocksdb cannot find Android system headers without explicit sysroot/clang configuration.
  • NDK 23+ no longer ships libgcc, but rustc still passes -lgcc to the linker when targeting *-linux-android.

Problem Summary: provide a reproducible cross-compilation environment (Nix flake, NixOS-friendly) and the small source patches needed to actually build ckb for aarch64-linux-android.

What is changed and how it works?

What's Changed:

  • flake.nix (new): devShell wiring rust-overlay (rustc 1.92.0 + aarch64-linux-android target) and pkgsCross.aarch64-android-prebuilt (Android NDK 27).
    • HOST_CC/CXX/AR/LD/RANLIB point at host gcc/g++/ar/ld/ranlib so cargo build scripts that compile and link on the host work correctly.
    • CC/CXX/AR/RANLIB/STRIP and CARGO_TARGET_AARCH64_LINUX_ANDROID_* point at the NDK toolchain so the target compiler is used for cross-compilation (and so build_detect_platform's SSE probes correctly fail on aarch64, skipping the x86 flags).
    • LIBCLANG_PATH and BINDGEN_EXTRA_CLANG_ARGS use the NDK's bundled clang-18 with the unwrapped sysroot so bindgen finds Android headers (uint32_t, etc.).
    • TARGET_OS=OS_ANDROID_CROSSCOMPILE and TARGET_ARCHITECTURE=aarch64 hint rocksdb's detect script.
    • A stub libgcc.a containing INPUT(-lunwind) is generated and added to the Android linker search path via CARGO_TARGET_AARCH64_LINUX_ANDROID_RUSTFLAGS to satisfy rustc's hardcoded -lgcc.
  • .cargo/config.toml: add empty [target.aarch64-linux-android] stanza; linker comes from the env vars set by the devShell.
  • .gitignore: ignore .android-libgcc-stub/.
  • Source cfg changes: extend cfg(not(target_os = "windows")) to also exclude target_os = "android" for daemonization-related code, in:
    • ckb-bin/Cargo.toml, ckb-bin/src/{lib.rs,setup.rs,cli.rs,subcommand/mod.rs}
    • util/app-config/src/args.rs (the daemon field of RunArgs)

Build command:

nix develop --command cargo build --release --target aarch64-linux-android --bin ckb

Produces target/aarch64-linux-android/release/ckb:

ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV),
dynamically linked, interpreter /system/bin/linker64

Related changes

  • No companion PRs.
  • No cherry-pick to release branches needed.

Check List

Tests

  • Manual test: built --release --bin ckb for aarch64-linux-android from a NixOS x86_64 host using nix develop; verified the resulting ELF is ARM aarch64 and dynamically linked against Android's /system/bin/linker64.

Side effects

  • No behavior change for existing supported targets: changes are limited to additional cfg exclusions for target_os = "android" (which was previously unbuildable) and a new flake.nix/.cargo/config.toml stanza that only affects the new target.

Add a Nix flake providing a devShell that cross-compiles ckb for
aarch64-linux-android using the Android NDK 27 toolchain together with
rust-overlay (rustc 1.92.0 + aarch64-linux-android target).

Source changes:
- Extend the existing 'cfg(not(target_os = "windows"))' gates around
  daemonization (daemonize-me, daemon subcommand, RunArgs.daemon field)
  to also exclude target_os = "android" since daemonize-me does not
  support Android.

Build/tooling:
- flake.nix: rust-overlay toolchain + pkgsCross.aarch64-android-prebuilt
  NDK; HOST_* point at host gcc while CC/CXX point at the NDK so
  rocksdb's build_detect_platform probes the *target* compiler and
  skips x86 SSE flags; LIBCLANG_PATH and BINDGEN_EXTRA_CLANG_ARGS use
  the NDK's bundled clang and the unwrapped sysroot so bindgen finds
  Android headers; TARGET_OS/TARGET_ARCHITECTURE hint rocksdb's detect
  script; a stub libgcc.a (INPUT(-lunwind)) is placed on the linker
  search path because NDK 23+ removed libgcc but rustc still passes
  -lgcc when targeting *-linux-android.
- .cargo/config.toml: add empty [target.aarch64-linux-android] stanza;
  the linker is supplied by the shell environment.
- .gitignore: ignore .android-libgcc-stub/.

Build:
  nix develop --command cargo build --release \
    --target aarch64-linux-android --bin ckb

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eval-exec eval-exec requested a review from a team as a code owner April 30, 2026 07:57
@eval-exec eval-exec requested review from Copilot and quake and removed request for a team and Copilot April 30, 2026 07:57
@eval-exec eval-exec marked this pull request as draft April 30, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant