Skip to content

build: fix local WebKit configure on PIE-default distros - #30710

Merged
dylan-conway merged 1 commit into
mainfrom
claude/pedantic-saha-449b5d
May 14, 2026
Merged

dylan-conway merged 1 commit into
mainfrom
claude/pedantic-saha-449b5d

Conversation

@dylan-conway

Copy link
Copy Markdown
Member

What

Pass -no-pie alongside -fno-pic -fno-pie in the CMAKE_C_FLAGS we hand to WebKit's local cmake configure.

Why

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.

Also

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.

Verified

  • 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

…bes link on PIE-default distros; fix LinkOpts.linkerMapOutput exactOptionalPropertyTypes error
@robobun

robobun commented May 14, 2026 •

Copy link
Copy Markdown
Collaborator

@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b366debd-3261-44cb-89b2-88bfc4e56440

📥 Commits

Reviewing files that changed from the base of the PR and between e872030 and e65fa03.

📒 Files selected for processing (2)
  • scripts/build/compile.ts
  • scripts/build/deps/webkit.ts

Walkthrough

This PR updates the build system with two targeted fixes: clarifying the optional type of linkerMapOutput in the link interface, and expanding the Unix compiler flags for WebKit builds to include -no-pie for better linker behavior during compilation probes.

Changes

Build System Configuration

Layer / File(s) Summary
Link options type clarification
scripts/build/compile.ts
LinkOpts.linkerMapOutput type is explicitly marked as string | undefined to clarify the optional behavior at the type contract level.
WebKit compilation flags
scripts/build/deps/webkit.ts
WebKit local-mode build adds -no-pie compiler flag for Unix non-Android builds, complementing the existing -fno-pic and -fno-pie flags used in try_compile probes and dependency discovery.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main change: fixing WebKit configure on PIE-default distributions by addressing linker flag issues.
Description check ✅ Passed The PR description comprehensively covers both template sections with detailed explanations of what changed, why it was necessary, and how it was verified.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@dylan-conway
dylan-conway merged commit d5c692a into main May 14, 2026
6 of 34 checks passed
@dylan-conway
dylan-conway deleted the claude/pedantic-saha-449b5d branch May 14, 2026 15:55
// -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");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 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

  1. Apple Silicon dev runs bun run build:local --target=configure-WebKit (or any local-WebKit build). cfg.darwin = true, so cfg.unix = true, cfg.abi !== "android" → optFlags gets -fno-pic -fno-pie -no-pie.
  2. args.CMAKE_C_FLAGS = optFlagStr is passed to the nested cmake (source.ts appends spec.args last, so it sticks).
  3. CMake runs FindThreads → try_compile() compiles a probe with -fno-pic -fno-pie -no-pie -c probe.c -o probe.o (fine), then links with clang ... -fno-pic -fno-pie -no-pie probe.o -o probe.
  4. clang's Darwin toolchain forwards -no-pie → -no_pie to ld64.
  5. ld64 on arm64: ld: -no_pie cannot be used with arm64 → link fails → Threads_FOUND = FALSE.
  6. FindThreads is REQUIRED → 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.

scook12 pushed a commit to scook12/bun that referenced this pull request May 16, 2026
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`
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.

2 participants