Skip to content

Commit 4d805fc

Browse files
committed
fix: remove .framework dirs entirely to pass notarization
Apple's notarization validates .framework directories as bundles, requiring proper symlink structure and _CodeSignature/CodeResources. Since cp -RL dereferences all symlinks, the framework structure is permanently broken — no signing approach can produce a valid bundle. Individual file signatures inside the framework pass codesign locally but Apple's notarization still rejects them because the bundle-level validation fails. Solution: delete all .framework directories after cp -RL. The standalone _internal/Python binary (an independent copy created by cp -RL breaking the hardlink) is already properly signed and passes notarization. The otool -L debug output will confirm whether the bootloader references the framework path at runtime.
1 parent ec06ba8 commit 4d805fc

1 file changed

Lines changed: 27 additions & 46 deletions

File tree

src-tauri/before_build.sh

Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -43,71 +43,52 @@ cp -RL dist/syft-space-backend/* "$BACKEND_DIST/"
4343
# 4. Ensure the main executable is executable
4444
chmod +x "$BACKEND_DIST/syft-space-backend${EXE_EXT}"
4545

46-
# Debug: verify no symlinks remain after copy
47-
echo "=== Checking for remaining symlinks ==="
48-
SYMLINKS=$(find "$BACKEND_DIST" -type l)
49-
if [ -n "$SYMLINKS" ]; then
50-
echo "WARNING: Symlinks still present:"
51-
echo "$SYMLINKS"
52-
else
53-
echo "OK: No symlinks found"
54-
fi
55-
56-
# Debug: show Python.framework structure
57-
echo "=== Python.framework structure ==="
58-
find "$BACKEND_DIST" -path "*/Python.framework/*" -exec ls -la {} \; 2>/dev/null | head -30
59-
60-
# 5. On macOS, codesign all binaries for notarization.
61-
# cp -RL dereferences symlinks, which breaks .framework bundle structure.
62-
# codesign auto-detects bundles by examining parent dir structure (Versions/,
63-
# Resources/, Info.plist) via CFBundle — not just the directory name.
64-
# Workaround: copy each Mach-O to an isolated temp dir for signing, then
65-
# copy back. The signature is embedded in the Mach-O LC_CODE_SIGNATURE
66-
# load command and is path-independent.
46+
# 5. On macOS, remove .framework bundles and codesign all binaries.
47+
# Apple's notarization validates .framework dirs as bundles, requiring proper
48+
# symlink structure and _CodeSignature/CodeResources. cp -RL dereferences
49+
# symlinks, making the framework structure invalid and unfixable.
50+
# Since _internal/Python already exists as a standalone copy of the Python
51+
# dylib (thanks to cp -RL breaking hardlinks), we can safely remove the
52+
# framework — the bootloader loads from _internal/Python, not the framework.
6753
if [[ "$TARGET_TRIPLE" == *"apple"* ]]; then
6854
ENTITLEMENTS="$PROJECT_ROOT/src-tauri/entitlements.plist"
6955
SIGN_IDENTITY="${APPLE_SIGNING_IDENTITY:--}"
70-
SIGN_TMPDIR=$(mktemp -d)
56+
57+
# a) Remove all .framework directories. After cp -RL, these contain only
58+
# redundant copies with broken bundle structure that notarization rejects.
59+
echo "Removing .framework bundles (broken by cp -RL, causes notarization failure)..."
60+
find "$BACKEND_DIST" -type d -name "*.framework" -print | while read -r fw; do
61+
echo " Removing: $fw"
62+
rm -rf "$fw"
63+
done
64+
65+
# Debug: show what the bootloader links against
66+
echo "=== Bootloader library dependencies ==="
67+
otool -L "$BACKEND_DIST/syft-space-backend" 2>&1 || true
68+
7169
echo "Codesigning PyInstaller onedir output (identity: $SIGN_IDENTITY)..."
7270

73-
# a) Sign all Mach-O files (except the main executable) individually.
74-
# Each file is copied to an isolated temp dir so codesign cannot
75-
# detect surrounding bundle structure and trigger bundle signing.
71+
# b) Sign all Mach-O files (except the main executable).
7672
find "$BACKEND_DIST" -type f ! -name "syft-space-backend" | while read -r f; do
7773
if file "$f" | grep -q "Mach-O"; then
78-
TMPFILE="$SIGN_TMPDIR/$(basename "$f")"
79-
cp "$f" "$TMPFILE"
8074
codesign --force --options runtime --entitlements "$ENTITLEMENTS" \
81-
--sign "$SIGN_IDENTITY" "$TMPFILE"
82-
cp "$TMPFILE" "$f"
83-
rm "$TMPFILE"
75+
--sign "$SIGN_IDENTITY" "$f"
8476
fi
8577
done
8678

87-
# b) Sign the main executable last (not inside a bundle, signs directly)
79+
# c) Sign the main executable last.
8880
codesign --force --options runtime --entitlements "$ENTITLEMENTS" \
8981
--sign "$SIGN_IDENTITY" "$BACKEND_DIST/syft-space-backend${EXE_EXT}"
90-
rm -rf "$SIGN_TMPDIR"
9182
echo "Codesigning complete."
9283

93-
# Debug: verify signatures on the previously-problematic files
94-
echo "=== Verifying signatures ==="
95-
for f in \
96-
"$BACKEND_DIST/_internal/Python" \
97-
"$BACKEND_DIST/_internal/Python.framework/Python" \
98-
"$BACKEND_DIST/_internal/Python.framework/Versions/3.12/Python" \
99-
"$BACKEND_DIST/syft-space-backend"; do
84+
# Debug: verify signatures
85+
echo "=== Verifying key signatures ==="
86+
for f in "$BACKEND_DIST/_internal/Python" "$BACKEND_DIST/syft-space-backend"; do
10087
if [ -f "$f" ]; then
10188
echo "--- $f ---"
102-
codesign -dvvv "$f" 2>&1 | head -5 || true
103-
codesign --verify --strict "$f" 2>&1 || true
89+
codesign --verify --strict --verbose "$f" 2>&1 || true
10490
fi
10591
done
106-
107-
# Debug: show what the bootloader links against (helps determine if
108-
# Python.framework is needed at runtime or can be removed in the future)
109-
echo "=== Bootloader library dependencies ==="
110-
otool -L "$BACKEND_DIST/syft-space-backend" 2>&1 | head -20 || true
11192
fi
11293

11394
# 6. Build frontend

0 commit comments

Comments
 (0)