Skip to content

fix(docker): separate host/target CC wrappers; drop Swatinem/rust-cache - #11

Merged
muralidhar-challa merged 2 commits into
mainfrom
fix/musl-cc-host-target-triple-mixup
Jul 9, 2026
Merged

fix(docker): separate host/target CC wrappers; drop Swatinem/rust-cache#11
muralidhar-challa merged 2 commits into
mainfrom
fix/musl-cc-host-target-triple-mixup

Conversation

@muralidhar-challa

Copy link
Copy Markdown
Collaborator

Summary

  • The actual arm64 build failure (not the cache-id issue fixed in fix(ci): fix alpine ABI cache mismatch and orphaned docs commits #10): CC_x86_64_unknown_linux_musl and CC_aarch64_unknown_linux_musl both pointed at the same musl-cc wrapper script, which read one global /zig_target.txt written once from $TARGETARCH. Build scripts and proc-macro crates (e.g. sqlx-macros) always compile for the host triple (x86_64, since the chef stage is pinned to --platform=$BUILDPLATFORM) regardless of the cross --target for the final binary. On the arm64 build, that shared file said aarch64-linux-musl, so host-triple C compiles (e.g. libsqlite3-sys's build script, needed by sqlx-macros) got wrongly compiled for aarch64 too, then failed to link into the host-native x86_64 proc-macro artifact (file in wrong format, EM_AARCH64 relocations). Worked "by accident" on amd64 only because host == target there.
    • Fix: generate one wrapper per triple (musl-cc-x86_64, musl-cc-aarch64, and the g++ equivalents) with the zig target hardcoded at generation time instead of read from a shared file.
    • Verified locally: built just the chef stage on this branch and confirmed each generated wrapper embeds the correct -target.
    • Also switched the wrapper-generation RUN to BuildKit's heredoc syntax (# syntax=docker/dockerfile:1) — the old backslash-continued form combined with an embedded cat <<WRAP heredoc caused the Dockerfile parser to lose track of where the RUN instruction ended (it read chmod on the next line as a bogus top-level instruction).
  • Supply-chain: dropped Swatinem/rust-cache@v2 (community-maintained third-party action) from clippy/test, replaced with GitHub's own actions/cache@v4 manually configured for the same cache paths (~/.cargo/registry, ~/.cargo/git, target/) keyed on Cargo.lock.

Test plan

  • Local build of the chef stage confirms both wrapper scripts have the correct hardcoded -target
  • CI run on this PR (fmt/clippy/test) passes
  • Once merged, push-to-main build actually completes for both amd64 and arm64

The push-to-main build failed again after the cache-id fix, this time
with: ld: .../liblibsqlite3_sys-*.rlib: file in wrong format
(Relocations in generic ELF (EM: 183) -- EM_AARCH64 -- while linking
a host-native x86_64 proc-macro artifact).

Root cause: CC_x86_64_unknown_linux_musl and CC_aarch64_unknown_linux_musl
both pointed at the same musl-cc script, which read one global
/zig_target.txt written once from $TARGETARCH. Build scripts and
proc-macro crates (e.g. sqlx-macros) always compile for the HOST triple
(x86_64, since this stage is pinned to --platform=$BUILDPLATFORM)
regardless of the cross --target for the final binary. On the arm64
build, that shared file said aarch64-linux-musl, so host-triple C
compiles (like libsqlite3-sys's build script, needed by sqlx-macros)
got wrongly compiled for aarch64 too, then failed to link into the
host-native x86_64 proc-macro artifact. Worked "by accident" on the
amd64 build only because host == target there.

Generates one wrapper per triple (musl-cc-x86_64, musl-cc-aarch64, and
the g++ equivalents) with the zig target hardcoded at generation time,
so CC selection is no longer ambiguous. Verified locally: built just
the chef stage and confirmed each wrapper embeds the correct -target.

Also rewrites the wrapper-generation RUN using BuildKit's heredoc
syntax (# syntax=docker/dockerfile:1) instead of backslash-continued
shell mixed with an embedded cat<<WRAP heredoc -- the old form's lack
of a trailing backslash on the heredoc's last line caused the
Dockerfile's line-continuation parser to lose track of where the RUN
instruction ended.
Reduces reliance on community-maintained third-party actions in the
supply chain. actions/cache is GitHub's own official action; manually
configuring the cache paths (~/.cargo/registry, ~/.cargo/git, target/)
keyed on Cargo.lock gives equivalent caching behavior to what
Swatinem/rust-cache was doing under the hood.
@vishwateja-angirekula
vishwateja-angirekula self-requested a review July 9, 2026 07:38
@muralidhar-challa
muralidhar-challa merged commit fcda093 into main Jul 9, 2026
3 checks passed
@vishwateja-angirekula
vishwateja-angirekula deleted the fix/musl-cc-host-target-triple-mixup branch July 9, 2026 07:39
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