macOS script to build the universal app bundle.
1. Build TuxPaint.app on Intel macOS, rename it TuxPaint-x86_64.app.
2. Build TuxPaint.app on Apple Silicon macOS, rename it TuxPaint-arm64.app.
3. Copy TuxPaint-x86_64.app to the same directory as TuxPaint-arm64.app
on the Apple Silicon macOS, then run:
macos/build-universal.sh TuxPaint-x86_64.app TuxPaint-arm64.app
... to produce TuxPaint.app that's universal.
4. `make TuxPaint.dmg` to produce TuxPaint.dmg from the universal
TuxPaint.app.
This commit is contained in:
parent
c239e849cb
commit
e5faf36d5d
1 changed files with 142 additions and 0 deletions
142
macos/build-universal.sh
Executable file
142
macos/build-universal.sh
Executable file
|
|
@ -0,0 +1,142 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
function usage() {
|
||||
cat <<EOF
|
||||
Build a macOS universal application bundle from one or more application
|
||||
bundles.
|
||||
|
||||
Usage: ${SCRIPTNAME} [OPTIONS] TuxPaint-1.app TuxPaint-2.app ...
|
||||
|
||||
TuxPaint-N.app Bundle(s) to read. If no bundles are specified, the
|
||||
following files are read:
|
||||
$(
|
||||
for bundle in "${BUNDLES[@]}"; do
|
||||
printf "\n%26s%s" "" "$bundle"
|
||||
done
|
||||
)
|
||||
|
||||
-o OUTBUNDLE Bundle to create. [Default=${OUTBUNDLE}]
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
##############################################################################
|
||||
# CONFIG
|
||||
|
||||
ARCHS=( arm64 x86_64 )
|
||||
BUNDLES=( $(printf "TuxPaint-%s.app\n" "${ARCHS[@]}") )
|
||||
OUTBUNDLE=TuxPaint.app
|
||||
FORCE=0
|
||||
|
||||
|
||||
##############################################################################
|
||||
# PROGRAM BEGINS HERE
|
||||
|
||||
function main() {
|
||||
local OPTIND OPTARG OPTERR opt
|
||||
local bundle
|
||||
local isok=1
|
||||
|
||||
# Process arguments
|
||||
while getopts "fo:h" opt; do
|
||||
case "$opt" in
|
||||
f) FORCE=1 ;;
|
||||
o) OUTBUNDLE=$OPTARG ;;
|
||||
h) usage && exit 0 ;;
|
||||
*) isok=0
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
# Use the specified bundles
|
||||
if (( $# )); then
|
||||
BUNDLES=( "$@" )
|
||||
fi
|
||||
|
||||
# Sanity check
|
||||
if (( ! isok )); then
|
||||
usage 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Status
|
||||
echo " * Creating universal app bundle $OUTBUNDLE by combining ${BUNDLES[*]}..."
|
||||
|
||||
# Validate input
|
||||
for bundle in "${BUNDLES[@]}"; do
|
||||
if ! [[ -d "$bundle" ]]; then
|
||||
printf " -> FAILED: No such input bundle named %s exists\n" "$bundle" 1>&2
|
||||
isok=0
|
||||
fi
|
||||
done
|
||||
(( isok)) || exit 1
|
||||
|
||||
# Validate output
|
||||
if [[ -d "$OUTBUNDLE" ]] && (( FORCE )); then
|
||||
printf " -> Deleting %s...\n" "$OUTBUNDLE"
|
||||
rm -rf "$OUTBUNDLE" || exitcode=1
|
||||
elif [[ -d "$OUTBUNDLE" ]]; then
|
||||
printf " -> FAILED: Output bundled named %s already exists, use -f option to recreate.\n" "$OUTBUNDLE" 1>&2
|
||||
isok=0
|
||||
fi
|
||||
(( isok )) || exit 1
|
||||
|
||||
build-universal
|
||||
}
|
||||
|
||||
|
||||
function build-universal() {
|
||||
local isok=1
|
||||
local i j
|
||||
|
||||
# Create the base package without binaries or libraries
|
||||
echo " -> Create skeleton app bundle ${OUTBUNDLE}..." \
|
||||
&& cp -a "${BUNDLES[0]}" "$OUTBUNDLE" \
|
||||
&& rm -f "${OUTBUNDLE}/Contents/MacOS"/* \
|
||||
&& find "$OUTBUNDLE" -name '*.dylib' -print0 | xargs -0 rm -f \
|
||||
|| return 1
|
||||
|
||||
# Create the universal binary for each binary and library
|
||||
for (( i=0; i < ${#BUNDLES[@]}; i++ )); do
|
||||
local filelist=()
|
||||
local file
|
||||
|
||||
# Binaries
|
||||
for file in "${BUNDLES[i]}/Contents/MacOS"/*; do
|
||||
filelist+=( "${file#${BUNDLES[i]}/}" )
|
||||
done
|
||||
|
||||
# Dynamic Libraries
|
||||
while IFS= read -r file; do
|
||||
filelist+=( "${file#${BUNDLES[i]}/}" )
|
||||
done < <(find "${BUNDLES[i]}" -name '*.dylib')
|
||||
|
||||
# Build each as universal
|
||||
for file in "${filelist[@]}"; do
|
||||
local instances=()
|
||||
|
||||
# Skip if already built
|
||||
[[ -e "${OUTBUNDLE}/${file}" ]] && continue
|
||||
|
||||
# Get this file's instances in all bundles
|
||||
for (( j=i; j < ${#BUNDLES[@]}; j++ )); do
|
||||
if [[ -e "${BUNDLES[j]}/${file}" ]]; then
|
||||
instances+=( "${BUNDLES[j]}/${file}" )
|
||||
fi
|
||||
done
|
||||
|
||||
# Build into $OUTBUNDLE
|
||||
echo " -> Combine ${file}..."
|
||||
lipo -create -output "${OUTBUNDLE}/${file}" "${instances[@]}" || isok=0
|
||||
done
|
||||
done
|
||||
|
||||
(( isok ))
|
||||
}
|
||||
|
||||
|
||||
##############################################################################
|
||||
# ENTRY POINT
|
||||
|
||||
main "$@"
|
||||
Loading…
Add table
Add a link
Reference in a new issue