11#!/usr/bin/env node
2- // Ad-hoc signs `set-mcp` before the macOS bundler seals the app (`build.beforeBundleCommand`).
3- // The bundler signs `Contents/MacOS/set` first, which codesign resolves to the bundle itself,
4- // sealing an unsigned `set-mcp` beside it and failing. On arm64 the linker ad-hoc signs everything
5- // so it passed; a universal `lipo` output has no signature.
2+ // Prepares `set-mcp` before the macOS bundler seals the app (`build.beforeBundleCommand`).
3+ //
4+ // Universal builds: `tauri build --target universal-apple-darwin` compiles both slices but `lipo`s
5+ // only the app binary, so the bundler then asks for `universal-apple-darwin/release/set-mcp`,
6+ // which nothing made. This script makes it from the two slices.
7+ //
8+ // Signing: the bundler signs `Contents/MacOS/set` first, which codesign resolves to the bundle
9+ // itself, sealing an unsigned `set-mcp` beside it and failing. On arm64 the linker ad-hoc signs
10+ // everything so it passed; a `lipo` output has no signature.
611
712import { execFileSync } from "node:child_process" ;
813import { existsSync , readdirSync } from "node:fs" ;
@@ -21,7 +26,29 @@ if (!existsSync(targetDir)) {
2126 process . exit ( 0 ) ;
2227}
2328
24- // `target/release/` without `--target`, `target/<triple>/release/` with it.
29+ // The universal app binary is the sign that this is a universal build; the slices are then
30+ // guaranteed to exist because Tauri just built them.
31+ const universalDir = join ( targetDir , "universal-apple-darwin" , "release" ) ;
32+ const slices = [ "aarch64-apple-darwin" , "x86_64-apple-darwin" ] . map ( ( triple ) =>
33+ join ( targetDir , triple , "release" , "set-mcp" ) ,
34+ ) ;
35+ if ( existsSync ( join ( universalDir , "set" ) ) ) {
36+ const missing = slices . filter ( ( slice ) => ! existsSync ( slice ) ) ;
37+ if ( missing . length > 0 ) {
38+ console . error (
39+ `::error::presign-mcp: universal build, but set-mcp slice missing: ${ missing . join ( ", " ) } ` ,
40+ ) ;
41+ process . exit ( 1 ) ;
42+ }
43+ const universal = join ( universalDir , "set-mcp" ) ;
44+ execFileSync ( "lipo" , [ "-create" , "-output" , universal , ...slices ] , {
45+ stdio : "inherit" ,
46+ } ) ;
47+ console . log ( `presign-mcp: lipo'd ${ universal } ` ) ;
48+ }
49+
50+ // `target/release/` without `--target`, `target/<triple>/release/` with it (including the
51+ // universal one made above, which is the copy the bundler ships).
2552const candidates = [ join ( targetDir , "release" , "set-mcp" ) ] ;
2653for ( const entry of readdirSync ( targetDir , { withFileTypes : true } ) ) {
2754 if ( entry . isDirectory ( ) && entry . name . endsWith ( "-apple-darwin" ) ) {
0 commit comments