fix(macos): haal het Metal-toolchainpad uit de koppelvlaggen #1946

Merged
brenno merged 2 commits from build/metal-toolchain-zoekpad into main 2026-09-03 13:29:29 +00:00
Owner

Wat dit oplost

Elke macOS-build opende met vier regels:

ld: warning: search path '/var/run/com.apple.security.cryptexd/mnt/com.apple.MobileAsset.MetalToolchain-v17.6.109.0.abPHna/Metal.xctoolchain/usr/lib/swift/macosx' not found

Sinds Xcode 26 komt de Metal-shadercompiler uit een los gedownload toolchain-cryptex. Zodra dat geladen is wijst TOOLCHAIN_DIR tijdens het koppelen daarheen in plaats van naar XcodeDefault.xctoolchain — en daar staat alleen shadergereedschap (metal, metallib, air-* onder usr/bin), geen usr/lib. CocoaPods en Flutters eigen podhelper hangen daar wel het zoekpad naar de Swift-runtime aan op.

Het is niet alleen ruis. Dezelfde waarde staat ook in LD_RUNPATH_SEARCH_PATHS, en die bakt een dode LC_RPATH ín de gebouwde app:

$ otool -l OciDeck.app/Contents/MacOS/OciDeck | grep -A2 LC_RPATH
  path /var/run/.../MetalToolchain-v17.6.109.0.abPHna/Metal.xctoolchain/usr/lib/swift/macosx

Dat koppelnummer (abPHna) verschilt per Metal-asset, dus per machine en per Apple-update. Een pad dat per bouwmachine anders is hoort niet in een binary die we uitbrengen.

De wijziging

Een post_install-haak in macos/Podfile haalt dat ene pad weg uit LIBRARY_SEARCH_PATHS en LD_RUNPATH_SEARCH_PATHS van alle gegenereerde xcconfigs. Wat overblijft is genoeg: /usr/lib/swift blijft op beide regels staan, Xcodes eigen standaarden leveren de Swift-map van de SDK, en niets in het bundel hangt aan @rpath/libswift* (hele bundel doorzocht op Mach-O-bestanden, nul treffers).

Twee dingen die tijdens het bouwen bleken:

  • Beide schrijfwijzen komen voor. "${TOOLCHAIN_DIR}" van CocoaPods en $(TOOLCHAIN_DIR) uit de podhelper — in Pods-Runner.debug.xcconfig zelfs samen op één regel. Wie er één van pakt, laat de waarschuwing gewoon staan.
  • DT_TOOLCHAIN_DIR kan niet. De eerste opzet leidde het pad daarheen om (dat wijst wél altijd naar Xcodes eigen toolchain). Xcode verbiedt die variabele hier expliciet en breekt de build af: error: DT_TOOLCHAIN_DIR cannot be used to evaluate LD_RUNPATH_SEARCH_PATHS, use TOOLCHAIN_DIR instead.

SWIFT_STDLIB_PATH in Pods-Runner-frameworks.sh houdt de oude schrijfwijze en blijft met opzet staan: die regel zit achter if [ "${XCODE_VERSION_MAJOR}" -lt 7 ] en wordt nooit uitgevoerd.

De haak telt hardop hoeveel bestanden hij raakte (nu 30). Dat is er niet voor de sier: een haak die niets meer vindt ziet er precies zo uit als een haak die zijn werk deed, dus de nul is het signaal op de dag dat CocoaPods die regels anders gaat schrijven.

Tweede commit: een verkeerde bewering in BUILD.md

docs/BUILD.md beschreef de macOS-build alsof Swift Package Manager uitstaat en CocoaPods al het pluginwerk doet. Sinds #1733 is dat omgedraaid. Die alinea stond twee regels boven de tekst die deze PR toch al schreef, dus hij is meteen rechtgezet.

Waarom hier geen regressietest bij zit

De wijziging zit in Ruby-code die CocoaPods uitvoert tijdens pod install, op bestanden die niet in git staan en die alleen op macOS bestaan. Er is geen laag waar flutter test bij kan: een Dart-test zou hooguit de tekst van de Podfile kunnen aflezen, en dat toetst de bewering, niet het gedrag. Een poort in tool/ zou alleen kunnen aanslaan op een machine waar macos/Pods al is uitgepakt — dus stil overslaan op de Linux-runner, en dat is precies het soort poort dat groen staat zonder iets te bewaken.

Wat er wél is: het faalgedrag kondigt zichzelf aan. Verdwijnt de haak of verandert CocoaPods het formaat, dan staan die vier regels weer bij élke build in beeld — precies zoals ze deze PR hebben veroorzaakt.

Bewaker

Overgeslagen, expliciet. Deze wijziging raakt geen bestandsformaat, geen opslag, geen afhankelijkheid erbij, geen uitgaand verkeer en geen publieke belofte — het zijn koppelvlaggen voor de macOS-build en een build-notitie.

Getoetst

  • make check groen
  • make check-secrets groen (gitleaks + trufflehog, 0 findings)
  • make sast groen (semgrep, 0 findings)
  • Debug-build met een koppeling die echt plaatsvond: 0 ld: warning, 0 fouten, dode rpath weg
  • Release-build (207,9 MB): 0 ld: warning, 0 fouten, rpaths schoon
  • pod install gedraaid door Flutter zelf (Manifest.lock weggegooid): haak slaat aan, 0 TOOLCHAIN_DIR over, build schoon
  • DAST (ZAP) niet gedraaid — niet van toepassing op een macOS-koppelvlag

Een eerdere ronde stond ten onrechte groen omdat de build niets te koppelen had en het oude product bleef staan. De cijfers hierboven komen uit builds die het product opnieuw hebben gemaakt.

## Wat dit oplost Elke macOS-build opende met vier regels: ``` ld: warning: search path '/var/run/com.apple.security.cryptexd/mnt/com.apple.MobileAsset.MetalToolchain-v17.6.109.0.abPHna/Metal.xctoolchain/usr/lib/swift/macosx' not found ``` Sinds Xcode 26 komt de Metal-shadercompiler uit een los gedownload toolchain-cryptex. Zodra dat geladen is wijst `TOOLCHAIN_DIR` tijdens het koppelen daarheen in plaats van naar `XcodeDefault.xctoolchain` — en daar staat alleen shadergereedschap (`metal`, `metallib`, `air-*` onder `usr/bin`), geen `usr/lib`. CocoaPods en Flutters eigen podhelper hangen daar wel het zoekpad naar de Swift-runtime aan op. **Het is niet alleen ruis.** Dezelfde waarde staat ook in `LD_RUNPATH_SEARCH_PATHS`, en die bakt een dode `LC_RPATH` ín de gebouwde app: ``` $ otool -l OciDeck.app/Contents/MacOS/OciDeck | grep -A2 LC_RPATH path /var/run/.../MetalToolchain-v17.6.109.0.abPHna/Metal.xctoolchain/usr/lib/swift/macosx ``` Dat koppelnummer (`abPHna`) verschilt per Metal-asset, dus per machine en per Apple-update. Een pad dat per bouwmachine anders is hoort niet in een binary die we uitbrengen. ## De wijziging Een `post_install`-haak in `macos/Podfile` haalt dat ene pad weg uit `LIBRARY_SEARCH_PATHS` en `LD_RUNPATH_SEARCH_PATHS` van alle gegenereerde xcconfigs. Wat overblijft is genoeg: `/usr/lib/swift` blijft op beide regels staan, Xcodes eigen standaarden leveren de Swift-map van de SDK, en **niets in het bundel hangt aan `@rpath/libswift*`** (hele bundel doorzocht op Mach-O-bestanden, nul treffers). Twee dingen die tijdens het bouwen bleken: - **Beide schrijfwijzen komen voor.** `"${TOOLCHAIN_DIR}"` van CocoaPods en `$(TOOLCHAIN_DIR)` uit de podhelper — in `Pods-Runner.debug.xcconfig` zelfs samen op één regel. Wie er één van pakt, laat de waarschuwing gewoon staan. - **`DT_TOOLCHAIN_DIR` kan niet.** De eerste opzet leidde het pad daarheen om (dat wijst wél altijd naar Xcodes eigen toolchain). Xcode verbiedt die variabele hier expliciet en breekt de build af: `error: DT_TOOLCHAIN_DIR cannot be used to evaluate LD_RUNPATH_SEARCH_PATHS, use TOOLCHAIN_DIR instead`. `SWIFT_STDLIB_PATH` in `Pods-Runner-frameworks.sh` houdt de oude schrijfwijze en blijft met opzet staan: die regel zit achter `if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]` en wordt nooit uitgevoerd. De haak telt hardop hoeveel bestanden hij raakte (nu 30). Dat is er niet voor de sier: een haak die niets meer vindt ziet er precies zo uit als een haak die zijn werk deed, dus de nul is het signaal op de dag dat CocoaPods die regels anders gaat schrijven. ## Tweede commit: een verkeerde bewering in BUILD.md `docs/BUILD.md` beschreef de macOS-build alsof Swift Package Manager uitstaat en CocoaPods al het pluginwerk doet. Sinds #1733 is dat omgedraaid. Die alinea stond twee regels boven de tekst die deze PR toch al schreef, dus hij is meteen rechtgezet. ## Waarom hier geen regressietest bij zit De wijziging zit in Ruby-code die CocoaPods uitvoert tijdens `pod install`, op bestanden die niet in git staan en die alleen op macOS bestaan. Er is geen laag waar `flutter test` bij kan: een Dart-test zou hooguit de tekst van de `Podfile` kunnen aflezen, en dat toetst de bewering, niet het gedrag. Een poort in `tool/` zou alleen kunnen aanslaan op een machine waar `macos/Pods` al is uitgepakt — dus stil overslaan op de Linux-runner, en dat is precies het soort poort dat groen staat zonder iets te bewaken. Wat er wél is: het faalgedrag kondigt zichzelf aan. Verdwijnt de haak of verandert CocoaPods het formaat, dan staan die vier regels weer bij élke build in beeld — precies zoals ze deze PR hebben veroorzaakt. ## Bewaker Overgeslagen, expliciet. Deze wijziging raakt geen bestandsformaat, geen opslag, geen afhankelijkheid erbij, geen uitgaand verkeer en geen publieke belofte — het zijn koppelvlaggen voor de macOS-build en een build-notitie. ## Getoetst - [x] `make check` groen - [x] `make check-secrets` groen (gitleaks + trufflehog, 0 findings) - [x] `make sast` groen (semgrep, 0 findings) - [x] **Debug-build met een koppeling die echt plaatsvond**: 0 `ld: warning`, 0 fouten, dode rpath weg - [x] **Release-build** (207,9 MB): 0 `ld: warning`, 0 fouten, rpaths schoon - [x] **`pod install` gedraaid door Flutter zelf** (`Manifest.lock` weggegooid): haak slaat aan, 0 `TOOLCHAIN_DIR` over, build schoon - [ ] DAST (ZAP) niet gedraaid — niet van toepassing op een macOS-koppelvlag Een eerdere ronde stond ten onrechte groen omdat de build niets te koppelen had en het oude product bleef staan. De cijfers hierboven komen uit builds die het product opnieuw hebben gemaakt.
BUILD.md beschreef de macOS-build alsof SPM is uitgezet en CocoaPods al het
pluginwerk doet. Sinds #1733 is dat omgedraaid: SPM staat aan en CocoaPods
houdt nog precies één plugin over, desktop_multi_window. Dat is ook waarom de
build meldt dat een plugin SPM niet ondersteunt — die melding hoort erbij.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fix(macos): haal het Metal-toolchainpad uit de koppelvlaggen
All checks were successful
scans / scans (pull_request) Successful in 4m26s
static-gate / static-gate (pull_request) Successful in 11m22s
0485af1b78
Sinds Xcode 26 komt de Metal-shadercompiler uit een los gedownload
toolchain-cryptex, en zodra dat geladen is wijst TOOLCHAIN_DIR tijdens het
koppelen daarheen in plaats van naar XcodeDefault.xctoolchain. Daar staat
alleen shadergereedschap en geen usr/lib, dus het zoekpad naar de
Swift-runtime dat CocoaPods en Flutters podhelper daaraan ophangen bestaat
niet. Elke build gaf vier regels

  ld: warning: search path '.../Metal.xctoolchain/usr/lib/swift/macosx' not found

en dezelfde waarde in LD_RUNPATH_SEARCH_PATHS bakte een dode LC_RPATH in de
gebouwde app, inclusief het koppelnummer van het cryptex — een pad dat per
machine en per Apple-update verschilt, in een binary die we uitbrengen.

Een post_install-haak haalt dat pad uit LIBRARY_SEARCH_PATHS en
LD_RUNPATH_SEARCH_PATHS van alle gegenereerde xcconfigs, in beide
schrijfwijzen: "${...}" van CocoaPods en $(...) uit de podhelper staan in
Pods-Runner.debug.xcconfig samen op één regel.

Getoetst met een koppeling die echt plaatsvond, in Debug en in Release: geen
waarschuwingen, geen fouten, en otool -l laat de dode rpath niet meer zien.
Niets in het bundel hangt aan @rpath/libswift*. Ook getoetst met een
pod install die Flutter zelf startte, niet ik.

Omleiden naar DT_TOOLCHAIN_DIR was de eerste opzet en gaat niet: Xcode
verbiedt die variabele hier expliciet en breekt de build af.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
brenno force-pushed build/metal-toolchain-zoekpad from 0485af1b78
All checks were successful
scans / scans (pull_request) Successful in 4m26s
static-gate / static-gate (pull_request) Successful in 11m22s
to 0689609881
All checks were successful
scans / scans (pull_request) Successful in 4m42s
static-gate / static-gate (pull_request) Successful in 12m11s
web-gate / web-gate (pull_request) Successful in 11m20s
2026-09-03 11:31:26 +00:00
Compare
brenno force-pushed build/metal-toolchain-zoekpad from 0689609881
All checks were successful
scans / scans (pull_request) Successful in 4m42s
static-gate / static-gate (pull_request) Successful in 12m11s
web-gate / web-gate (pull_request) Successful in 11m20s
to d6cefd0a47
All checks were successful
scans / scans (pull_request) Successful in 4m54s
static-gate / static-gate (pull_request) Successful in 10m50s
2026-09-03 11:59:47 +00:00
Compare
brenno force-pushed build/metal-toolchain-zoekpad from d6cefd0a47
All checks were successful
scans / scans (pull_request) Successful in 4m54s
static-gate / static-gate (pull_request) Successful in 10m50s
to 0f4936f2df
All checks were successful
scans / scans (pull_request) Successful in 3m12s
static-gate / static-gate (pull_request) Successful in 8m30s
2026-09-03 13:05:12 +00:00
Compare
brenno force-pushed build/metal-toolchain-zoekpad from 0f4936f2df
All checks were successful
scans / scans (pull_request) Successful in 3m12s
static-gate / static-gate (pull_request) Successful in 8m30s
to 86613edad6
All checks were successful
scans / scans (pull_request) Successful in 3m7s
static-gate / static-gate (pull_request) Successful in 7m0s
2026-09-03 13:20:25 +00:00
Compare
brenno merged commit 72a280b319 into main 2026-09-03 13:29:29 +00:00
Sign in to join this conversation.
No description provided.