Skip to content

Commit f6c136b

Browse files
committed
fix(ci): replace zig with g++ FORTIFY_SOURCE wrapper for musl builds
Zig's C++ compiler uses libc++ while the system linker expects libstdc++, causing unresolved std::__1::* symbols from z3. Replace zig with a simple g++ wrapper that disables _FORTIFY_SOURCE — the only glibc-specific flag that produces symbols absent from musl (__printf_chk, __memcpy_chk, etc.). System gcc handles linking correctly since Rust provides its own musl CRT objects and libc.
1 parent 88b2ba7 commit f6c136b

File tree

3 files changed

+24
-63
lines changed

3 files changed

+24
-63
lines changed

.github/workflows/release-dev.yml

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,9 @@ jobs:
150150
# ---------------------------------------------------------------------------
151151
# Build CLI binaries (Linux musl — static, native on each arch)
152152
#
153-
# Builds run directly on the CI host (glibc Ubuntu). Zig provides a
154-
# musl-targeting C/C++ compiler so that bundled-z3 produces musl-compatible
155-
# objects without glibc contamination. This avoids Docker-in-Docker and
156-
# lets sccache work normally.
153+
# Builds run directly on the CI host (glibc Ubuntu). The system g++ is
154+
# used for C++ compilation (z3) with _FORTIFY_SOURCE disabled to avoid
155+
# glibc-specific hardened symbols that do not exist in musl.
157156
# ---------------------------------------------------------------------------
158157
build-cli-linux:
159158
name: Build CLI (Linux ${{ matrix.arch }})
@@ -164,11 +163,9 @@ jobs:
164163
- arch: amd64
165164
runner: build-amd64
166165
target: x86_64-unknown-linux-musl
167-
zig_target: x86_64-linux-musl
168166
- arch: arm64
169167
runner: build-arm64
170168
target: aarch64-unknown-linux-musl
171-
zig_target: aarch64-linux-musl
172169
runs-on: ${{ matrix.runner }}
173170
timeout-minutes: 60
174171
container:
@@ -205,35 +202,19 @@ jobs:
205202
- name: Add Rust musl target
206203
run: mise x -- rustup target add ${{ matrix.target }}
207204

208-
- name: Set up zig-musl toolchain
205+
- name: Set up musl C++ wrapper
209206
run: |
210207
set -euo pipefail
211-
ZIG="$(mise which zig)"
212-
ZIG_TARGET="${{ matrix.zig_target }}"
213-
mkdir -p /tmp/zig-musl
214-
215-
# cc-rs injects --target=<rust-triple> (e.g. aarch64-unknown-linux-musl)
216-
# which zig cannot parse. The wrappers strip any --target flags and use
217-
# the correct zig target instead.
218-
for tool in cc c++; do
219-
cat > "/tmp/zig-musl/${tool}" <<WRAPPER
220-
#!/bin/bash
221-
args=()
222-
for arg in "\$@"; do
223-
case "\$arg" in --target=*) ;; *) args+=("\$arg") ;; esac
224-
done
225-
exec "$ZIG" $tool --target=$ZIG_TARGET "\${args[@]}"
226-
WRAPPER
227-
chmod +x "/tmp/zig-musl/${tool}"
228-
done
208+
# System g++ with _FORTIFY_SOURCE disabled. FORTIFY_SOURCE makes
209+
# g++ emit glibc-specific hardened calls (__printf_chk, __memcpy_chk)
210+
# that do not exist in musl, causing linker failures. Disabling it
211+
# produces standard POSIX calls that resolve against musl.
212+
printf '#!/bin/sh\nexec g++ -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 "$@"\n' \
213+
> /usr/local/bin/musl-g++
214+
chmod +x /usr/local/bin/musl-g++
229215
230-
# Tell cargo / cc-rs / cmake to use zig for C/C++ compilation.
231-
# Do NOT set the linker — Rust's default linker (system cc/gcc)
232-
# works correctly because Rust ships its own musl CRT objects.
233-
# Using zig as the linker causes duplicate _start symbols.
234216
TARGET_ENV=$(echo "${{ matrix.target }}" | tr '-' '_')
235-
echo "CC_${TARGET_ENV}=/tmp/zig-musl/cc" >> "$GITHUB_ENV"
236-
echo "CXX_${TARGET_ENV}=/tmp/zig-musl/c++" >> "$GITHUB_ENV"
217+
echo "CXX_${TARGET_ENV}=/usr/local/bin/musl-g++" >> "$GITHUB_ENV"
237218
238219
- name: Scope workspace to CLI crates
239220
run: |

.github/workflows/release-tag.yml

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,9 @@ jobs:
171171
# ---------------------------------------------------------------------------
172172
# Build CLI binaries (Linux musl — static, native on each arch)
173173
#
174-
# Builds run directly on the CI host (glibc Ubuntu). Zig provides a
175-
# musl-targeting C/C++ compiler so that bundled-z3 produces musl-compatible
176-
# objects without glibc contamination. This avoids Docker-in-Docker and
177-
# lets sccache work normally.
174+
# Builds run directly on the CI host (glibc Ubuntu). The system g++ is
175+
# used for C++ compilation (z3) with _FORTIFY_SOURCE disabled to avoid
176+
# glibc-specific hardened symbols that do not exist in musl.
178177
# ---------------------------------------------------------------------------
179178
build-cli-linux:
180179
name: Build CLI (Linux ${{ matrix.arch }})
@@ -185,11 +184,9 @@ jobs:
185184
- arch: amd64
186185
runner: build-amd64
187186
target: x86_64-unknown-linux-musl
188-
zig_target: x86_64-linux-musl
189187
- arch: arm64
190188
runner: build-arm64
191189
target: aarch64-unknown-linux-musl
192-
zig_target: aarch64-linux-musl
193190
runs-on: ${{ matrix.runner }}
194191
timeout-minutes: 60
195192
container:
@@ -227,35 +224,19 @@ jobs:
227224
- name: Add Rust musl target
228225
run: mise x -- rustup target add ${{ matrix.target }}
229226

230-
- name: Set up zig-musl toolchain
227+
- name: Set up musl C++ wrapper
231228
run: |
232229
set -euo pipefail
233-
ZIG="$(mise which zig)"
234-
ZIG_TARGET="${{ matrix.zig_target }}"
235-
mkdir -p /tmp/zig-musl
236-
237-
# cc-rs injects --target=<rust-triple> (e.g. aarch64-unknown-linux-musl)
238-
# which zig cannot parse. The wrappers strip any --target flags and use
239-
# the correct zig target instead.
240-
for tool in cc c++; do
241-
cat > "/tmp/zig-musl/${tool}" <<WRAPPER
242-
#!/bin/bash
243-
args=()
244-
for arg in "\$@"; do
245-
case "\$arg" in --target=*) ;; *) args+=("\$arg") ;; esac
246-
done
247-
exec "$ZIG" $tool --target=$ZIG_TARGET "\${args[@]}"
248-
WRAPPER
249-
chmod +x "/tmp/zig-musl/${tool}"
250-
done
230+
# System g++ with _FORTIFY_SOURCE disabled. FORTIFY_SOURCE makes
231+
# g++ emit glibc-specific hardened calls (__printf_chk, __memcpy_chk)
232+
# that do not exist in musl, causing linker failures. Disabling it
233+
# produces standard POSIX calls that resolve against musl.
234+
printf '#!/bin/sh\nexec g++ -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 "$@"\n' \
235+
> /usr/local/bin/musl-g++
236+
chmod +x /usr/local/bin/musl-g++
251237
252-
# Tell cargo / cc-rs / cmake to use zig for C/C++ compilation.
253-
# Do NOT set the linker — Rust's default linker (system cc/gcc)
254-
# works correctly because Rust ships its own musl CRT objects.
255-
# Using zig as the linker causes duplicate _start symbols.
256238
TARGET_ENV=$(echo "${{ matrix.target }}" | tr '-' '_')
257-
echo "CC_${TARGET_ENV}=/tmp/zig-musl/cc" >> "$GITHUB_ENV"
258-
echo "CXX_${TARGET_ENV}=/tmp/zig-musl/c++" >> "$GITHUB_ENV"
239+
echo "CXX_${TARGET_ENV}=/usr/local/bin/musl-g++" >> "$GITHUB_ENV"
259240
260241
- name: Scope workspace to CLI crates
261242
run: |

mise.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ helm = "4.1.1"
2323
"ubi:mozilla/sccache" = { version = "0.14.0", matching = "sccache-v" }
2424
"ubi:anchore/syft" = { version = "1.42.3", matching = "syft_" }
2525
"ubi:EmbarkStudios/cargo-about" = "0.8.4"
26-
zig = "0.14.1"
2726

2827
[env]
2928
_.path = ["{{config_root}}/scripts/bin"]

0 commit comments

Comments
 (0)