Summary
nightly.yml's build-linux job sets both of these:
CC_x86_64_unknown_linux_musl: musl-gcc
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc # <- this one
The second is unnecessary, and on a builder image whose musl-gcc specs point at musl's dynamic loader it silently produces a dynamically-linked binary — the exact condition #616 was closed to prevent. It happens to be harmless on blacksmith-8vcpu-ubuntu-2404 today, so this is a latent dependency on the runner image rather than a live breakage. But it means the nightly's static-linkage guarantee rests on a property of the image that nothing pins or asserts.
Evidence
Measured while building wfl from source on rust:1-bookworm (musl-tools 1.2.3, rustc 1.97.1), same env vars as nightly.yml, three configurations:
| Configuration |
Result |
| musl target, rustc's default linker |
static-pie ✅ |
+ CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc |
dynamic ❌ |
+ that, plus an explicit -C target-feature=+crt-static`` |
still dynamic ❌ |
The produced binary requested /lib/ld-musl-x86_64.so.1. crt-static cannot win the argument back once musl-gcc drives the link: musl-gcc is a spec-file wrapper around the host gcc, and its specs select the dynamic loader. Rust's x86_64-unknown-linux-musl target ships its own self-contained musl libc and static-links by default, so the fix is simply not to take the link away from it.
Why it's worth caring about
This fails quietly at every layer a person would normally check:
- the build goes green
ldd reports statically linked (it is reporting on the wrong thing)
file says dynamically linked, interpreter /lib/ld-musl-x86_64.so.1 — which is easy to skim past when you were expecting a musl binary and just saw the word "musl"
The PT_INTERP assertion added in this job is what catches it, and it caught it immediately in my case — that check is doing real work and is worth keeping exactly as it is. But if the builder image ever shifts, the symptom will be a red nightly with a confusing message rather than a clean build, and whoever debugs it will start from "why is our musl build not static" instead of "which of these two env vars is fighting the other".
Suggested fix
Drop the linker line; keep CC_, which is genuinely needed so cc-rs compiles aws-lc-sys for the musl target:
env:
TARGET: x86_64-unknown-linux-musl
CC_x86_64_unknown_linux_musl: musl-gcc
- CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc
CARGO_PROFILE_RELEASE_DEBUG: false
Optionally make the intent explicit rather than implicit in the target default:
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS: "-C target-feature=+crt-static"
That variable is unioned with the cfg(target_os = "linux") rustflags in .cargo/config.toml, so the 8 MB stack-size link-arg the parser depends on is still applied — I verified GNU_STACK remains 0x800000 with it set.
What I verified, and what I didn't
Verified: with the linker line removed and CC_ kept, a full cargo build --release --locked --target x86_64-unknown-linux-musl of both wfl and wfl-lsp at 150c8a7 (26.7.64) succeeds — aws-lc-sys and the whole graph build fine — and both binaries come out with no PT_INTERP segment. The resulting wfl (22 MB stripped) runs on Ubuntu 22.04 / glibc 2.35 and executes TestPrograms/basic_syntax_comprehensive.wfl, so the #616 property genuinely holds.
Not verified: I did this on rust:1-bookworm, not on blacksmith-8vcpu-ubuntu-2404. I have no reason to expect a difference — removing the override moves the build toward rustc's default behaviour rather than away from it — but I haven't run it on your actual runner.
Happy to send a PR if the change looks right to you.
Filed by the WFL repo warden (automated maintenance pass). Found while building the runtime from source for a downstream project that needs WFL fixes before the nightly carrying them publishes.
Summary
nightly.yml'sbuild-linuxjob sets both of these:The second is unnecessary, and on a builder image whose
musl-gccspecs point at musl's dynamic loader it silently produces a dynamically-linked binary — the exact condition #616 was closed to prevent. It happens to be harmless onblacksmith-8vcpu-ubuntu-2404today, so this is a latent dependency on the runner image rather than a live breakage. But it means the nightly's static-linkage guarantee rests on a property of the image that nothing pins or asserts.Evidence
Measured while building
wflfrom source onrust:1-bookworm(musl-tools 1.2.3, rustc 1.97.1), same env vars asnightly.yml, three configurations:+ CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=musl-gcc+ that, plus an explicit-C target-feature=+crt-static``The produced binary requested
/lib/ld-musl-x86_64.so.1.crt-staticcannot win the argument back oncemusl-gccdrives the link:musl-gccis a spec-file wrapper around the hostgcc, and its specs select the dynamic loader. Rust'sx86_64-unknown-linux-musltarget ships its own self-contained musl libc and static-links by default, so the fix is simply not to take the link away from it.Why it's worth caring about
This fails quietly at every layer a person would normally check:
lddreportsstatically linked(it is reporting on the wrong thing)filesaysdynamically linked, interpreter /lib/ld-musl-x86_64.so.1— which is easy to skim past when you were expecting a musl binary and just saw the word "musl"The
PT_INTERPassertion added in this job is what catches it, and it caught it immediately in my case — that check is doing real work and is worth keeping exactly as it is. But if the builder image ever shifts, the symptom will be a red nightly with a confusing message rather than a clean build, and whoever debugs it will start from "why is our musl build not static" instead of "which of these two env vars is fighting the other".Suggested fix
Drop the linker line; keep
CC_, which is genuinely needed socc-rscompilesaws-lc-sysfor the musl target:env: TARGET: x86_64-unknown-linux-musl CC_x86_64_unknown_linux_musl: musl-gcc - CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc CARGO_PROFILE_RELEASE_DEBUG: falseOptionally make the intent explicit rather than implicit in the target default:
That variable is unioned with the
cfg(target_os = "linux")rustflagsin.cargo/config.toml, so the 8 MB stack-sizelink-argthe parser depends on is still applied — I verifiedGNU_STACKremains0x800000with it set.What I verified, and what I didn't
Verified: with the linker line removed and
CC_kept, a fullcargo build --release --locked --target x86_64-unknown-linux-muslof bothwflandwfl-lspat150c8a7(26.7.64) succeeds —aws-lc-sysand the whole graph build fine — and both binaries come out with noPT_INTERPsegment. The resultingwfl(22 MB stripped) runs on Ubuntu 22.04 / glibc 2.35 and executesTestPrograms/basic_syntax_comprehensive.wfl, so the #616 property genuinely holds.Not verified: I did this on
rust:1-bookworm, not onblacksmith-8vcpu-ubuntu-2404. I have no reason to expect a difference — removing the override moves the build toward rustc's default behaviour rather than away from it — but I haven't run it on your actual runner.Happy to send a PR if the change looks right to you.
Filed by the WFL repo warden (automated maintenance pass). Found while building the runtime from source for a downstream project that needs WFL fixes before the nightly carrying them publishes.