#!/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 resign-bundle } 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 version of 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 )) } function resign-bundle() { echo " * Sign $OUTBUNDLE..." codesign --remove-signature "$OUTBUNDLE" codesign -s "$IDENTITY" "$OUTBUNDLE" echo " -> Done!" } ############################################################################## # ENTRY POINT main "$@"