Files
fiv/macos-install.sh
Přemysl Eric Janouch 690e60cd74
All checks were successful
Alpine 3.22 Success
Arch Linux Success
Arch Linux AUR Success
Debian Bookworm Success
Fedora 39 Success
OpenBSD 7.8 Success
openSUSE 15.5 Success
Build an application bundle on macOS
This is far from done, but nonetheless constitutes a big improvement.

macOS application bundles are more or less necessary for:
 - showing a nice icon;
 - having spawned off instances actually be brought to the foreground;
 - file associations (yet files currently do not open properly);
 - having a reasonable method of distribution.

Also resolving a bunch of minor issues:
 - The context menu had duplicate items,
   and might needlessly end up with (null) labels.
2025-11-11 19:28:45 +01:00

116 lines
3.8 KiB
Bash
Executable File

#!/bin/sh -e
export LC_ALL=C
cd "$MESON_INSTALL_DESTDIR_PREFIX"
# Input: Half-baked application bundle linked against Homebrew.
# Output: Portable application bundle.
source=/opt/homebrew
bindir=Contents/MacOS
libdir=Contents/Resources/lib
datadir=Contents/Resources/share
mkdir -p "$datadir"/glib-2.0/schemas
cp -p "$source"/share/glib-2.0/schemas/org.gtk.Settings.* \
"$datadir"/glib-2.0/schemas
mkdir -p "$datadir"/icons
cp -pRL "$source"/share/icons/Adwaita "$datadir/"icons
mkdir -p "$datadir"/icons/hicolor
cp -p "$source"/share/icons/hicolor/index.theme "$datadir"/icons/hicolor
mkdir -p "$datadir/mime"
# GIO doesn't use the database on macOS, this subset is for us.
find "$source"/share/mime/ -maxdepth 1 -type f -exec cp -p {} "$datadir"/mime \;
# Copy binaries we directly or indirectly depend on.
#
# Homebrew is a bit chaotic in that some libraries are linked against locations
# in /opt/homebrew/Cellar, and some against /opt/homebrew/opt symlinks.
# We'll process things in such a way that it does not matter.
#
# As a side note, libraries in /usr/lib are now actually being served from
# a shared cache by the dynamic linker and aren't visible on the filesystem.
# There is an alternative to "otool -L" which can see them but it isn't
# particularly nicer to parse: "dyld_info -dependents/-linked_dylibs".
rm -rf "$libdir"
mkdir -p "$libdir"
pixbufdir=$libdir/gdk-pixbuf-2.0
loadersdir=$pixbufdir/loaders
cp -RL "$source"/lib/gdk-pixbuf-2.0/* "$pixbufdir"
# Fix a piece of crap loader that needs to be special.
svg=$loadersdir/libpixbufloader_svg.so
rm -f "$loadersdir"/libpixbufloader_svg.dylib
otool -L "$svg" | grep -o '@rpath/[^ ]*' | while IFS= read -r bad
do install_name_tool -change "$bad" "$source/lib/$(basename "$bad")" "$svg"
done
GDK_PIXBUF_MODULEDIR=$loadersdir gdk-pixbuf-query-loaders \
| sed "s,$libdir,@rpath," > "$pixbufdir/loaders.cache"
gtkdir=$libdir/gtk-3.0
printbackendsdir=$gtkdir/printbackends
cp -RL "$source"/lib/gtk-3.0/* "$gtkdir"
# TODO: Figure out how to make gtk-query-immodules-3.0 pick up exactly
# what it needs to. So far I'm not sure if this is at all even useful.
rm -rf "$gtkdir"/immodules*
find "$bindir" "$loadersdir" "$printbackendsdir" -type f -maxdepth 1 | awk '
function collect(binary, command, line) {
if (seen[binary]++)
return
command = "otool -L \"" binary "\""
while ((command | getline line) > 0)
if (match(line, /^\t\/opt\/.+ \(/))
collect(substr(line, RSTART + 1, RLENGTH - 3))
close(command)
} {
collect($0)
delete seen[$0]
} END {
for (library in seen)
print library
}
' | while IFS= read -r binary
do test -f "$libdir/$(basename "$binary")" || cp "$binary" "$libdir"
done
# Now redirect all binaries to internal linking.
# A good overview of how this works is "man dyld" and:
# https://itwenty.me/posts/01-understanding-rpath/
rewrite() {
otool -L "$1" | sed -n 's,^\t\(.*\) (.*,\1,p' | grep '^/opt/' \
| while IFS= read -r lib
do install_name_tool -change "$lib" "@rpath/$(basename "$lib")" "$1"
done
}
find "$bindir" -type f -maxdepth 1 | while IFS= read -r binary
do
install_name_tool -add_rpath @executable_path/../Resources/lib "$binary"
rewrite "$binary"
done
find "$libdir" -type f \( -name '*.so' -o -name '*.dylib' \) \
| while IFS= read -r binary
do
chmod 644 "$binary"
install_name_tool -id "@rpath/${binary#$libdir/}" "$binary"
rewrite "$binary"
# Discard pointless @loader_path/../lib and absolute Homebrew paths.
otool -l "$binary" | awk '
$1 == "cmd" { command = $2 }
command == "LC_RPATH" && $1 == "path" { print $2 }
' | xargs -R 1 -I % install_name_tool -delete_rpath % "$binary"
# Replace freshly invalidated code signatures with ad-hoc ones.
codesign --force --sign - "$binary"
done
glib-compile-schemas "$datadir"/glib-2.0/schemas
# This may speed up program start-up a little bit.
gtk-update-icon-cache "$datadir"/icons/Adwaita