Allow macOS users to select a direct linker and pass custom linker arguments
Problem
napi-build currently emits these macOS linker arguments:
println!("cargo:rustc-cdylib-link-arg=-Wl");
println!("cargo:rustc-cdylib-link-arg=-undefined");
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");The standalone -Wl assumes that rustc invokes a compiler driver such as Clang. When a consumer selects the bundled Mach-O LLD directly:
RUSTFLAGS="\
-C linker=rust-lld \
-C linker-flavor=ld64.lld \
-C link-arg=--icf=safe" \
napi build --releasethe build fails because ld64.lld does not recognize the compiler-driver argument -Wl.
This prevents consumers from changing linker behavior from userland. One use case is opting into safe identical code folding with --icf=safe to reduce release artifact size.
Requested behavior
Could napi-build emit its required dynamic-lookup defaults in a form compatible with both Apple Clang and direct Mach-O linkers?
The minimal change appears to be removing only -Wl while retaining:
println!("cargo:rustc-cdylib-link-arg=-undefined");
println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");Apple Clang accepts -undefined dynamic_lookup directly, and ld64.lld accepts the same native Mach-O arguments.
This request is not to enable --icf=safe by default. Consumers should remain responsible for selecting their linker and supplying optimization arguments through Cargo or RUSTFLAGS.
Motivation
Using Rust's bundled ld64.lld with safe ICF reduced Rolldown's macOS binding sizes:
| Target | Raw binding reduction | gzip reduction |
|---|---|---|
| arm64 | 216,752 bytes (1.31%) | 19,779 bytes (0.29%) |
| x64 | 496,904 bytes (2.86%) | 110,482 bytes (1.50%) |
That is 713,656 bytes (about 0.68 MiB) across the two raw bindings, with effectively unchanged build time.
The arm64 result isolates ICF against the same LLD linker without ICF. The x64 comparison also includes changing from Apple's default linker to LLD.
A similar configuration is used by astral-sh/uv: https://github.com/astral-sh/uv/pull/19615
Source: napi-rs/napi-rs