Skip to content

perf: remap build-machine paths out of release binaries#10177

Closed
Boshen wants to merge 1 commit into
mainfrom
perf/shrink-release-binary
Closed

perf: remap build-machine paths out of release binaries#10177
Boshen wants to merge 1 commit into
mainfrom
perf/shrink-release-binary

Conversation

@Boshen

@Boshen Boshen commented Jul 7, 2026

Copy link
Copy Markdown
Member

Remap the absolute build-machine paths that rustc embeds into shipped release binaries. Two benefits: the build machine's filesystem layout is kept out of published artifacts (12 of 14 targets), and every target's .node shrinks (−52 to −165 KiB, mean −110 KiB).

Scope: this PR is now path-remap only. The separate "build std without the backtrace symbolizer" change (a larger, independent size win) has been split out to land on its own — it is not part of this diff.

Size impact

Measured as a matched same-day pair: baseline branch baseline-size-4b018b35 pinned at this PR's exact parent 4b018b35c, rebuilt today alongside the PR build by the same workflow. Drift is verified zero — the same-day baseline is byte-identical to the original 2026-07-07 baseline on all 14 targets, so every delta below is attributable to exactly this diff. Sizes are the stripped release .node per target.

platform baseline (KiB) this PR (KiB) Δ build-machine paths
linux-x64-gnu 18,657.6 18,509.6 −148.0 (−0.79%) removed
darwin-x64 16,725.4 16,573.7 −151.8 (−0.91%) removed
linux-arm64-gnu 16,821.2 16,725.2 −96.0 (−0.57%) removed
darwin-arm64 15,928.9 15,864.4 −64.5 (−0.40%) removed
win32-x64-msvc 20,007.5 19,842.5 −165.0 (−0.82%) removed
linux-x64-musl 18,705.5 18,594.5 −111.0 (−0.59%) kept (≈500)
All 14 targets — 1,539 KiB saved total, 110 KiB/target mean
platform baseline (KiB) this PR (KiB) Δ build-machine paths
win32-x64-msvc 20,007.5 19,842.5 −165.0 (−0.82%) removed
darwin-x64 16,725.4 16,573.7 −151.8 (−0.91%) removed
linux-x64-gnu 18,657.6 18,509.6 −148.0 (−0.79%) removed
freebsd-x64 18,654.4 18,510.3 −144.1 (−0.77%) removed
linux-ppc64-gnu 21,213.7 21,085.7 −128.0 (−0.60%) removed
linux-s390x-gnu 19,477.1 19,353.1 −124.0 (−0.64%) removed
win32-arm64-msvc 17,310.5 17,188.5 −122.0 (−0.70%) removed
linux-x64-musl 18,705.5 18,594.5 −111.0 (−0.59%) kept (≈500)
linux-arm64-gnu 16,821.2 16,725.2 −96.0 (−0.57%) removed
openharmony-arm64 16,826.2 16,737.5 −88.7 (−0.53%) removed
android-arm64 16,833.9 16,745.9 −88.1 (−0.52%) removed
darwin-arm64 15,928.9 15,864.4 −64.5 (−0.40%) removed
linux-arm64-musl 16,865.1 16,808.8 −56.2 (−0.33%) kept (≈500)
linux-arm-gnueabihf 15,173.8 15,121.8 −52.0 (−0.34%) removed

Only ~20–47% of each delta is the shorter path strings themselves (e.g. linux-x64-gnu: −69 KiB of strings within the −148 KiB total); the rest is the section-layout shift that adding --remap-path-prefix induces in rustc's symbol/metadata handling. That layout effect is also why the two musl targets still shrink even though their paths stay unremapped (see gaps).

What changed

  • packages/rolldown/build-binding.ts — on release builds, builds the --remap-path-prefix set (cargo home → /cargo, rustup home → /rustup, workspace root → /rolldown, each registry/src/<hash> dir → /deps) and injects it via a cargo --config target.'cfg(all())'.rustflags=[…] option.
  • No workflow or toolchain changes. The remap needs no rust-src, no -Z build-std, no env flags; .github/workflows/reusable-release-build.yml is untouched.

How it works

rustc embeds absolute paths (/…/.cargo/registry/src/…, rustup toolchain sources, the workspace root) into panic Locations and tracing callsite metadata. Release builds remap them, so panic messages read /deps/oxc_transformer-0.139.0/src/… and the build machine's filesystem layout stays out of shipped artifacts. Release-only, so local dev backtraces keep clickable absolute paths.

Deterministic: the per-registry registry/src/<hash> dirs only exist after a fetch, so the script runs cargo fetch --locked --target first, then enumerates them sorted — the flag set is a function of the lockfile, not of ambient cargo-home state on the runner.

Why --config instead of RUSTFLAGS/CARGO_BUILD_RUSTFLAGS: the napi CLI promotes CARGO_BUILD_RUSTFLAGS to RUSTFLAGS, which suppresses all target-level rustflags from .cargo/config.toml — an earlier revision of this PR silently dropped crt-static from the windows binary that way (its .node gained VCRUNTIME140 imports). Config-level target rustflags are joined with the config.toml entries instead, so windows keeps crt-static and still gets remapped.

Verification (from the PR artifacts)

  • Build-machine paths removed on 12/14 targets — 0 /home/runner, /Users/runner, runneradmin, or D:\a strings (e.g. linux-x64-gnu 605 → 0, win32-x64-msvc 878 → 0).
  • windows crt-static intact — 0 VCRUNTIME140 imports; the .node stays statically linked to the CRT.
  • No linking change — every ELF target stays dynamically linked / stripped, exactly as baseline.
  • Zero drift — original 07-07 baseline ≡ same-day baseline, byte-for-byte, all 14 targets.

Known gaps / follow-ups

  • musl keeps its registry paths (linux-x64-musl, linux-arm64-musl): napi-cli unconditionally sets RUSTFLAGS for musl (-C target-feature=-crt-static), suppressing the config-level rustflags, so ~500 /home/runner/.cargo/registry/… strings remain — no privacy benefit on musl (the size still drops via the layout effect). Root cause is the CLI's CARGO_BUILD_RUSTFLAGSRUSTFLAGS promotion; the durable fix is upstream in napi-rs.
  • Migrate the remap block to cargo -Ztrim-paths when it stabilizes (Tracking Issue for trim-paths RFC 3127 rust-lang/cargo#12137).
  • The build-std / backtrace-symbolizer removal (a separate, larger size win) lands on its own PR.

🤖 Generated with Claude Code

@netlify

netlify Bot commented Jul 7, 2026

Copy link
Copy Markdown

Deploy Preview for rolldown-rs ready!

Name Link
🔨 Latest commit 6ee291e
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/6a53b9c6790a8f0008527dc2
😎 Deploy Preview https://deploy-preview-10177--rolldown-rs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@Boshen
Boshen marked this pull request as draft July 7, 2026 10:16
@Boshen
Boshen force-pushed the perf/shrink-release-binary branch from 3e8182b to bdd5a93 Compare July 7, 2026 10:17
@Boshen Boshen changed the title perf: shrink release binaries (−240 KiB: helper dedup, path remap, build-std without backtrace) perf: shrink release binaries (path remap + build-std without backtrace) Jul 7, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3e8182b3c5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/rolldown/build-binding.ts Outdated
@Boshen
Boshen force-pushed the perf/shrink-release-binary branch from c8d23bd to 7ca1dff Compare July 7, 2026 10:26
@pkg-pr-new

pkg-pr-new Bot commented Jul 7, 2026

Copy link
Copy Markdown

Open in StackBlitz

@rolldown/browser

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/browser@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/browser@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/debug

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/debug@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/debug@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

rolldown

pnpm add https://pkg.pr.new/rolldown/rolldown@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown@10177 -D
yarn add https://pkg.pr.new/rolldown/[email protected] -D

@rolldown/binding-android-arm64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-android-arm64@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-android-arm64@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-darwin-arm64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-arm64@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-arm64@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-darwin-x64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-x64@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-darwin-x64@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-freebsd-x64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-freebsd-x64@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-freebsd-x64@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-linux-arm-gnueabihf

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm-gnueabihf@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm-gnueabihf@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-linux-arm64-gnu

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-gnu@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-gnu@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-linux-arm64-musl

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-musl@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-arm64-musl@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-linux-ppc64-gnu

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-ppc64-gnu@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-ppc64-gnu@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-linux-s390x-gnu

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-s390x-gnu@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-s390x-gnu@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-linux-x64-gnu

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-gnu@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-gnu@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-linux-x64-musl

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-musl@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-linux-x64-musl@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-openharmony-arm64

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-openharmony-arm64@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-openharmony-arm64@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-wasm32-wasi

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-wasm32-wasi@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-wasm32-wasi@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-win32-arm64-msvc

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-arm64-msvc@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-arm64-msvc@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

@rolldown/binding-win32-x64-msvc

pnpm add https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-x64-msvc@10177 -D
npm i https://pkg.pr.new/rolldown/rolldown/@rolldown/binding-win32-x64-msvc@10177 -D
yarn add https://pkg.pr.new/rolldown/rolldown/@rolldown/[email protected] -D

commit: 6b21cdd

@Boshen

This comment has been minimized.

@Boshen
Boshen marked this pull request as ready for review July 7, 2026 13:51
@Boshen
Boshen requested a review from Brooooooklyn July 7, 2026 13:52
@hyfdev

This comment has been minimized.

@Boshen
Boshen force-pushed the perf/shrink-release-binary branch from 36a8585 to 6b21cdd Compare July 7, 2026 14:35
@Boshen

This comment has been minimized.

@Boshen

This comment has been minimized.

@hyfdev

hyfdev commented Jul 8, 2026

Copy link
Copy Markdown
Member

Follow-up review on ea9939515: the previous three findings are addressed. I independently reproduced the matched size deltas, verified that /deps mappings now fire on cold runners, and confirmed that Windows keeps crt-static while skipping build-std.

I found two remaining issues.

1. Fail the build when cargo fetch --locked fails

packages/rolldown/build-binding.ts calls spawnSync(...) but does not inspect its error, status, or signal:

spawnSync(
  'cargo',
  ['fetch', '--locked', ...(argsOptions.target ? ['--target', argsOptions.target] : [])],
  { cwd: workspaceRoot, stdio: 'inherit' },
);

The subsequent napi-cli metadata/build invocation does not use --locked. A failed locked prefetch can therefore be silently followed by an unlocked build that rewrites Cargo.lock and succeeds.

Reproduction

tmp=$(mktemp -d)
mkdir -p "$tmp/src"

cat > "$tmp/Cargo.toml" <<'EOF'
[package]
name = "locked-fetch-repro"
version = "0.1.0"
edition = "2024"

[dependencies]
anyhow = "=1.0.100"
EOF

echo 'fn main() {}' > "$tmp/src/main.rs"

cd "$tmp"
cargo +1.96.1 generate-lockfile
perl -0pi -e 's/1\.0\.100/1.0.103/' Cargo.toml

cargo +1.96.1 fetch --locked
echo $?
# 101: lockfile update rejected

cargo +1.96.1 build
echo $?
# 0: succeeds and updates Cargo.lock to anyhow 1.0.103

Normal CI catches stale lockfiles, so the common path is protected, but this release-only prefetch should still fail closed. Please use execFileSync, or explicitly throw/exit on a spawn error, signal, or nonzero status. Using process.env.CARGO ?? 'cargo' would also match the executable selected by napi-cli.

2. The diagnostic regression also affects JS errors backed by anyhow

The description now accurately accepts that the default panic hook prints no frames. However, non-NAPI errors from this.load and this.resolve are formatted into JS error messages with {err:?} in crates/rolldown_binding/src/utils/napi_error.rs.

anyhow::Error's Debug output contains its captured Rust backtrace. Dropping std's symbolizer changes these user-visible JS errors from partly named frames to entirely <unknown> frames.

Reproduction on the matched artifacts

The following runs on Apple Silicon:

git clone --filter=blob:none https://github.com/rolldown/rolldown.git
cd rolldown
git checkout ea9939515547e8b1a52017d28421635f4fd20bfa

artifacts=$(mktemp -d)

gh run download 28874572401 -R rolldown/rolldown \
  -n bindings-aarch64-apple-darwin -D "$artifacts/base"

gh run download 28874569118 -R rolldown/rolldown \
  -n bindings-aarch64-apple-darwin -D "$artifacts/pr"

for side in base pr; do
  echo "===== $side ====="
  RUST_BACKTRACE=1 SIDE="$side" CHECKOUT="$PWD" ARTIFACT_ROOT="$artifacts" node <<'NODE'
(async () => {
  const side = process.env.SIDE;
  process.env.NAPI_RS_NATIVE_LIBRARY_PATH =
    `${process.env.ARTIFACT_ROOT}/${side}/rolldown-binding.darwin-arm64.node`;

  const { BindingBundler } = require(
    `${process.env.CHECKOUT}/packages/rolldown/src/binding.cjs`
  );

  const bundler = new BindingBundler();
  const result = await bundler.generate({
    inputOptions: {
      input: [{ import: '/tmp/nonexistent-entry.js' }],
      plugins: [{
        name: 'backtrace-repro',
        hookUsage: 1,
        async buildStart(ctx) {
          await ctx.load('virtual:forced-error');
        },
      }],
      logLevel: 2,
      onLog() {},
      cwd: '/tmp',
    },
    outputOptions: { plugins: [], format: 'es' },
  });

  console.log(result.errors[0].field0.message);
})().catch(error => {
  console.error(error);
  process.exit(1);
});
NODE
done

Observed output:

  • Baseline: 11 frames, with 8 named frames including _napi_register_module_v1 and __pthread_cond_wait.
  • PR: 10 frames, all <unknown>.

This may still be an acceptable size/diagnostics trade-off, but it is broader than the currently documented panic behavior. Please explicitly document and accept that RUST_BACKTRACE=1 also loses symbolization in some JS error messages, or retain symbolization for that path.

Boshen added a commit to oxc-project/oxc-resolver that referenced this pull request Jul 12, 2026
…acktrace) (#1283)

Shrink the shipped `.node` binaries, ported from
rolldown/rolldown#10177. Measured on a matched pair of release runs
([baseline](https://github.com/oxc-project/oxc-resolver/actions/runs/28878899374)
vs [this
branch](https://github.com/oxc-project/oxc-resolver/actions/runs/28878896916)):
**−8 to −12%** on build-std targets (darwin-arm64 1,738.8 → 1,543.7 KiB,
linux-x64-gnu 2,303.2 → 2,104.7 KiB), −0.2 to −0.3% on the remap-only
targets (windows, wasm, freebsd).

`napi/build.mjs` wraps `napi build` (same clipanion arg parsing, `--`
passthrough) and, **only on CI release builds with an explicit
`--target`**, injects:

1. **Path remap** — `--remap-path-prefix` for cargo home → `/cargo`,
rustup home → `/rustup`, workspace → `/oxc-resolver`, registry dirs →
`/deps`, std sources → `/std`, injected as a cargo `--config` rustflags
entry so the `.cargo/config.toml` target rustflags (gnu `nodelete`, wasi
stack size) still apply. Panic locations read
`/deps/sharded-slab-0.1.7/…` / `/std/alloc/…` instead of build-machine
paths. Migrate to `-Ztrim-paths` once it stabilizes
(rust-lang/cargo#12137).
2. **build-std without std's `backtrace` feature** — drops the ~200 KiB
DWARF symbolizer (gimli/object/addr2line), dead weight under `panic =
"abort"` + `strip = "symbols"`. `RUSTC_BOOTSTRAP=1` +
`-Zbuild-std=std,panic_abort` CLI flags on the pinned stable toolchain
(CLI flags hard-error if the unlock ever breaks; env config would be
silently ignored). Excluded: wasm, windows-msvc, FreeBSD
(`OXC_RESOLVER_BUILD_STD=0`).

Local builds — debug or release — are untouched: real clickable paths,
prebuilt std, no `cargo fetch`. `CI=1 pnpm build --target <t>`
reproduces a shipped binary byte-for-byte. A CI release build missing
`rust-src` fails the job instead of silently shipping the prebuilt std.

Accepted behavior change: `RUST_BACKTRACE=1` on shipped binaries prints
no stack frames — panic message + source location survive. Today's
stripped binaries already can't symbolize (`=1` prints zero frames,
`=full` mislabels every frame).

Known gap: musl artifacts keep unremapped paths — napi-cli force-sets
`RUSTFLAGS` for musl, which suppresses config-level rustflags; the fix
belongs upstream. build-std still applies there.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
rustc embeds absolute cargo/rustup/workspace paths into panic locations
and tracing callsite metadata. Release binding builds now pass
--remap-path-prefix mappings (cargo home, rustup home, workspace root,
and each registry src hash dir) so the build machine's filesystem layout
stays out of shipped artifacts and the string tables shrink.

The flags are injected via a cargo `--config target.'cfg(all())'.rustflags`
entry rather than CARGO_BUILD_RUSTFLAGS: the napi CLI promotes the latter
to RUSTFLAGS, which would suppress the target rustflags from
.cargo/config.toml (windows crt-static / ucrt link-args). Registry dirs
are enumerated after `cargo fetch --locked` and sorted so the flag set is
deterministic on cold CI runners.

Known gap: napi-cli always sets RUSTFLAGS for musl targets, which
suppresses config-level rustflags, so musl artifacts keep unremapped
paths.
@Boshen
Boshen force-pushed the perf/shrink-release-binary branch from ea99395 to 6ee291e Compare July 12, 2026 15:59
@Boshen Boshen changed the title perf: shrink release binaries (path remap + build-std without backtrace) perf: remap build-machine paths out of release binaries Jul 12, 2026
@Boshen Boshen closed this Jul 12, 2026
@Boshen
Boshen deleted the perf/shrink-release-binary branch July 12, 2026 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants