Skip to content

Commit 6d36479

Browse files
feat(aarch64): default to musl-static toolchain on non-x86 Linux (#148)
Bare `mcpp build` (new project, no [toolchain]) on aarch64 tried to install the glibc default gcc@16.1.0 + glibc + linux-headers, which have no aarch64 assets (HTTP 404). On non-x86_64 Linux, default to gcc@15.1.0-musl instead: it's published for aarch64, self-contained (skip glibc/linux-headers deps), and yields portable static binaries (ideal for aarch64/Termux). x86_64 keeps the glibc default. Seeds the host triple so the <host>-linux-musl-g++ frontend resolves for the no---target default. Also: fresh-install CI self-hosts mcpp AND xlings via --target aarch64-linux-musl (their manifests pin a glibc default). Co-authored-by: Sunrisepeak <x.d2learn.org@gmail.com>
1 parent d2a53bf commit 6d36479

2 files changed

Lines changed: 37 additions & 10 deletions

File tree

.github/workflows/ci-aarch64-fresh-install.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,20 @@ jobs:
6969
file "$bin"
7070
file "$bin" | grep -q "ARM aarch64" || { echo "expected aarch64 ELF"; exit 1; }
7171
72-
- name: Self-host — build mcpp from source natively
72+
- name: Self-host — build mcpp + xlings from source natively
7373
run: |
74+
# mcpp/xlings manifests pin a glibc default toolchain; on aarch64 the
75+
# musl-static target is the published path, so build with --target.
7476
git clone --depth 1 https://github.com/mcpp-community/mcpp /tmp/mcpp-src
7577
cd /tmp/mcpp-src
7678
mcpp self config --mirror GLOBAL 2>/dev/null || true
77-
mcpp build
78-
m=$(find target -type f -name mcpp | head -1)
79+
mcpp build --target aarch64-linux-musl
80+
m=$(find target/aarch64-linux-musl -type f -name mcpp | head -1)
7981
file "$m" | grep -q "ARM aarch64" || { echo "expected aarch64 mcpp"; exit 1; }
8082
"$m" --version
83+
git clone --depth 1 https://github.com/openxlings/xlings /tmp/xlings-src
84+
cd /tmp/xlings-src
85+
mcpp build --target aarch64-linux-musl
86+
x=$(find target/aarch64-linux-musl -type f -name xlings | head -1)
87+
file "$x" | grep -q "ARM aarch64" || { echo "expected aarch64 xlings"; exit 1; }
88+
"$x" --version

src/build/prepare.cppm

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,29 @@ prepare_build(bool print_fingerprint,
607607
// breaks GUI/native packages out of the box. musl-static stays
608608
// opt-in via `mcpp build --target x86_64-linux-musl` for users
609609
// who explicitly want portable static binaries.
610-
std::string defaultSpec = (mcpp::platform::is_macos || mcpp::platform::is_windows)
611-
? "llvm@20.1.7" : "gcc@16.1.0";
610+
// Linux default is arch-aware:
611+
// x86_64 → glibc gcc (native ABI; the glibc toolchain is published
612+
// for x86_64). musl-static stays opt-in via --target.
613+
// other arches (aarch64, ...) → musl-static gcc: it's what's
614+
// published for them, is self-contained, and yields portable
615+
// static binaries (ideal for aarch64 / Termux, no bionic dep).
616+
// glibc-world linking (X11/GL) needs an explicit glibc
617+
// toolchain, addable later for native-ABI aarch64 builds.
618+
std::string defaultSpec;
619+
if constexpr (mcpp::platform::is_macos || mcpp::platform::is_windows) {
620+
defaultSpec = "llvm@20.1.7";
621+
} else if (mcpp::platform::host_arch == std::string_view("x86_64")) {
622+
defaultSpec = "gcc@16.1.0";
623+
} else {
624+
defaultSpec = "gcc@15.1.0-musl";
625+
}
626+
bool muslDefault = defaultSpec.find("-musl") != std::string::npos;
612627
auto defaultParsed = mcpp::toolchain::parse_toolchain_spec(defaultSpec);
628+
// Host-native musl default has no --target, so seed the triple so the
629+
// resolver finds the `<host_arch>-linux-musl-g++` frontend.
630+
if (muslDefault)
631+
defaultParsed->targetTriple =
632+
std::string(mcpp::platform::host_arch) + "-linux-musl";
613633
auto defaultPkg = mcpp::toolchain::to_xim_package(*defaultParsed);
614634

615635
if constexpr (mcpp::platform::is_macos || mcpp::platform::is_windows) {
@@ -618,8 +638,8 @@ prepare_build(bool print_fingerprint,
618638
defaultSpec));
619639
} else {
620640
mcpp::ui::info("First run",
621-
std::format("no toolchain configured — installing {} (glibc, native ABI) as default",
622-
defaultSpec));
641+
std::format("no toolchain configured — installing {} ({}) as default",
642+
defaultSpec, muslDefault ? "musl, static" : "glibc, native ABI"));
623643
}
624644

625645
auto cfg = get_cfg();
@@ -628,9 +648,8 @@ prepare_build(bool print_fingerprint,
628648

629649
mcpp::fetcher::InstallProgressHandler progress;
630650
// The glibc default toolchain needs the sysroot payloads (C library +
631-
// kernel headers), exactly like `mcpp toolchain install` provides.
632-
// The old musl-static default was self-contained, which masked this.
633-
if constexpr (!mcpp::platform::is_macos && !mcpp::platform::is_windows) {
651+
// kernel headers). The musl default is self-contained, so skip them.
652+
if (!mcpp::platform::is_macos && !mcpp::platform::is_windows && !muslDefault) {
634653
for (auto dep : {"xim:glibc", "xim:linux-headers"}) {
635654
(void)fetcher.resolve_xpkg_path(dep, /*autoInstall=*/true, &progress);
636655
}

0 commit comments

Comments
 (0)