diff --git a/macos/build-universal.sh b/macos/build-universal.sh new file mode 100755 index 000000000..536da3c97 --- /dev/null +++ b/macos/build-universal.sh @@ -0,0 +1,142 @@ +#!/usr/bin/env bash + +function usage() { + cat <&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 "$@"