fix(build): make macOS's libsystem/ with Xcode 16 too, as release builds do by Kushalkhemka · Pull Request #192 · opensec-git/Pi-Bolt · GitHub
Skip to content

fix(build): make macOS's libsystem/ with Xcode 16 too, as release builds do - #192

Draft
Kushalkhemka wants to merge 1 commit into
pi-boltfrom
fix/macos-libsystem-xcode16
Draft

Kushalkhemka wants to merge 1 commit into
pi-boltfrom
fix/macos-libsystem-xcode16

Conversation

@Kushalkhemka

@Kushalkhemka Kushalkhemka commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Problem

A macOS release start costs about 17 M instructions more than a local build of the same source (M5: pi --version 70 vs 53 M,
ready to type 170 vs 153 M, pi -p 222 vs 206 M on bolt-v1.0.5).

The release archives have no libsystem/ beside pi-bin. scripts/lib/darwin_libsystem.py (#139) reads pi-bin's linked
libraries and rpaths from xcrun dyld_info -dependents. Xcode 16.4, which GitHub's macos-15 runners have, prints no rpath
section there, so the script decides the runtime is an older one and makes nothing. The release log says so:

libsystem: pi-bin loads libSystem from /usr/lib (an older runtime): none made

The step is advice-only, so the build went on. Every macOS release since 1.0.3 (the first with #139) shipped without it. A
local build with a newer Xcode makes it, which is the whole local-vs-release gap.

Xcode 16's dyld_info -imports also prints no index column before each name, so the script's check (line.split()[1])
would have read the wrong word once the first problem was fixed.

Change

  • darwin_libsystem.py: the load commands come from otool -l (LC_LOAD_DYLIB, LC_RPATH); the import name is the word
    before (from libSystem), which both dyld_info formats print. The shim and its check are otherwise unchanged.
  • release.yml: a macOS archive without libsystem/libSystem.B.dylib stops the release, so this cannot silently come back.

Nothing in Pi or the engine changes; the executables are the same, only libsystem/ (six 16 KB files) is added beside them.

Evidence

macOS release builds on GitHub's macos-15 runner, as release.yml makes them (fetch-runtime bolt-v1.0.5, prepare-pi.sh,
package-release.sh), scratch run 40526577133:

  • base (pi-bolt 2e1bc7a): libsystem: pi-bin loads libSystem from /usr/lib (an older runtime): none made (as the release)
  • this branch: libsystem: 483 imports bind to the same addresses through it; check-macos-floor passes for the new dylibs
    (macOS 13.0); tests/pi/run.sh passes.

M5, instructions, interleaved medians (ready.py), the CI-built archives against the bolt-v1.0.5 archive and a copy of it:

RESULTS_TABLE

Sameness (CI-built fix vs bolt-v1.0.5, default and -jit): SAMENESS

Linux and Windows have no such gap: a build made on a runner with build-pi.sh / build-pi.ps1 runs as the bolt-v1.0.5
archive does (Linux x86-64: startup 7 / 7 ms CPU, pi -p 43 / 44, interactive 136 / 137, release copy 8 / 43 / 138;
-jit within 3%. Windows: --version 17 / 17 ms, pi -p 79 / 80, copies 16-17 / 80-81). Their builds have no
advice-only step like this one, and the release logs show no skipped step.

…lds do

darwin_libsystem.py read pi-bin's linked libraries and rpaths from dyld_info -dependents. Xcode 16's (GitHub's macOS 15
runners) prints no rpaths, so the script decided the runtime loads libSystem from /usr/lib and made no libsystem/: every
macOS release since 1.0.3 shipped without it, and starts with about 17 M more instructions than a build made with a newer
Xcode. The load commands now come from otool -l, and each import's name is the word before "(from libSystem)", which
both dyld_info formats print. release.yml now stops when a macOS archive has no libsystem/.

This branch has not been deployed

No deployments
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