Skip to content

fix: preserve linker list operands with Zig 0.16 - #480

Merged
messense merged 2 commits into
mainfrom
codex/fix-linker-list-operands
Sep 9, 2026
Merged

messense merged 2 commits into
mainfrom
codex/fix-linker-list-operands

Conversation

@messense

@messense messense commented Sep 8, 2026

Copy link
Copy Markdown
Member

Since 0.23.4, an existing filename passed as -Wl,<path> is rewritten as a positional input even when it is the operand of -exported_symbols_list. With Zig 0.16, an Apple cdylib link then fails with unable to read exported symbols list '-dead_strip': FileNotFound.

Preserve the following operand for the two list options already handled by the filter: -exported_symbols_list and --dynamic-list. Share filtering state between command-line arguments and response files, including pairs that cross a response-file boundary. A trailing response-file newline no longer consumes a pending operand. Older Zig versions still strip these list pairs, and the positional archive rewrite from #477 is preserved.

Replace the nonexistent filename in the existing Zig 0.16 unit test with a real file. Add executable-wrapper regression tests covering 106 argument scenarios: split and combined forms, old and new version gates, whole-archive inputs, subsequent argument filtering, UTF-16 response files, and pairs crossing response-file boundaries. Run the Rust test suite in the existing CI matrix. Correct the stale percent-escaping assertion exposed by running the suite on Windows, and run that pure string test on all hosts.

Validation on macOS with rustc 1.98.0:

  • cargo test --locked --all-targets --all-features: 57 tests passed.
  • cargo fmt --all -- --check and git diff --check: passed.
  • cargo clippy --locked --all-targets --all-features: completed with five pre-existing warnings; strict -D warnings remains blocked by those warnings.
  • A minimal Rust cdylib links, loads, and returns the expected value with Zig 0.16.0.
  • Real Apple C links through direct, response-file, and split-boundary arguments match direct Zig's exported symbols.
  • Real Linux ELF links with Zig 0.11.0 and 0.16.0 retain an otherwise unused archive symbol only when whole-archive is enabled, through both argument paths.

The executable-wrapper tests require Unix. They exercise Windows-target filtering and UTF-16 response files, but native Windows execution was not validated locally.

Fixes #479.

@messense
messense merged commit 110abf5 into main Sep 9, 2026
49 checks passed
@messense
messense deleted the codex/fix-linker-list-operands branch September 9, 2026 11:27
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.

-Wl,<path> rewrite detaches the operand from -exported_symbols_list, breaking cdylib links on Apple targets with zig >= 0.16

1 participant