openclonk/tools/osx_bundle_libs

127 lines
3.5 KiB
Bash

#!/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
# Skip system libraries, e.g. libraries in /usr/lib,
# as well as any system frameworks.
if echo ${_library_path} | egrep -q "(^/usr/lib|^${_sysroot}/usr/lib|/System/Library/Frameworks)"; then
continue
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}"