#!/bin/bash set -e _sysroot="${SYSROOT}" # Collect options from the command line for i in "$@"; do case "$i" in --sysroot=*) _sysroot="${i#*=}" shift ;; --) shift break ;; --*) echo "$0: Unknown option: $i" >&2 exit 1 ;; *) break ;; esac done # Grab information about the bundle from the environment (if XCode) or make # assumptions about the bundle layout (everywhere else) _executable_path="${EXECUTABLE_PATH:-$1}" if [ -n "${WRAPPER_NAME}" ]; then _wrapper_name="${WRAPPER_NAME}" else _wrapper_name="${_executable_path%.app/*}" if [ "${_wrapper_name}" == "${_executable_path}" ]; then echo "Unable to derive bundle location from '${_wrapper_name}'!" >&2 exit 1 fi _wrapper_name="${_wrapper_name}.app" fi _contents_folder="${CONTENTS_FOLDER_PATH:-${_wrapper_name}/Contents}" _frameworks_folder_path="${FRAMEWORKS_FOLDER_PATH:-${_contents_folder}/Frameworks}" # Get tool names/paths from the environment in case we're cross compiling _otool="${OTOOL:-otool}" _install_name_tool="${INSTALL_NAME_TOOL:-install_name_tool}" if [ -n "${TARGET_BUILD_DIR}" ]; then cd "${TARGET_BUILD_DIR}" fi echo "Bundling libraries..." bundle_dependencies() { local _object_path="$1" local _library_name "${_otool}" -L "${_object_path}" | \ awk '/^\t+\// { print $1 }' | \ grep -v '@executable_path.*' | \ while read _library_name; do local _library_path="${_library_name}" # If the library isn't available at the stored path, it may be # stored inside the sysroot (when cross-compiling for example) if [ ! -e "${_library_path}" -a -n "${_sysroot}" ]; then _library_path="${_sysroot}${_library_path}" fi # If the library still isn't available there, there might be a YAML # stub instead in more recent SDKs; if we find one of those, the # library is part of the base install and doesn't need to be bundled local _stub_path="${_library_path%.dylib}.tbd" if [ ! -e "${_library_path}" -a -e "${_stub_path}" ]; then continue fi # Stop bundling if a lib doesn't exist if [ ! -e "${_library_path}" ]; then echo "Cannot find ${_library_name}." >&2 exit 1 fi local _base="$(basename "${_library_name}")" local _bundle_path="${_frameworks_folder_path}/${_base}" local _id="@executable_path/../Frameworks/${_base}" # Skip if it's a library stub (because we can't change the install name # of those anyway) if file -b "${_library_path}" | grep -q 'shared library stub'; then continue fi # Change the depender reference unconditionally "${_install_name_tool}" -change "${_library_name}" "${_id}" "${_object_path}" # Don't fixup this lib if it is already bundled - no point in doing the # same work multiple times [ -e "${_bundle_path}" ] && continue echo "Bundling '${_library_path}' as '${_base}'..." cp "${_library_path}" "${_bundle_path}" chmod u+w "${_bundle_path}" # Set a new install name for this dylib "${_install_name_tool}" -id "${_id}" "${_bundle_path}" # Also change the reference inside the application itself if [ "${_executable_path}" != "${_object_path}" ]; then "${_install_name_tool}" -change "${_library_name}" "${_id}" "${_executable_path}" fi # And also recursively bundle the dependencies of this dependency. bundle_dependencies "${_bundle_path}" done } mkdir -p "${_frameworks_folder_path}" bundle_dependencies "${_executable_path}"