forked from Mirrors/openclonk
OSX: Bundle libraries even when not compiling with XCode
We have half-arsed support for building Darwin executables with Unix tools instead of XCode. Make it slightly more whole-arsed.issue1247
parent
d44d7ba33e
commit
2e1bdd742f
|
@ -1241,9 +1241,6 @@ if (APPLE)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++0x -g -Wall -fobjc-arc")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++0x -g -Wall -fobjc-arc")
|
||||||
|
|
||||||
if(CMAKE_GENERATOR STREQUAL Xcode)
|
if(CMAKE_GENERATOR STREQUAL Xcode)
|
||||||
add_custom_command(TARGET openclonk
|
|
||||||
POST_BUILD COMMAND "/usr/bin/ruby" "${CMAKE_CURRENT_SOURCE_DIR}/tools/osx_bundle_libs"
|
|
||||||
)
|
|
||||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES)
|
set(CMAKE_XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES)
|
||||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/C4Include.h")
|
set(CMAKE_XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/src/C4Include.h")
|
||||||
set_target_properties(openclonk PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES)
|
set_target_properties(openclonk PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES)
|
||||||
|
@ -1263,6 +1260,12 @@ if (APPLE)
|
||||||
set_target_properties(c4group PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++0x objective-c++0x")
|
set_target_properties(c4group PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++0x objective-c++0x")
|
||||||
set_target_properties(openclonk PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++0x objective-c++0x")
|
set_target_properties(openclonk PROPERTIES XCODE_ATTRIBUTE_GCC_PFE_FILE_C_DIALECTS "c++0x objective-c++0x")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_custom_command(TARGET openclonk
|
||||||
|
POST_BUILD COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/osx_bundle_libs"
|
||||||
|
"$<TARGET_FILE:openclonk>"
|
||||||
|
)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
|
@ -1,33 +1,88 @@
|
||||||
#!/usr/bin/env ruby
|
#!/bin/bash
|
||||||
|
|
||||||
# Bundle all the libraries, no matter their potential existence on pristine OSX installations
|
set -e
|
||||||
$libs_to_bundle=".*?/lib(jpeg|GLEW|llvm|SDL|SDL_mixer|freetype|ogg|vorbis|vorbisfile|z\.|png[0-9]*|iconv|alut)\.[^ ]+\.dylib"
|
|
||||||
$executable_path = ENV['EXECUTABLE_PATH']
|
|
||||||
$frameworks_folder_path = ENV['FRAMEWORKS_FOLDER_PATH']
|
|
||||||
|
|
||||||
Dir.chdir ENV['TARGET_BUILD_DIR'] if ENV['TARGET_BUILD_DIR']
|
# Grab information about the bundle from the environment (if XCode) or make
|
||||||
puts "Bundling libraries..."
|
# 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}"
|
||||||
|
|
||||||
def bundle_dependencies(executable_path)
|
# Get tool names/paths from the environment in case we're cross compiling
|
||||||
`otool -L #{executable_path} | grep -Eo "#{$libs_to_bundle}" | grep -v "@executable_path.*"`.each_line do |lib|
|
_otool="${OTOOL:-otool}"
|
||||||
lib.strip!
|
_install_name_tool="${INSTALL_NAME_TOOL:-install_name_tool}"
|
||||||
break if not File.exists? lib
|
|
||||||
puts "Bundling #{lib}"
|
|
||||||
base = `basename #{lib}`.strip
|
|
||||||
bundle_path = "#{$frameworks_folder_path}/#{base}"
|
|
||||||
already_bundled = File.exists? bundle_path
|
|
||||||
id = "@executable_path/../Frameworks/#{base}"
|
|
||||||
if not already_bundled then
|
|
||||||
puts "Bundling #{base}..."
|
|
||||||
`cp #{lib} #{bundle_path}`
|
|
||||||
`chmod u+w #{bundle_path}`
|
|
||||||
end
|
|
||||||
`install_name_tool -id #{id} #{bundle_path}`
|
|
||||||
`install_name_tool -change #{lib} #{id} #{$executable_path}`
|
|
||||||
`install_name_tool -change #{lib} #{id} #{executable_path}` if $executable_path != executable_path
|
|
||||||
bundle_dependencies bundle_path if not already_bundled
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
`mkdir -p #{$frameworks_folder_path}`
|
# This regexp should match every lib we want to bundle.
|
||||||
bundle_dependencies $executable_path
|
_libs_to_bundle=".*?/lib(jpeg|GLEW|llvm|SDL|SDL_mixer|freetype|ogg|vorbis|vorbisfile|z\.|png[0-9]*|iconv|alut)\.[^ ]+\.dylib"
|
||||||
|
|
||||||
|
if [ -n "${TARGET_BUILD_DIR}" ]; then
|
||||||
|
cd "${TARGET_BUILD_DIR}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Bundling libraries..."
|
||||||
|
|
||||||
|
bundle_dependencies() {
|
||||||
|
_object_path="$1"
|
||||||
|
"${_otool}" -L "${_object_path}" | \
|
||||||
|
grep -Eo -- "${_libs_to_bundle}" | \
|
||||||
|
grep -v '@executable_path.*' | \
|
||||||
|
while read _library_name; do
|
||||||
|
_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
|
||||||
|
# Stop bundling if a lib doesn't exist
|
||||||
|
if [ ! -e "${_library_path}" ]; then
|
||||||
|
echo "Cannot find ${_library_name}." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_base="$(basename "${_library_name}")"
|
||||||
|
_bundle_path="${_frameworks_folder_path}/${_base}"
|
||||||
|
|
||||||
|
_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}"
|
||||||
|
|
Loading…
Reference in New Issue