#3441·napi-rs

Allow macOS users to select a direct linker and pass custom linker arguments

Author: BoshenCreated Aug 5, 2026Updated Aug 5, 2026

Problem

napi-build currently emits these macOS linker arguments:

rust
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:

bash
RUSTFLAGS="\
-C linker=rust-lld \
-C linker-flavor=ld64.lld \
-C link-arg=--icf=safe" \
  napi build --release

the 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:

rust
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