build: fix local WebKit configure on PIE-default distros - #30710
Conversation
…bes link on PIE-default distros; fix LinkOpts.linkerMapOutput exactOptionalPropertyTypes error
|
Updated 10:05 AM PT - May 14th, 2026
❌ @dylan-conway, your commit e65fa03 has 1 failures in
🧪 To try this PR locally: bunx bun-pr 30710That installs a local version of the PR into your bun-30710 --bun |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughThis PR updates the build system with two targeted fixes: clarifying the optional type of ChangesBuild System Configuration
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
| // -no-pie rides along in CMAKE_C_FLAGS so try_compile() probes link on | ||
| // PIE-default distros — without it the driver still passes -pie and the | ||
| // -fno-pic probe object fails R_X86_64_32S relocation, killing FindThreads. | ||
| if (cfg.unix && cfg.abi !== "android") optFlags.push("-fno-pic", "-fno-pie", "-no-pie"); |
There was a problem hiding this comment.
🔴 cfg.unix includes darwin (config.ts:596: unix = linux || darwin || freebsd), so this now passes -no-pie to the WebKit cmake on macOS. Everywhere else in the codebase the link-time -no-pie is deliberately gated to linux/freebsd only (flags.ts:943-944, flags.ts:1046-1047, source.ts:1210-1212) — on arm64 darwin, clang's Darwin driver forwards this to ld64 as -no_pie, which ld64 rejects with "-no_pie cannot be used with arm64", so every try_compile() probe fails — the exact regression this PR is fixing on Linux. Gate the -no-pie push on (cfg.linux || cfg.freebsd) (or !cfg.darwin) to match flags.ts; the R_X86_64_32S rationale is ELF-specific and doesn't apply to Mach-O anyway.
Extended reasoning...
What the bug is
The new -no-pie flag is pushed under cfg.unix && cfg.abi !== "android". Per config.ts:596, const unix = linux || darwin || freebsd, so this gate includes darwin. The flag therefore lands in CMAKE_C_FLAGS / CMAKE_CXX_FLAGS for local-WebKit builds on macOS, where it was never passed before.
This diverges from the codebase's established pattern: the link-time -no-pie is gated on c.linux && c.abi !== "android" at flags.ts:943-944 and on c.freebsd at flags.ts:1046-1047. Darwin only ever gets the compile-mode -fno-pic -fno-pie (flags.ts:533-534, source.ts:1210-1212, source.ts:1494-1495) — never the link-mode -no-pie. The pre-PR webkit.ts line matched that pattern exactly.
Why it manifests
On darwin, cfg.ld is empty (config.ts:184: "May be empty on darwin (clang invokes ld)"), and source.ts:1135 only sets CMAKE_EXE_LINKER_FLAGS=--ld-path=... when cfg.linux. So WebKit's nested-cmake try_compile() probes on macOS link via clang's Darwin driver → Apple ld64, not lld.
CMake's try_compile() includes CMAKE_C_FLAGS in the <FLAGS> slot for both the compile and the link of the probe executable. When clang's Darwin driver sees -no-pie on a link line, it translates it to ld64's spelling -no_pie. On arm64, ld64 hard-errors with "-no_pie cannot be used with arm64" (arm64 macOS mandates PIE). The -Qunused-arguments that WebKit prepends only suppresses clang's unused-argument compile warning; it does not stop the driver from forwarding -no_pie to the linker.
Nothing filters this out on the way to cmake: source.ts:1225-1227 appends spec.args (which carries webkit's CMAKE_C_FLAGS=optFlagStr) last, so it overrides the global CMAKE_C_FLAGS and the -no-pie definitely reaches darwin's configure.
Step-by-step proof
- Apple Silicon dev runs
bun run build:local --target=configure-WebKit(or any local-WebKit build).cfg.darwin = true, socfg.unix = true,cfg.abi !== "android"→optFlagsgets-fno-pic -fno-pie -no-pie. args.CMAKE_C_FLAGS = optFlagStris passed to the nested cmake (source.ts appends spec.args last, so it sticks).- CMake runs
FindThreads→try_compile()compiles a probe with-fno-pic -fno-pie -no-pie -c probe.c -o probe.o(fine), then links withclang ... -fno-pic -fno-pie -no-pie probe.o -o probe. - clang's Darwin toolchain forwards
-no-pie→-no_pieto ld64. - ld64 on arm64:
ld: -no_pie cannot be used with arm64→ link fails →Threads_FOUND = FALSE. FindThreadsisREQUIRED→CMake Error ... FindThreads→ configure aborts.
This is exactly the regression class the PR is fixing on Linux, transplanted onto macOS. CI won't catch it because the prebuilt path returns {kind: "none"} before optFlags is built; only local-mode developers on Apple Silicon hit it.
Why the flag is unnecessary on darwin anyway
The PR's stated rationale — driver-default -pie + -fno-pic object → R_X86_64_32S relocation failure — is ELF-specific. macOS uses Mach-O, Apple clang does not default-link try_compile probes as PIE in a way that conflicts with -fno-pic, and there is no equivalent failure mode. So even setting aside the ld64 error, -no-pie provides zero benefit on darwin while creating risk.
Fix
Match the rest of the codebase by gating the link-mode flag separately:
if (cfg.unix && cfg.abi !== "android") optFlags.push("-fno-pic", "-fno-pie");
if ((cfg.linux || cfg.freebsd) && cfg.abi !== "android") optFlags.push("-no-pie");(or equivalently keep one line and add -no-pie under !cfg.darwin). This mirrors flags.ts:943-944 / flags.ts:1046-1047 and keeps the Linux fix intact.
Pass `-no-pie` alongside `-fno-pic -fno-pie` in the `CMAKE_C_FLAGS` we hand to WebKit's local cmake configure. 23427db added `-fno-pic -fno-pie` to `optFlags` so JSC/WTF vtables land in `.rodata`. On distros where the clang driver defaults to `-pie` (Arch, current Ubuntu/Debian), cmake's `try_compile()` then compiles the probe with `-fno-pic` but still links it `-pie`, so every probe dies with: ``` relocation R_X86_64_32S against symbol `info_compiler' can not be used when making a PIE object; recompile with -fPIE ``` `FindThreads` is `REQUIRED`, so configure aborts. CI doesn't see this because the prebuilt-WebKit path never reconfigures. `-no-pie` in `CMAKE_C_FLAGS` is ignored at `-c` time (and WebKit already prepends `-Qunused-arguments` for its own compiles) but suppresses the driver's default `-pie` when `try_compile` links the probe. Kept it in `optFlags` rather than `CMAKE_EXE_LINKER_FLAGS` because `spec.args` are appended last and would clobber source.ts's `--ld-path=${cfg.ld}`. Prebuilt mode is unaffected — `build()` returns `{kind: "none"}` before `optFlags` is constructed. `compile.ts`: widen `LinkOpts.linkerMapOutput` to `string | undefined` so the `cond ? path : undefined` call sites in `bun.ts` typecheck under `exactOptionalPropertyTypes`. Same pattern as `bun.ts:136,138`. - Before: `bun run build:local --target=configure-WebKit` → `CMake Error ... FindThreads` - After: `Found Threads: TRUE`, `Configuring done` - `bun x tsc --noEmit -p scripts/build/tsconfig.json` clean - `build/debug/build.ninja` (prebuilt) contains no standalone `-no-pie`
What
Pass
-no-piealongside-fno-pic -fno-piein theCMAKE_C_FLAGSwe hand to WebKit's local cmake configure.Why
23427db added
-fno-pic -fno-pietooptFlagsso JSC/WTF vtables land in.rodata. On distros where the clang driver defaults to-pie(Arch, current Ubuntu/Debian), cmake'stry_compile()then compiles the probe with-fno-picbut still links it-pie, so every probe dies with:FindThreadsisREQUIRED, so configure aborts. CI doesn't see this because the prebuilt-WebKit path never reconfigures.-no-pieinCMAKE_C_FLAGSis ignored at-ctime (and WebKit already prepends-Qunused-argumentsfor its own compiles) but suppresses the driver's default-piewhentry_compilelinks the probe. Kept it inoptFlagsrather thanCMAKE_EXE_LINKER_FLAGSbecausespec.argsare appended last and would clobber source.ts's--ld-path=${cfg.ld}.Prebuilt mode is unaffected —
build()returns{kind: "none"}beforeoptFlagsis constructed.Also
compile.ts: widenLinkOpts.linkerMapOutputtostring | undefinedso thecond ? path : undefinedcall sites inbun.tstypecheck underexactOptionalPropertyTypes. Same pattern asbun.ts:136,138.Verified
bun run build:local --target=configure-WebKit→CMake Error ... FindThreadsFound Threads: TRUE,Configuring donebun x tsc --noEmit -p scripts/build/tsconfig.jsoncleanbuild/debug/build.ninja(prebuilt) contains no standalone-no-pie