Bash · 8396 bytes Raw Blame History
1 #!/bin/bash
2 # Complete library bundling script for Sniffly
3 # Handles all GTK4 dependencies properly
4
5 set -e
6
7 APP_BUNDLE="Sniffly.app"
8 FRAMEWORKS="${APP_BUNDLE}/Contents/Frameworks"
9 MACOS_BIN="${APP_BUNDLE}/Contents/MacOS/sniffly-bin"
10
11 echo "=== Sniffly Library Bundling ==="
12 echo ""
13
14 # Create frameworks directory
15 mkdir -p "$FRAMEWORKS"
16
17 echo "Step 1: Copying critical GTK4 libraries..."
18 # Main GTK4
19 cp -v /opt/homebrew/opt/gtk4/lib/libgtk-4.1.dylib "$FRAMEWORKS/" 2>/dev/null || echo " libgtk-4.1.dylib not found (may be bundled already)"
20
21 # GLib family
22 cp -v /opt/homebrew/opt/glib/lib/libglib-2.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
23 cp -v /opt/homebrew/opt/glib/lib/libgio-2.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
24 cp -v /opt/homebrew/opt/glib/lib/libgobject-2.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
25 cp -v /opt/homebrew/opt/glib/lib/libgmodule-2.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
26
27 # GTK-Fortran binding
28 cp -v /usr/local/lib/libgtk-4-fortran.4.8.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
29
30 # Pango
31 cp -v /opt/homebrew/opt/pango/lib/libpango-1.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
32 cp -v /opt/homebrew/opt/pango/lib/libpangocairo-1.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
33 cp -v /opt/homebrew/opt/pango/lib/libpangoft2-1.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
34
35 # GdkPixbuf
36 cp -v /opt/homebrew/opt/gdk-pixbuf/lib/libgdk_pixbuf-2.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
37
38 # Cairo
39 cp -v /opt/homebrew/opt/cairo/lib/libcairo.2.dylib "$FRAMEWORKS/" 2>/dev/null || true
40 cp -v /opt/homebrew/opt/cairo/lib/libcairo-gobject.2.dylib "$FRAMEWORKS/" 2>/dev/null || true
41
42 # HarfBuzz
43 cp -v /opt/homebrew/opt/harfbuzz/lib/libharfbuzz.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
44
45 # Graphene
46 cp -v /opt/homebrew/opt/graphene/lib/libgraphene-1.0.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
47
48 # Epoxy (OpenGL wrapper)
49 cp -v /opt/homebrew/opt/libepoxy/lib/libepoxy.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
50
51 # Gettext (internationalization)
52 cp -v /opt/homebrew/opt/gettext/lib/libintl.8.dylib "$FRAMEWORKS/" 2>/dev/null || true
53
54 # Additional dependencies
55 cp -v /opt/homebrew/opt/fribidi/lib/libfribidi.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
56 cp -v /opt/homebrew/opt/fontconfig/lib/libfontconfig.1.dylib "$FRAMEWORKS/" 2>/dev/null || true
57 cp -v /opt/homebrew/opt/freetype/lib/libfreetype.6.dylib "$FRAMEWORKS/" 2>/dev/null || true
58
59 # GFortran runtime (dylibbundler can't handle this due to header padding)
60 echo "Manually copying GFortran runtime..."
61 cp -v /opt/homebrew/opt/gcc/lib/gcc/current/libgfortran.5.dylib "$FRAMEWORKS/" 2>/dev/null || \
62 cp -v /usr/local/lib/gcc/current/libgfortran.5.dylib "$FRAMEWORKS/" 2>/dev/null || true
63 cp -v /opt/homebrew/opt/gcc/lib/gcc/current/libgcc_s.1.1.dylib "$FRAMEWORKS/" 2>/dev/null || \
64 cp -v /usr/local/lib/gcc/current/libgcc_s.1.1.dylib "$FRAMEWORKS/" 2>/dev/null || true
65 cp -v /opt/homebrew/opt/gcc/lib/gcc/current/libquadmath.0.dylib "$FRAMEWORKS/" 2>/dev/null || \
66 cp -v /usr/local/lib/gcc/current/libquadmath.0.dylib "$FRAMEWORKS/" 2>/dev/null || true
67
68 # Fix paths in sniffly-bin to point to bundled gfortran
69 echo "Fixing GFortran library paths in binary..."
70 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
71 install_name_tool -change /usr/local/lib/gcc/current/libgfortran.5.dylib @executable_path/../Frameworks/libgfortran.5.dylib "$MACOS_BIN" 2>/dev/null || true
72
73 echo ""
74 echo "Step 2: Running dylibbundler for ALL dependencies..."
75 # Use -of to overwrite and fix ALL dylibs recursively
76 dylibbundler -of -b \
77 -x "$MACOS_BIN" \
78 -d "$FRAMEWORKS/" \
79 -p @executable_path/../Frameworks/ \
80 -s /usr/local/lib \
81 -s /opt/homebrew/lib \
82 -s /opt/homebrew/opt/gtk4/lib \
83 -s /opt/homebrew/opt/glib/lib \
84 -s /opt/homebrew/opt/pango/lib \
85 -s /opt/homebrew/opt/cairo/lib \
86 -s /opt/homebrew/opt/harfbuzz/lib \
87 -s /opt/homebrew/opt/gdk-pixbuf/lib \
88 -s /opt/homebrew/opt/graphene/lib \
89 -s /opt/homebrew/opt/libepoxy/lib \
90 -s /opt/homebrew/opt/gettext/lib \
91 -s /opt/homebrew/opt/fribidi/lib \
92 -s /opt/homebrew/opt/fontconfig/lib \
93 -s /opt/homebrew/opt/freetype/lib \
94 -s /opt/homebrew/opt/libpng/lib \
95 -s /opt/homebrew/opt/graphite2/lib \
96 -s /opt/homebrew/opt/pcre2/lib \
97 -s /opt/homebrew/opt/brotli/lib \
98 -s /opt/homebrew/opt/bzip2/lib \
99 -s /opt/homebrew/opt/zstd/lib 2>&1
100
101 echo ""
102 echo "Step 2.5: Fixing library interdependencies..."
103 # dylibbundler should have done this, but let's make sure all bundled libs reference each other correctly
104 for lib in "$FRAMEWORKS"/*.dylib; do
105 if [ -f "$lib" ]; then
106 # Fix any remaining /opt/homebrew references
107 install_name_tool -change /opt/homebrew/opt/glib/lib/libglib-2.0.0.dylib @executable_path/../Frameworks/libglib-2.0.0.dylib "$lib" 2>/dev/null || true
108 install_name_tool -change /opt/homebrew/opt/glib/lib/libgio-2.0.0.dylib @executable_path/../Frameworks/libgio-2.0.0.dylib "$lib" 2>/dev/null || true
109 install_name_tool -change /opt/homebrew/opt/glib/lib/libgobject-2.0.0.dylib @executable_path/../Frameworks/libgobject-2.0.0.dylib "$lib" 2>/dev/null || true
110 install_name_tool -change /opt/homebrew/opt/glib/lib/libgmodule-2.0.0.dylib @executable_path/../Frameworks/libgmodule-2.0.0.dylib "$lib" 2>/dev/null || true
111 install_name_tool -change /opt/homebrew/opt/cairo/lib/libcairo.2.dylib @executable_path/../Frameworks/libcairo.2.dylib "$lib" 2>/dev/null || true
112 install_name_tool -change /opt/homebrew/opt/cairo/lib/libcairo-gobject.2.dylib @executable_path/../Frameworks/libcairo-gobject.2.dylib "$lib" 2>/dev/null || true
113 install_name_tool -change /opt/homebrew/opt/pango/lib/libpango-1.0.0.dylib @executable_path/../Frameworks/libpango-1.0.0.dylib "$lib" 2>/dev/null || true
114 install_name_tool -change /opt/homebrew/opt/pango/lib/libpangocairo-1.0.0.dylib @executable_path/../Frameworks/libpangocairo-1.0.0.dylib "$lib" 2>/dev/null || true
115 install_name_tool -change /opt/homebrew/opt/gtk4/lib/libgtk-4.1.dylib @executable_path/../Frameworks/libgtk-4.1.dylib "$lib" 2>/dev/null || true
116 install_name_tool -change /opt/homebrew/opt/gettext/lib/libintl.8.dylib @executable_path/../Frameworks/libintl.8.dylib "$lib" 2>/dev/null || true
117 install_name_tool -change /opt/homebrew/opt/harfbuzz/lib/libharfbuzz.0.dylib @executable_path/../Frameworks/libharfbuzz.0.dylib "$lib" 2>/dev/null || true
118 install_name_tool -change /opt/homebrew/opt/fribidi/lib/libfribidi.0.dylib @executable_path/../Frameworks/libfribidi.0.dylib "$lib" 2>/dev/null || true
119 install_name_tool -change /opt/homebrew/opt/fontconfig/lib/libfontconfig.1.dylib @executable_path/../Frameworks/libfontconfig.1.dylib "$lib" 2>/dev/null || true
120 install_name_tool -change /opt/homebrew/opt/freetype/lib/libfreetype.6.dylib @executable_path/../Frameworks/libfreetype.6.dylib "$lib" 2>/dev/null || true
121 install_name_tool -change /opt/homebrew/opt/gdk-pixbuf/lib/libgdk_pixbuf-2.0.0.dylib @executable_path/../Frameworks/libgdk_pixbuf-2.0.0.dylib "$lib" 2>/dev/null || true
122 install_name_tool -change /opt/homebrew/opt/graphene/lib/libgraphene-1.0.0.dylib @executable_path/../Frameworks/libgraphene-1.0.0.dylib "$lib" 2>/dev/null || true
123 install_name_tool -change /opt/homebrew/opt/libepoxy/lib/libepoxy.0.dylib @executable_path/../Frameworks/libepoxy.0.dylib "$lib" 2>/dev/null || true
124 fi
125 done
126
127 echo " Fixing library ID names..."
128 # Also fix the library ID names themselves
129 for lib in "$FRAMEWORKS"/*.dylib; do
130 if [ -f "$lib" ]; then
131 libname=$(basename "$lib")
132 install_name_tool -id @executable_path/../Frameworks/"$libname" "$lib" 2>/dev/null || true
133 fi
134 done
135
136 echo ""
137 echo "Step 3: Verifying bundle..."
138 TOTAL_LIBS=$(ls -1 "$FRAMEWORKS" | wc -l | tr -d ' ')
139 echo "Total libraries bundled: $TOTAL_LIBS"
140
141 # Check for critical libraries
142 echo ""
143 echo "Critical libraries check:"
144 for lib in libgtk-4 libglib-2.0 libgtk-4-fortran libcairo libpango; do
145 if ls "$FRAMEWORKS"/${lib}* 1> /dev/null 2>&1; then
146 echo " ✓ ${lib}"
147 else
148 echo " ✗ ${lib} MISSING!"
149 fi
150 done
151
152 echo ""
153 echo "Step 4: Checking binary dependencies..."
154 otool -L "$MACOS_BIN" | grep -E "(gtk|glib|cairo)" | head -5
155
156 echo ""
157 echo "=== Bundling Complete ==="