polserver/bin-build/brew-universalize
Kevin Eady 7a4faf1786
Add support for building universal binaries for macOS (#572)
* universal binaries for src and prebuilt deps

* Rebuild antlr from cache?

* Recache everything

* universalize libssh2

* Pin brew-universalize versions

* Better handling of cxxflags for boost

* Correctly handle cmake message

* Store brew-universalize in bin-build

* Standardize cache keys

* No clue on this compiler flag

* Lets try this boost cxxflag
2023-12-06 22:36:42 +01:00

110 lines
3.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# This tool is used to create universal binaries of Homebrew-installed shared
# libraries. This is needed to build universal (x86_64 and arm64) binaries on
# macOS.
set -e
for COMMAND_DEPENDENCY in "jq" "wget"; do
if ! command -v $COMMAND_DEPENDENCY &> /dev/null; then
printf "'$COMMAND_DEPENDENCY' could not be found. Install via: brew install $COMMAND_DEPENDENCY\n" >&2
exit 1
fi
done
MACOS_VERSION=$(/usr/bin/sw_vers -productVersion)
case $MACOS_VERSION in
14.*) MACOS_RELEASE="sonoma" ;;
13.*) MACOS_RELEASE="ventura" ;;
12.*) MACOS_RELEASE="monterey" ;;
11.*) MACOS_RELEASE="big_sur" ;;
10.15.*) MACOS_RELEASE="catalina" ;;
10.14.*) MACOS_RELEASE="mojave" ;;
10.13.*) MACOS_RELEASE="high_sierra" ;;
10.12.*) MACOS_RELEASE="sierra" ;;
10.11.*) MACOS_RELEASE="el_capitan" ;;
esac
if [ -z "$MACOS_RELEASE" ]; then
printf "Cannot get macOS release from version: $MACOS_VERSION\n" >&2
exit 1
fi
HOMEBREW_PREFIX=$(brew --prefix)
ARCH_THIS=$(uname -m)
if [ "$ARCH_THIS" == "arm64" ]; then
ARCH_OTHER=x86_64
HOMEBREW_PREFIX_OTHER=/usr/local
DOWNLOAD_PROPERTY=$MACOS_RELEASE
else
ARCH_OTHER=arm64
HOMEBREW_PREFIX_OTHER=/opt/homebrew
DOWNLOAD_PROPERTY="arm64_$MACOS_RELEASE"
fi
HOMEBREW_CELLAR_OTHER=$HOMEBREW_PREFIX_OTHER/Cellar
WORK_DIR=$(mktemp -d)
echo "Homebrew prefix: $HOMEBREW_PREFIX"
echo "macOS release: $MACOS_RELEASE [$ARCH_THIS]"
echo "brew info download property: $DOWNLOAD_PROPERTY"
echo "Work directory: $WORK_DIR"
DOWNLOAD_URLS=$(brew info --json $@ | jq -r '.[] | .bottle.stable.files[. = "'$DOWNLOAD_PROPERTY'"].url')
echo "$DOWNLOAD_URLS" | wget --no-verbose -P $WORK_DIR --header "Authorization: Bearer QQ==" -i -
for DOWNLOAD_URL in $DOWNLOAD_URLS; do
tar xfz $WORK_DIR/$(basename $DOWNLOAD_URL) -C $WORK_DIR
done
for MERGING_LIB in $(find $WORK_DIR -iname '*.dylib' -type f); do
EXISTING_LIB="${MERGING_LIB/$WORK_DIR/$HOMEBREW_PREFIX/Cellar}"
MERGING_ARCH=$(lipo -archs $MERGING_LIB)
if [ ! -f $EXISTING_LIB ]; then
echo "$EXISTING_LIB does not exist to merge $MERGING_LIB [$MERGING_ARCH]"
continue
fi
EXISTING_ARCH=$(lipo -archs $EXISTING_LIB)
if [ "$EXISTING_ARCH" = "x86_64 arm64" ]; then
echo "$EXISTING_LIB [$EXISTING_ARCH] -> already universal"
continue
fi
BACKUP_FILENAME=${EXISTING_LIB%.dylib}.$EXISTING_ARCH.dylib
echo "$EXISTING_LIB [$EXISTING_ARCH] -> $BACKUP_FILENAME and merging $MERGING_LIB [$MERGING_ARCH]"
if [ ! -f $BACKUP_FILENAME ]; then
cp $EXISTING_LIB $BACKUP_FILENAME
fi
INSTALL_NAME_TOOL_ARGS=""
for DEP_LIB_FILENAME in $(otool -L -arch $ARCH_OTHER $MERGING_LIB | grep -Eo '@@HOMEBREW_(PREFIX|CELLAR)@@\S+'); do
NEW_DEP_LIB_FILENAME=${DEP_LIB_FILENAME/@@HOMEBREW_PREFIX@@/$HOMEBREW_PREFIX_OTHER}
NEW_DEP_LIB_FILENAME=${NEW_DEP_LIB_FILENAME/@@HOMEBREW_CELLAR@@/$HOMEBREW_CELLAR_OTHER}
if [ "$(basename $NEW_DEP_LIB_FILENAME)" == "$(basename $MERGING_LIB)" ]; then
INSTALL_NAME_TOOL_ARGS+="-id $NEW_DEP_LIB_FILENAME "
else
INSTALL_NAME_TOOL_ARGS+="-change $DEP_LIB_FILENAME $NEW_DEP_LIB_FILENAME "
fi
done
if [ ${#INSTALL_NAME_TOOL_ARGS} -ne 0 ]; then
install_name_tool $INSTALL_NAME_TOOL_ARGS $MERGING_LIB
fi
lipo -create $BACKUP_FILENAME $MERGING_LIB -output $EXISTING_LIB
codesign -s - $EXISTING_LIB || true
done
rm -rf $WORK_DIR