Skip to content

Make non-glibc Linux cross-compilation work#55

Open
Schnitzel wants to merge 1 commit into
256foundation:mainfrom
Schnitzel:cross-compile-musl-aarch64
Open

Make non-glibc Linux cross-compilation work#55
Schnitzel wants to merge 1 commit into
256foundation:mainfrom
Schnitzel:cross-compile-musl-aarch64

Conversation

@Schnitzel
Copy link
Copy Markdown
Member

Summary

Three small changes that let mujina-miner cross-compile for aarch64-unknown-linux-musl (and other non-glibc Linux targets), so it can be deployed onto mining hardware that ships with musl userspace — concretely, the Amlogic A113D control board found on Antminer S19 series miners.

  • Switch reqwest to rustls-tls. The default features pull in native-tls, which transitively requires openssl-sys. Cross-building openssl-sys to musl is painful (sysroot, pkg-config wrapper, vendored OpenSSL or a sysroot install) and unnecessary when reqwest can use rustls directly.
  • Gate udev and tracing-journald to target_env = "gnu". Both link against glibc-only system libraries (libudev, libsystemd) that have no good musl story. The existing fallback mod platform in src/transport/usb.rs already covers the no-udev case as a stub for unsupported platforms (Windows, etc.), so musl Linux now falls into that same path — fine for the CPU backend and any non-USB hashboard.
  • Same cfg change in src/tracing.rs so the journald init mod follows the same gate as its dependency.

Net diff: 4 files, +7 / -7 lines.

Test plan

  • cargo build --release on macOS (aarch64-apple-darwin) — unchanged, still builds.
  • cargo build --release --target aarch64-unknown-linux-musl --bin mujina-minerd from macOS — now succeeds (previously failed at openssl-sys and udev).
  • Resulting 17 MB statically-linked aarch64 ELF transferred to an Antminer S19j Pro control board (LuxOS base, kernel aarch64 / userspace armhf — the static aarch64 binary runs fine via the 64-bit kernel).
  • MUJINA_CPUMINER_THREADS=1 MUJINA_CPUMINER_DUTY=50 MUJINA_USB_DISABLE=1 MUJINA_API_LISTEN=0.0.0.0:7785 ./mujina-minerd — comes up cleanly, CPU board attached, dummy job source, REST API responds at /swagger-ui, mining-status log line ticks at 30s.

Build steps on macOS

rustup target add aarch64-unknown-linux-musl
brew install messense/macos-cross-toolchains/aarch64-unknown-linux-musl

CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-unknown-linux-musl-gcc \
CC_aarch64_unknown_linux_musl=aarch64-unknown-linux-musl-gcc \
  cargo build --release --target aarch64-unknown-linux-musl --bin mujina-minerd

Notes / open questions

  • The reqwest rustls swap is mildly opinionated. If you'd prefer to keep native-tls as the default and offer rustls behind a feature flag instead, happy to refactor — but it'd add complexity for the cross-build path with no obvious upstream benefit.
  • This is the minimal change to make the build work. Real S19 hashboard support (driving BM1362 chips over UART, APW12 PSU over I²C, fans, EEPROM decode, PIC sensor reads) is separate work — see skot/amlogic-cb-tools for the standalone hardware-validation binaries that prove out the control-board interfaces before they land in mujina.

Three small changes that let mujina-miner cross-compile for
aarch64-unknown-linux-musl (and other non-glibc Linux targets) so it
can be deployed to mining hardware that ships with musl userspace --
e.g. the Amlogic A113D control board on Antminer S19 series.

- Switch reqwest to rustls-tls. Default features pull in native-tls,
  which transitively requires openssl-sys; cross-building openssl-sys
  to musl is painful and unnecessary when reqwest can use rustls.

- Gate udev and tracing-journald to target_env = "gnu". Both link
  against glibc-only system libraries (libudev, libsystemd) that have
  no good musl story. The existing fallback module in
  src/transport/usb.rs already covers the no-udev case as a stub, so
  musl Linux falls into the same "USB hashboard discovery
  unsupported" path as Windows etc. -- fine for the CPU backend and
  any non-USB board.

- Same gate change in src/tracing.rs: the journald init path requires
  tracing-journald, so it has to follow the same cfg.

Tested by cross-compiling mujina-minerd from macOS to
aarch64-unknown-linux-musl and running on an Antminer S19j Pro
control board (kernel aarch64, userspace armhf, musl static binary
runs fine via the 64-bit kernel) with MUJINA_USB_DISABLE=1 and the
CPU backend.

Build prereqs on macOS:
  rustup target add aarch64-unknown-linux-musl
  brew install messense/macos-cross-toolchains/aarch64-unknown-linux-musl

Then:
  CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-unknown-linux-musl-gcc \
  CC_aarch64_unknown_linux_musl=aarch64-unknown-linux-musl-gcc \
    cargo build --release --target aarch64-unknown-linux-musl --bin mujina-minerd
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts mujina-miner to successfully cross-compile for non-glibc Linux targets (notably aarch64-unknown-linux-musl) by avoiding glibc-only system integrations and removing OpenSSL/native-tls requirements from the HTTP client dependency chain.

Changes:

  • Switch workspace reqwest configuration to default-features = false and enable rustls-tls (avoids openssl-sys).
  • Gate Linux-only dependencies (udev, tracing-journald) to cfg(all(target_os = "linux", target_env = "gnu")).
  • Gate Linux journald initialization and Linux USB serial-port discovery code to the same glibc-only cfg, falling back to stub behavior on musl.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
Cargo.toml Reconfigures reqwest to use rustls and avoid native-tls/OpenSSL.
mujina-miner/Cargo.toml Limits udev and tracing-journald dependencies to glibc Linux targets.
mujina-miner/src/transport/usb.rs Limits Linux USB serial-port discovery module to glibc Linux; uses stub elsewhere (incl. musl).
mujina-miner/src/tracing.rs Limits journald init module to glibc Linux; uses stub elsewhere.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mujina-miner/Cargo.toml
[target.'cfg(all(target_os = "linux", target_env = "gnu"))'.dependencies]
tracing-journald = { workspace = true }
udev = { workspace = true }

Comment on lines +28 to 32
#[cfg(all(target_os = "linux", target_env = "gnu"))]
mod linux;
#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", target_env = "gnu"))]
use linux as platform;

Comment on lines +56 to 59
#[cfg(all(target_os = "linux", target_env = "gnu"))]
mod journald {
use std::env;
use std::io;
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.

2 participants