Bash · 4724 bytes Raw Blame History
1 #!/bin/bash
2 # Simple library bundling - copy libs and update binary paths only
3 # Don't touch the bundled libraries themselves
4
5 set -e
6
7 APP_BUNDLE="Sniffly.app"
8 FRAMEWORKS="${APP_BUNDLE}/Contents/Frameworks"
9 MACOS_BIN="${APP_BUNDLE}/Contents/MacOS/sniffly"
10
11 echo "=== Simple Library Bundling ==="
12
13 # Copy all GTK4-related libraries recursively
14 echo "Step 1: Copying GTK4 libraries..."
15 mkdir -p "$FRAMEWORKS"
16
17 # Function to copy a library and its dependencies
18 copy_lib_and_deps() {
19 local lib=$1
20 local libname=$(basename "$lib")
21
22 if [ -f "$FRAMEWORKS/$libname" ]; then
23 return # Already copied
24 fi
25
26 if [ ! -f "$lib" ]; then
27 return # Doesn't exist
28 fi
29
30 echo " Copying $libname"
31 cp "$lib" "$FRAMEWORKS/"
32 chmod 644 "$FRAMEWORKS/$libname"
33
34 # Get dependencies and copy them too
35 otool -L "$lib" | grep "/opt/homebrew" | awk '{print $1}' | while read dep; do
36 if [ -f "$dep" ]; then
37 copy_lib_and_deps "$dep"
38 fi
39 done
40 }
41
42 # Start with the main libraries the binary needs
43 for lib in libgtk-4-fortran libgtk-4 libcairo libgio libglib libgfortran; do
44 find /opt/homebrew -name "${lib}*.dylib" -o -name "${lib}*.*.dylib" 2>/dev/null | head -1 | while read libpath; do
45 if [ -n "$libpath" ]; then
46 copy_lib_and_deps "$libpath"
47 fi
48 done
49 done
50
51 # Also copy from /usr/local for gtk-4-fortran
52 if [ -f "/usr/local/lib/libgtk-4-fortran.4.8.0.dylib" ]; then
53 copy_lib_and_deps "/usr/local/lib/libgtk-4-fortran.4.8.0.dylib"
54 fi
55
56 echo ""
57 echo "Step 2: Updating binary to use bundled libraries..."
58 # Only update the main binary's paths - don't touch the libraries
59 for lib in "$FRAMEWORKS"/*.dylib; do
60 if [ -f "$lib" ]; then
61 libname=$(basename "$lib")
62 # Try to change the binary's reference to this library
63 install_name_tool -change "/opt/homebrew/opt/*/lib/$libname" "@executable_path/../Frameworks/$libname" "$MACOS_BIN" 2>/dev/null || true
64 install_name_tool -change "/usr/local/lib/$libname" "@executable_path/../Frameworks/$libname" "$MACOS_BIN" 2>/dev/null || true
65 fi
66 done
67
68 # Update specific known paths in the binary
69 install_name_tool -change "@rpath/libgtk-4-fortran.4.8.0.dylib" "@executable_path/../Frameworks/libgtk-4-fortran.4.8.0.dylib" "$MACOS_BIN" 2>/dev/null || true
70 install_name_tool -change "/opt/homebrew/opt/gtk4/lib/libgtk-4.1.dylib" "@executable_path/../Frameworks/libgtk-4.1.dylib" "$MACOS_BIN" 2>/dev/null || true
71 install_name_tool -change "/opt/homebrew/opt/cairo/lib/libcairo.2.dylib" "@executable_path/../Frameworks/libcairo.2.dylib" "$MACOS_BIN" 2>/dev/null || true
72 install_name_tool -change "/opt/homebrew/opt/glib/lib/libgio-2.0.0.dylib" "@executable_path/../Frameworks/libgio-2.0.0.dylib" "$MACOS_BIN" 2>/dev/null || true
73 install_name_tool -change "/opt/homebrew/opt/glib/lib/libglib-2.0.0.dylib" "@executable_path/../Frameworks/libglib-2.0.0.dylib" "$MACOS_BIN" 2>/dev/null || true
74 install_name_tool -change "/opt/homebrew/opt/gcc/lib/gcc/current/libgfortran.5.dylib" "@executable_path/../Frameworks/libgfortran.5.dylib" "$MACOS_BIN" 2>/dev/null || true
75
76 echo ""
77 echo "Step 3: Fixing bundled libraries to reference each other..."
78 # Fix all the bundled libraries to reference each other instead of /opt/homebrew
79 for lib in "$FRAMEWORKS"/*.dylib; do
80 if [ -f "$lib" ]; then
81 libname=$(basename "$lib")
82
83 # Fix the library's ID
84 install_name_tool -id "@executable_path/../Frameworks/$libname" "$lib" 2>/dev/null || true
85
86 # Fix only the actual dependencies (much faster than trying all combinations)
87 otool -L "$lib" | grep "/opt/homebrew\|/usr/local" | awk '{print $1}' | while read dep_path; do
88 dep_name=$(basename "$dep_path")
89 if [ -f "$FRAMEWORKS/$dep_name" ]; then
90 install_name_tool -change "$dep_path" "@executable_path/../Frameworks/$dep_name" "$lib" 2>/dev/null || true
91 fi
92 done
93 fi
94 done
95
96 echo ""
97 echo "Step 4: Re-signing everything (CRITICAL)..."
98 # After install_name_tool modifications, code signatures are invalid
99 # macOS will SIGKILL the app if signatures don't match
100 # Use ad-hoc signing (no certificate needed)
101 echo " Re-signing main binary..."
102 codesign --remove-signature "$MACOS_BIN" 2>/dev/null || true
103 codesign -s - -f "$MACOS_BIN"
104
105 echo " Re-signing bundled libraries..."
106 for lib in "$FRAMEWORKS"/*.dylib; do
107 if [ -f "$lib" ]; then
108 codesign --remove-signature "$lib" 2>/dev/null || true
109 codesign -s - -f "$lib" 2>/dev/null || true
110 fi
111 done
112
113 echo ""
114 echo "Step 5: Verifying..."
115 TOTAL_LIBS=$(ls -1 "$FRAMEWORKS" | wc -l | tr -d ' ')
116 echo "Total libraries bundled: $TOTAL_LIBS"
117
118 echo ""
119 echo "=== Bundling Complete ==="