From 958f6626afe3ee0f1a035b9b9ed57a1c65a38028 Mon Sep 17 00:00:00 2001 From: Gennady Pospelov <g.pospelov@fz-juelich.de> Date: Tue, 11 Nov 2014 23:35:52 +0100 Subject: [PATCH] Refactoring in cmake::FixAppleBundle --- CMakeLists.txt | 3 + GUI/main/CMakeLists.txt | 64 ++- ...s.cmake => BundleUtilitiesWithRPath.cmake} | 445 ++++++++---------- cmake/modules/FixBundle.cmake.in | 109 +++++ ....cmake => GetPrerequisitesWithRPath.cmake} | 306 ++++++------ cmake/modules/bundle.cmake.in | 21 + 6 files changed, 535 insertions(+), 413 deletions(-) rename cmake/modules/{BABundleUtilities.cmake => BundleUtilitiesWithRPath.cmake} (73%) create mode 100644 cmake/modules/FixBundle.cmake.in rename cmake/modules/{GetPrerequisites.cmake => GetPrerequisitesWithRPath.cmake} (77%) create mode 100644 cmake/modules/bundle.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 80bf158f677..27c07ac1b5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ option(BORNAGAIN_RELEASE "Special option for making release" OFF) option(BORNAGAIN_CRASHHADLER "Additional machinery to send crash reports" OFF) + #--- Including macros --- set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules) include(BornAgainMacros) @@ -38,6 +39,8 @@ if(BORNAGAIN_MAN) add_subdirectory(Doc/UserManual) endif() +set(CMAKE_MACOSX_RPATH 1) + add_subdirectory(Core) add_subdirectory(ThirdParty/gtest) add_subdirectory(Tests/UnitTests/TestCore) diff --git a/GUI/main/CMakeLists.txt b/GUI/main/CMakeLists.txt index d3316322abe..6c600d8c066 100644 --- a/GUI/main/CMakeLists.txt +++ b/GUI/main/CMakeLists.txt @@ -107,15 +107,18 @@ IF(APPLE AND CREATE_BUNDLE) get_filename_component(qcustomplot_LIBRARY_DIR "${qcustomplot_LIBRARY}" REALPATH) get_filename_component(qtpropertybrowser_LIBRARY_DIR "${qtpropertybrowser_LIBRARY}" REALPATH) get_filename_component(Boost_Real_LIBRARY_DIR "${Boost_LIBRARY_DIR}" REALPATH) -# get_filename_component(PYTHON_LIBRARY_DIR "${PYTHON_REAL_LIBRARY}" PATH) +# get_filename_component(PYTHON_LIBRARY_DIR "${PYTHON_LIBRARIES}" REALPATH) + get_filename_component(PYTHON_REAL_LIBRARY_DIR "${PYTHON_LIBRARY}" REALPATH) -# message("PYTHON_LIBRARY_DIR: ${PYTHON_LIBRARY_DIR}") + message("OOO PYTHON_LIBRARY_DIR: ${PYTHON_LIBRARY_DIR} PYTHON_LIBRARY:${PYTHON_LIBRARY} PYTHON_LIBRARIES:${PYTHON_LIBRARIES}") + message("OOO2 PYTHON_REAL_LIBRARY_DIR:${PYTHON_REAL_LIBRARY_DIR}") + message("OOO3 CMAKE_LIBRARY_OUTPUT_DIRECTORY:${CMAKE_LIBRARY_OUTPUT_DIRECTORY} CMAKE_LIBRARY_PATH:${CMAKE_LIBRARY_PATH}") set(DIRS - ${ManhattanStyle_LIBRARY_DIR} - ${qcustomplot_LIBRARY_DIR} - ${qtpropertybrowser_LIBRARY_DIR} -# ${PYTHON_LIBRARY_DIR} +# ${ManhattanStyle_LIBRARY_DIR} +# ${qcustomplot_LIBRARY_DIR} +# ${qtpropertybrowser_LIBRARY_DIR} + ${PYTHON_REAL_LIBRARY_DIR} ${Boost_Real_LIBRARY_DIR} "${CMAKE_BINARY_DIR}/lib" "$ENV{QTDIR}" @@ -127,25 +130,36 @@ IF(APPLE AND CREATE_BUNDLE) BUNDLE DESTINATION . COMPONENT Applications RUNTIME DESTINATION ${destination_bin} COMPONENT Runtime) - install(DIRECTORY "$ENV{QTDIR}/plugins/platforms" DESTINATION ${plugin_dest_dir} COMPONENT Runtime) - - set(qtconf_text " -[Paths] -Plugins = PlugIns - ") - - install(CODE " - file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"${qtconf_text}\") - " COMPONENT Runtime) - - install(CODE " - file(GLOB_RECURSE QTPLUGINS - \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\") - set(BU_CHMOD_BUNDLE_ITEMS True) - set(BU_COPY_FULL_FRAMEWORK_CONTENTS False) - include(${CMAKE_MODULE_PATH}/BABundleUtilities.cmake) - fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\") - " COMPONENT Runtime) + +# install(DIRECTORY "$ENV{QTDIR}/plugins/platforms" DESTINATION ${plugin_dest_dir} COMPONENT Runtime) + +# set(qtconf_text " +#[Paths] +#Plugins = PlugIns +# ") + +# install(CODE " +# file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"${qtconf_text}\") +# " COMPONENT Runtime) + +# install(CODE " +# file(GLOB_RECURSE QTPLUGINS +# \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\") +# set(BU_CHMOD_BUNDLE_ITEMS True) +# set(BU_COPY_FULL_FRAMEWORK_CONTENTS False) +# include(${CMAKE_MODULE_PATH}/BABundleUtilities.cmake) +# fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\") +# " COMPONENT Runtime) + +# configure_file(${CMAKE_SOURCE_DIR}/cmake/modules/bundle.cmake.in ${CMAKE_BINARY_DIR}/bundle.cmake @ONLY) +# install(SCRIPT ${CMAKE_BINARY_DIR}/bundle.cmake COMPONENT Runtime) + + set(fixup_path @rpath) + configure_file(${CMAKE_SOURCE_DIR}/cmake/modules/FixBundle.cmake.in ${CMAKE_BINARY_DIR}/FixBundle.cmake @ONLY) + install(SCRIPT ${CMAKE_BINARY_DIR}/FixBundle.cmake COMPONENT Runtime) + +# include(BundleUtilities) +# fixup_bundle(${CMAKE_INSTALL_PREFIX}/BornAgain.app "" "") else() install (TARGETS ${executable_name} DESTINATION ${destination_bin} COMPONENT Applications) diff --git a/cmake/modules/BABundleUtilities.cmake b/cmake/modules/BundleUtilitiesWithRPath.cmake similarity index 73% rename from cmake/modules/BABundleUtilities.cmake rename to cmake/modules/BundleUtilitiesWithRPath.cmake index e9d5242d30a..9a7586590de 100644 --- a/cmake/modules/BABundleUtilities.cmake +++ b/cmake/modules/BundleUtilitiesWithRPath.cmake @@ -1,207 +1,154 @@ -#.rst: -# BundleUtilities -# --------------- -# -# Functions to help assemble a standalone bundle application. -# +# - Functions to help assemble a standalone bundle application. # A collection of CMake utility functions useful for dealing with .app # bundles on the Mac and bundle-like directories on any OS. # # The following functions are provided by this module: -# -# :: -# -# fixup_bundle -# copy_and_fixup_bundle -# verify_app -# get_bundle_main_executable -# get_dotapp_dir -# get_bundle_and_executable -# get_bundle_all_executables -# get_item_key -# clear_bundle_keys -# set_bundle_key_values -# get_bundle_keys -# copy_resolved_item_into_bundle -# copy_resolved_framework_into_bundle -# fixup_bundle_item -# verify_bundle_prerequisites -# verify_bundle_symlinks -# +# fixup_bundle +# copy_and_fixup_bundle +# verify_app +# get_bundle_main_executable +# get_dotapp_dir +# get_bundle_and_executable +# get_bundle_all_executables +# get_item_key +# clear_bundle_keys +# set_bundle_key_values +# get_bundle_keys +# copy_resolved_item_into_bundle +# copy_resolved_framework_into_bundle +# is_resolved_item_embedded +# fixup_bundle_item +# verify_bundle_prerequisites +# verify_bundle_symlinks # Requires CMake 2.6 or greater because it uses function, break and -# PARENT_SCOPE. Also depends on GetPrerequisites.cmake. -# -# :: -# -# FIXUP_BUNDLE(<app> <libs> <dirs>) +# PARENT_SCOPE. Also depends on GetPrerequisites.cmake. # +# FIXUP_BUNDLE(<app> <libs> <dirs>) # Fix up a bundle in-place and make it standalone, such that it can be -# drag-n-drop copied to another machine and run on that machine as long -# as all of the system libraries are compatible. -# -# If you pass plugins to fixup_bundle as the libs parameter, you should -# install them or copy them into the bundle before calling fixup_bundle. -# The "libs" parameter is a list of libraries that must be fixed up, but -# that cannot be determined by otool output analysis. (i.e., plugins) -# -# Gather all the keys for all the executables and libraries in a bundle, -# and then, for each key, copy each prerequisite into the bundle. Then -# fix each one up according to its own list of prerequisites. -# -# Then clear all the keys and call verify_app on the final bundle to -# ensure that it is truly standalone. -# -# :: +# drag-n-drop copied to another machine and run on that machine as long as all +# of the system libraries are compatible. # -# COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>) +# If you pass plugins to fixup_bundle as the libs parameter, you should install +# them or copy them into the bundle before calling fixup_bundle. The "libs" +# parameter is a list of libraries that must be fixed up, but that cannot be +# determined by otool output analysis. (i.e., plugins) # -# Makes a copy of the bundle <src> at location <dst> and then fixes up -# the new copied bundle in-place at <dst>... +# Gather all the keys for all the executables and libraries in a bundle, and +# then, for each key, copy each prerequisite into the bundle. Then fix each one +# up according to its own list of prerequisites. # -# :: +# Then clear all the keys and call verify_app on the final bundle to ensure +# that it is truly standalone. # -# VERIFY_APP(<app>) +# COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>) +# Makes a copy of the bundle <src> at location <dst> and then fixes up the +# new copied bundle in-place at <dst>... # -# Verifies that an application <app> appears valid based on running -# analysis tools on it. Calls "message(FATAL_ERROR" if the application -# is not verified. +# VERIFY_APP(<app>) +# Verifies that an application <app> appears valid based on running analysis +# tools on it. Calls "message(FATAL_ERROR" if the application is not verified. # -# :: +# GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>) +# The result will be the full path name of the bundle's main executable file +# or an "error:" prefixed string if it could not be determined. # -# GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>) -# -# The result will be the full path name of the bundle's main executable -# file or an "error:" prefixed string if it could not be determined. -# -# :: -# -# GET_DOTAPP_DIR(<exe> <dotapp_dir_var>) -# -# Returns the nearest parent dir whose name ends with ".app" given the -# full path to an executable. If there is no such parent dir, then -# simply return the dir containing the executable. +# GET_DOTAPP_DIR(<exe> <dotapp_dir_var>) +# Returns the nearest parent dir whose name ends with ".app" given the full +# path to an executable. If there is no such parent dir, then simply return +# the dir containing the executable. # # The returned directory may or may not exist. # -# :: -# -# GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>) -# +# GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>) # Takes either a ".app" directory name or the name of an executable # nested inside a ".app" directory and returns the path to the ".app" # directory in <bundle_var> and the path to its main executable in # <executable_var> # -# :: -# -# GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>) -# -# Scans the given bundle recursively for all executable files and -# accumulates them into a variable. -# -# :: -# -# GET_ITEM_KEY(<item> <key_var>) +# GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>) +# Scans the given bundle recursively for all executable files and accumulates +# them into a variable. # -# Given a file (item) name, generate a key that should be unique -# considering the set of libraries that need copying or fixing up to -# make a bundle standalone. This is essentially the file name including -# extension with "." replaced by "_" +# GET_ITEM_KEY(<item> <key_var>) +# Given a file (item) name, generate a key that should be unique considering +# the set of libraries that need copying or fixing up to make a bundle +# standalone. This is essentially the file name including extension with "." +# replaced by "_" # -# This key is used as a prefix for CMake variables so that we can -# associate a set of variables with a given item based on its key. +# This key is used as a prefix for CMake variables so that we can associate a +# set of variables with a given item based on its key. # -# :: +# CLEAR_BUNDLE_KEYS(<keys_var>) +# Loop over the list of keys, clearing all the variables associated with each +# key. After the loop, clear the list of keys itself. # -# CLEAR_BUNDLE_KEYS(<keys_var>) +# Caller of get_bundle_keys should call clear_bundle_keys when done with list +# of keys. # -# Loop over the list of keys, clearing all the variables associated with -# each key. After the loop, clear the list of keys itself. -# -# Caller of get_bundle_keys should call clear_bundle_keys when done with -# list of keys. -# -# :: -# -# SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs> -# <copyflag>) -# -# Add a key to the list (if necessary) for the given item. If added, +# SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs> +# <copyflag>) +# Add a key to the list (if necessary) for the given item. If added, # also set all the variables associated with that key. # -# :: -# -# GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>) -# -# Loop over all the executable and library files within the bundle (and -# given as extra <libs>) and accumulate a list of keys representing -# them. Set values associated with each key such that we can loop over -# all of them and copy prerequisite libs into the bundle and then do -# appropriate install_name_tool fixups. -# -# :: -# -# COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>) -# -# Copy a resolved item into the bundle if necessary. Copy is not -# necessary if the resolved_item is "the same as" the -# resolved_embedded_item. -# -# :: -# -# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>) -# -# Copy a resolved framework into the bundle if necessary. Copy is not -# necessary if the resolved_item is "the same as" the -# resolved_embedded_item. -# -# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set. If you want -# full frameworks embedded in your bundles, set -# BU_COPY_FULL_FRAMEWORK_CONTENTS to ON before calling fixup_bundle. By -# default, COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework -# dylib itself plus the framework Resources directory. -# -# :: -# -# FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>) -# -# Get the direct/non-system prerequisites of the resolved embedded item. -# For each prerequisite, change the way it is referenced to the value of -# the _EMBEDDED_ITEM keyed variable for that prerequisite. (Most likely -# changing to an "@executable_path" style reference.) -# -# This function requires that the resolved_embedded_item be "inside" the -# bundle already. In other words, if you pass plugins to fixup_bundle -# as the libs parameter, you should install them or copy them into the -# bundle before calling fixup_bundle. The "libs" parameter is a list of -# libraries that must be fixed up, but that cannot be determined by -# otool output analysis. (i.e., plugins) -# -# Also, change the id of the item being fixed up to its own -# _EMBEDDED_ITEM value. +# GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>) +# Loop over all the executable and library files within the bundle (and given +# as extra <libs>) and accumulate a list of keys representing them. Set +# values associated with each key such that we can loop over all of them and +# copy prerequisite libs into the bundle and then do appropriate +# install_name_tool fixups. +# +# COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>) +# Copy a resolved item into the bundle if necessary. Copy is not necessary if +# the resolved_item is "the same as" the resolved_embedded_item. +# +# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>) +# Copy a resolved framework into the bundle if necessary. Copy is not necessary +# if the resolved_item is "the same as" the resolved_embedded_item. +# +# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set. If you want full +# frameworks embedded in your bundles, set BU_COPY_FULL_FRAMEWORK_CONTENTS to +# ON before calling fixup_bundle. By default, +# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework dylib itself plus +# the framework Resources directory. +# +# IS_RESOLVED_ITEM_EMBEDDED(<resolved_item> <exepath> <verbose> <is_embedded_var>) +# Set variable <is_embedded_var> to True if the resolved item is +# embedded into the bundle. The function does NOT check for the existence of the +# item, instead if checks if the provided path would correspond to an embeddable +# item. If <verbose> is True, extra information will be displayed in case the item +# is not embedded. +# +# FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>) +# Get the direct/non-system prerequisites of the resolved embedded item. For +# each prerequisite, change the way it is referenced to the value of the +# _EMBEDDED_ITEM keyed variable for that prerequisite. (Most likely changing to +# an "@executable_path" style reference.) +# +# This function requires that the resolved_embedded_item be "inside" the bundle +# already. In other words, if you pass plugins to fixup_bundle as the libs +# parameter, you should install them or copy them into the bundle before +# calling fixup_bundle. The "libs" parameter is a list of libraries that must +# be fixed up, but that cannot be determined by otool output analysis. (i.e., +# plugins) +# +# Also, change the id of the item being fixed up to its own _EMBEDDED_ITEM +# value. # # Accumulate changes in a local variable and make *one* call to -# install_name_tool at the end of the function with all the changes at -# once. +# install_name_tool at the end of the function with all the changes at once. # # If the BU_CHMOD_BUNDLE_ITEMS variable is set then bundle items will be # marked writable before install_name_tool tries to change them. # -# :: -# -# VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>) -# -# Verifies that the sum of all prerequisites of all files inside the -# bundle are contained within the bundle or are "system" libraries, -# presumed to exist everywhere. +# VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>) +# Verifies that the sum of all prerequisites of all files inside the bundle +# are contained within the bundle or are "system" libraries, presumed to exist +# everywhere. # -# :: -# -# VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>) -# -# Verifies that any symlinks found in the bundle point to other files -# that are already also in the bundle... Anything that points to an -# external file causes this function to fail the verification. +# VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>) +# Verifies that any symlinks found in the bundle point to other files that are +# already also in the bundle... Anything that points to an external file causes +# this function to fail the verification. #============================================================================= # Copyright 2008-2009 Kitware, Inc. @@ -220,7 +167,7 @@ # (and possibly others) found in: # get_filename_component(BundleUtilities_cmake_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) -include("${BundleUtilities_cmake_dir}/GetPrerequisites.cmake") +include("${BundleUtilities_cmake_dir}/GetPrerequisitesWithRPath.cmake") function(get_bundle_main_executable bundle result_var) @@ -436,22 +383,52 @@ function(set_bundle_key_values keys_var context item exepath dirs copyflag) # embedded path: # set(embedded_item "${default_embedded_path}/${item_name}") + + if(APPLE) + # For executables inside the bundle, extract the expected path. + # This remove the hack introduced in commit 6f8bdd27 consisting in + # reseting the value of 'resolved_embedded_item' with 'resolved_item'. + get_dotapp_dir("${exepath}" exe_dotapp_dir) + if(NOT DEFINED gp_bundle_executables) + get_bundle_all_executables("${exe_dotapp_dir}" gp_bundle_executables) + endif() + foreach(exe ${gp_bundle_executables}) + get_item_key("${exe}" exe_key) + list(APPEND exe_keys ${exe_key}) + endforeach() + list(FIND exe_keys ${key} is_executable) + if(NOT is_executable EQUAL "-1") + get_filename_component(resolved_item_path ${resolved_item} PATH) + file(RELATIVE_PATH exe_relative_path_from_dir ${exe_dotapp_dir} ${resolved_item_path}) + # For example, if input variables are: + # resolved_item: /path/to/MyApp.app/Contents/bin/myapp + # exe_dotapp_dir: /path/to/MyApp.app + # Computed variables will be: + # resolved_item_path: /path/to/MyApp.app/Contents/bin + # exe_relative_path_from_dir: Contents/bin + set(embedded_item "@executable_path/../../${exe_relative_path_from_dir}/${item_name}") + set(show_status 0) + if(show_status) + message(STATUS "resolved_item='${resolved_item}'") + message(STATUS "exe_dotapp_dir='${exe_dotapp_dir}'") + message(STATUS "exe_relative_path_from_dir='${exe_relative_path_from_dir}'") + message(STATUS "item_name='${item_name}'") + message(STATUS "embedded_item='${embedded_item}'") + message(STATUS "") + endif() + endif() + endif() endif() - # Replace @executable_path and resolve ".." references: - # - string(REPLACE "@executable_path" "${exepath}" resolved_embedded_item "${embedded_item}") + gp_resolve_embedded_item("${context}" "${embedded_item}" "${exepath}" resolved_embedded_item) get_filename_component(resolved_embedded_item "${resolved_embedded_item}" ABSOLUTE) - # *But* -- if we are not copying, then force resolved_embedded_item to be - # the same as resolved_item. In the case of multiple executables in the - # original bundle, using the default_embedded_path results in looking for - # the resolved executable next to the main bundle executable. This is here - # so that exes in the other sibling directories (like "bin") get fixed up - # properly... - # - if(NOT copyflag) - set(resolved_embedded_item "${resolved_item}") + # Do not copy already embedded item + set(verbose 0) + is_resolved_item_embedded("${resolved_embedded_item}" "${exepath}" "${verbose}" is_embedded) + if(EXISTS "${resolved_embedded_item}" AND is_embedded) + set(copyflag 0) + set(resolved_item "${resolved_embedded_item}") endif() set(${keys_var} ${${keys_var}} PARENT_SCOPE) @@ -479,7 +456,7 @@ function(get_bundle_keys app libs dirs keys_var) # But do fixups on all executables in the bundle: # - get_bundle_all_executables("${bundle}" exes) + get_bundle_all_executables("${bundle}" gp_bundle_executables) # For each extra lib, accumulate a key as well and then also accumulate # any of its prerequisites. (Extra libs are typically dynamically loaded @@ -500,7 +477,7 @@ function(get_bundle_keys app libs dirs keys_var) # The list of keys should be complete when all prerequisites of all # binaries in the bundle have been analyzed. # - foreach(exe ${exes}) + foreach(exe ${gp_bundle_executables}) # Add the exe itself to the keys: # set_bundle_key_values(${keys_var} "${exe}" "${exe}" "${exepath}" "${dirs}" 0) @@ -593,36 +570,43 @@ function(copy_resolved_framework_into_bundle resolved_item resolved_embedded_ite endfunction() - -function(fixup_bundle_item resolved_embedded_item exepath dirs) - # This item's key is "ikey": - # - get_item_key("${resolved_embedded_item}" ikey) - - # Ensure the item is "inside the .app bundle" -- it should not be fixed up if - # it is not in the .app bundle... Otherwise, we'll modify files in the build - # tree, or in other varied locations around the file system, with our call to - # install_name_tool. Make sure that doesn't happen here: - # +function(is_resolved_item_embedded resolved_item exepath verbose is_embedded_var) get_dotapp_dir("${exepath}" exe_dotapp_dir) string(LENGTH "${exe_dotapp_dir}/" exe_dotapp_dir_length) - string(LENGTH "${resolved_embedded_item}" resolved_embedded_item_length) + string(LENGTH "${resolved_item}" resolved_item_length) set(path_too_short 0) set(is_embedded 0) - if(${resolved_embedded_item_length} LESS ${exe_dotapp_dir_length}) + if(${resolved_item_length} LESS ${exe_dotapp_dir_length}) set(path_too_short 1) endif() if(NOT path_too_short) - string(SUBSTRING "${resolved_embedded_item}" 0 ${exe_dotapp_dir_length} item_substring) + string(SUBSTRING "${resolved_item}" 0 ${exe_dotapp_dir_length} item_substring) if("${exe_dotapp_dir}/" STREQUAL "${item_substring}") set(is_embedded 1) endif() endif() - if(NOT is_embedded) + if(verbose AND NOT is_embedded) message(" exe_dotapp_dir/='${exe_dotapp_dir}/'") message(" item_substring='${item_substring}'") - message(" resolved_embedded_item='${resolved_embedded_item}'") + message(" resolved_item='${resolved_item}'") message("") + endif() + set(${is_embedded_var} ${is_embedded} PARENT_SCOPE) +endfunction() + +function(fixup_bundle_item resolved_embedded_item exepath dirs) + # This item's key is "ikey": + # + get_item_key("${resolved_embedded_item}" ikey) + + # Ensure the item is "inside the .app bundle" -- it should not be fixed up if + # it is not in the .app bundle... Otherwise, we'll modify files in the build + # tree, or in other varied locations around the file system, with our call to + # install_name_tool. Make sure that doesn't happen here: + # + set(verbose 1) + is_resolved_item_embedded("${resolved_embedded_item}" "${exepath}" "${verbose}" is_embedded) + if(NOT is_embedded) message("Install or copy the item into the bundle before calling fixup_bundle.") message("Or maybe there's a typo or incorrect path in one of the args to fixup_bundle?") message("") @@ -658,48 +642,6 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs) ) endfunction() -function(fixup_python_framework exepath dirs) - if(APPLE) - message(STATUS "Begin fixup python framework") - file(GLOB_RECURSE file_list "${exepath}/../Frameworks/Python.framework/*Python") - set(depends "") - set(file_need_fix "") - foreach(file ${file_list}) - set(prereqs "") - get_prerequisites("${file}" prereqs 1 1 "${exepath}" "${dirs}") - if(prereqs) - gp_append_unique(file_need_fix "${file}") - foreach(pr ${prereqs}) - gp_append_unique(depends "${pr}") - endforeach(pr) - endif(prereqs) - endforeach(file) - set(embed_deps "") - foreach(dep ${depends}) - GET_FILENAME_COMPONENT(dep_name "${dep}" NAME) - if(NOT EXISTS "${exepath}/../MacOS/${dep_name}") - execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${dep}" "${exepath}/../MacOS") - gp_append_unique(embed_deps "${exepath}/../MacOS/${dep_name}") - endif(NOT EXISTS "${exepath}/../MacOS/${dep_name}") - endforeach(dep) - set(file_list ${file_need_fix} ${embed_deps}) - foreach(f ${file_list}) - GET_FILENAME_COMPONENT(fname "${f}" NAME) - set(prereqs "") - get_prerequisites("${f}" prereqs 1 0 "${exepath}" "${dirs}") - set(changes "") - foreach(pr ${prereqs}) - GET_FILENAME_COMPONENT(pfname "${pr}" NAME) - set(changes ${changes} "-change" "${pr}" "@executable_path/../MacOS/${pfname}") - endforeach(pr) - execute_process(COMMAND chmod u+w "${f}") - execute_process(COMMAND install_name_tool - ${changes} -id "@executable_path/../MacOS/${fname}" "${f}") - endforeach(f) - message(STATUS "end fixup python framework") - endif(APPLE) -endfunction(fixup_python_framework) - function(fixup_bundle app libs dirs) message(STATUS "fixup_bundle") @@ -708,9 +650,17 @@ function(fixup_bundle app libs dirs) message(STATUS " dirs='${dirs}'") get_bundle_and_executable("${app}" bundle executable valid) + message(STATUS " bundle='${bundle}'") + message(STATUS " executable='${executable}'") if(valid) get_filename_component(exepath "${executable}" PATH) + # TODO: Extract list of rpath dirs automatically. On MacOSX, the following could be + # done: otool -l path/to/executable | grep -A 3 LC_RPATH | grep path + # See http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html#comment-87ea054b4839586412727dcfc94c79d2 + set(GP_RPATH_DIR ${bundle}/Contents) + message(STATUS " GP_RPATH_DIR='${GP_RPATH_DIR}'") + message(STATUS "fixup_bundle: preparing...") get_bundle_keys("${app}" "${libs}" "${dirs}" keys) @@ -727,7 +677,7 @@ function(fixup_bundle app libs dirs) message(STATUS "${i}/${n}: *NOT* copying '${${key}_RESOLVED_ITEM}'") endif() - set(show_status 1) + set(show_status 0) if(show_status) message(STATUS "key='${key}'") message(STATUS "item='${${key}_ITEM}'") @@ -765,14 +715,6 @@ function(fixup_bundle app libs dirs) message(STATUS "fixup_bundle: cleaning up...") clear_bundle_keys(keys) - message(STATUS "XXX ${exepath} ${dirs}") -# fixup_python_framework("${exepath}" "${dirs}") - - set(install_name_tool_cmd "install_name_tool -change @executable_path/../Frameworks/Python.framework/Versions/2.7/Python @rpath/Python ${exepath}/libBornAgainCore.so") - message(STATUS "XXX ${install_name_tool_cmd}") - execute_process(COMMAND chmod u+w "${exepath}/libBornAgainCore.so") - execute_process(COMMAND ${install_name_tool_cmd}) - message(STATUS "fixup_bundle: verifying...") verify_app("${app}") else() @@ -892,7 +834,6 @@ function(verify_app app) endif() if(NOT verified) -# message(FATAL_ERROR "error: verify_app failed") - message(WARNING "error: verify_app failed") + message(FATAL_ERROR "error: verify_app failed") endif() endfunction() diff --git a/cmake/modules/FixBundle.cmake.in b/cmake/modules/FixBundle.cmake.in new file mode 100644 index 00000000000..340394f4e5a --- /dev/null +++ b/cmake/modules/FixBundle.cmake.in @@ -0,0 +1,109 @@ + +set ( bundle ${CMAKE_INSTALL_PREFIX}/BornAgain.app ) + +message("AAAAA @CMAKE_SOURCE_DIR@") + +file ( GLOB pyqt_libs ${bundle}/Contents/MacOS/PyQt4/*.so ) +file ( GLOB mantid_plugins ${bundle}/plugins/*.dylib ) +file ( GLOB_RECURSE qtplugins ${bundle}/Contents/Frameworks/plugins/*.dylib ) +file ( GLOB_RECURSE mtdqtplugins ${bundle}/plugins/*.dylib ) +file ( GLOB_RECURSE pvplugins ${bundle}/pvplugins/*.dylib ) +file ( GLOB vatesplugins ${bundle}/pvplugins/*.dylib ) # Find just the top level Vates plugins + +# gp_resolved_file_type_override +# Sets the type of the dependency. The options are: system, local, embedded, other +# For OS X, system & embedded dependencies are NOT copied in to the bundle +function(gp_resolved_file_type_override resolved_file type_var) + + if(file MATCHES "Qt") + message("XXX resolving file as _embedded : ${file}") + set(${type_var} embedded PARENT_SCOPE) + elseif(file MATCHES "Python.framework") + message("XXX resolving file as _embedded : ${file}") + set(${type_var} embedded PARENT_SCOPE) + else() + message("XXX resolving file as _system : ${file}") + set(${type_var} system PARENT_SCOPE) + endif() + + +# if(resolved_file MATCHES "^/usr(|/local)/lib") +# message(STATUS "resolving ${file} as system") +# set(${type_var} system PARENT_SCOPE) +# endif() +# # Copy Qt dependencies to bundle +# if(file MATCHES "libQt") +# message("resolving ${file} as embedded") +# set(${type_var} embedded PARENT_SCOPE) +# endif() +# # Don't copy ParaView into the bundle +# if(resolved_file MATCHES "^@ParaView_DIR@") +# message(STATUS "resolving ParaView dependency ${file} as system") +# set(${type_var} system PARENT_SCOPE) +# endif() +endfunction() + +# gp_item_default_embedded_path_override item default_embedded_path_var +# +# Return the path that others should refer to the item by when the item +# is embedded inside a bundle. +# +# This is a project-specific override of BundleUtilities.cmake's +# gp_item_default_embedded_path +# +function(gp_item_default_embedded_path_override item default_embedded_path_var) + + # By default, embed items as set by gp_item_default_embedded_path: + set(path "${${default_embedded_path_var}}") + + if(item MATCHES "[^/]+\\.framework/") + set(path "@fixup_path@/Frameworks") + endif() + + +# if(item MATCHES "Python.framework") +## set( path "@rpath" ) +# set(path "@fixup_path@") +## set( overridden 1 PARENT_SCOPE ) +# message("YYY 1.1 path_override to ${path} item:${item}") +# else() +# set( path "@executable_path/../MacOS" ) +# message("YYY 1.2 path_override to ${path} item:${item}") +# endif() + + set(${default_embedded_path_var} "${path}" PARENT_SCOPE) + +endfunction(gp_item_default_embedded_path_override) + + +set(BU_CHMOD_BUNDLE_ITEMS True) +set(BU_COPY_FULL_FRAMEWORK_CONTENTS False) + +#include (BundleUtilities) +include (@CMAKE_SOURCE_DIR@/cmake/modules/BundleUtilitiesWithRPath.cmake) + +#set ( mantidpydir ${bundle}/Contents/MacOS/mantid ) +#set ( mantidpylibs ${mantidpydir}/kernel/_kernel.so +# ${mantidpydir}/geometry/_geometry.so +# ${mantidpydir}/api/_api.so ) + +#set ( other_libs ${bundle}/Contents/MacOS/mantidqtpython.so +# ${mantid_plugins} +# ${pyqt_libs} ${qtplugins} ${pvplugins} +# ${mantidpylibs} ${mtdqtplugins} ) + +#set ( dirs "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@" "@CMAKE_LIBRARY_PATH@" /Library/Frameworks /opt/intel/lib ) + +fixup_bundle ( "${bundle}" "${other_libs}" "${dirs}" ) # This will fix up the dependencies for the hard dependencies: MantidKernel etc + +#################################################### +# Functions to change the dependency references +#################################################### +function( change_bundle_id new_id sharedlib ) + execute_process(COMMAND install_name_tool -id ${new_id} ${sharedlib}) +endfunction() + +function( change_bundle_dep old_dep new_dep sharedlib ) + execute_process(COMMAND install_name_tool -change ${old_dep} ${new_dep} ${sharedlib}) +endfunction() + diff --git a/cmake/modules/GetPrerequisites.cmake b/cmake/modules/GetPrerequisitesWithRPath.cmake similarity index 77% rename from cmake/modules/GetPrerequisites.cmake rename to cmake/modules/GetPrerequisitesWithRPath.cmake index ac649e9af9c..528c540392f 100644 --- a/cmake/modules/GetPrerequisites.cmake +++ b/cmake/modules/GetPrerequisitesWithRPath.cmake @@ -1,164 +1,136 @@ -#.rst: -# GetPrerequisites -# ---------------- -# -# Functions to analyze and list executable file prerequisites. -# -# This module provides functions to list the .dll, .dylib or .so files -# that an executable or shared library file depends on. (Its +# - Functions to analyze and list executable file prerequisites. +# This module provides functions to list the .dll, .dylib or .so +# files that an executable or shared library file depends on. (Its # prerequisites.) # -# It uses various tools to obtain the list of required shared library -# files: -# -# :: -# -# dumpbin (Windows) -# objdump (MinGW on Windows) -# ldd (Linux/Unix) -# otool (Mac OSX) -# +# It uses various tools to obtain the list of required shared library files: +# dumpbin (Windows) +# objdump (MinGW on Windows) +# ldd (Linux/Unix) +# otool (Mac OSX) # The following functions are provided by this module: -# -# :: -# -# get_prerequisites -# list_prerequisites -# list_prerequisites_by_glob -# gp_append_unique -# is_file_executable -# gp_item_default_embedded_path -# (projects can override with gp_item_default_embedded_path_override) -# gp_resolve_item -# (projects can override with gp_resolve_item_override) -# gp_resolved_file_type -# (projects can override with gp_resolved_file_type_override) -# gp_file_type -# -# Requires CMake 2.6 or greater because it uses function, break, return -# and PARENT_SCOPE. -# -# :: -# -# GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse> -# <exepath> <dirs>) -# -# Get the list of shared library files required by <target>. The list -# in the variable named <prerequisites_var> should be empty on first -# entry to this function. On exit, <prerequisites_var> will contain the -# list of required shared library files. -# -# <target> is the full path to an executable file. <prerequisites_var> -# is the name of a CMake variable to contain the results. -# <exclude_system> must be 0 or 1 indicating whether to include or -# exclude "system" prerequisites. If <recurse> is set to 1 all -# prerequisites will be found recursively, if set to 0 only direct -# prerequisites are listed. <exepath> is the path to the top level -# executable used for @executable_path replacment on the Mac. <dirs> is -# a list of paths where libraries might be found: these paths are -# searched first when a target without any path info is given. Then -# standard system locations are also searched: PATH, Framework -# locations, /usr/lib... -# -# :: -# -# LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]]) -# +# get_prerequisites +# list_prerequisites +# list_prerequisites_by_glob +# gp_append_unique +# is_file_executable +# gp_item_default_embedded_path +# (projects can override with gp_item_default_embedded_path_override) +# gp_resolve_item +# (projects can override with gp_resolve_item_override) +# gp_resolve_embedded_item +# (projects can override with gp_resolve_embedded_item_override) +# gp_resolved_file_type +# (projects can override with gp_resolved_file_type_override) +# gp_file_type +# Requires CMake 2.6 or greater because it uses function, break, return and +# PARENT_SCOPE. +# +# GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse> +# <exepath> <dirs>) +# Get the list of shared library files required by <target>. The list in +# the variable named <prerequisites_var> should be empty on first entry to +# this function. On exit, <prerequisites_var> will contain the list of +# required shared library files. +# +# <target> is the full path to an executable file. <prerequisites_var> is the +# name of a CMake variable to contain the results. <exclude_system> must be 0 +# or 1 indicating whether to include or exclude "system" prerequisites. If +# <recurse> is set to 1 all prerequisites will be found recursively, if set to +# 0 only direct prerequisites are listed. <exepath> is the path to the top +# level executable used for @executable_path replacment on the Mac. <dirs> is +# a list of paths where libraries might be found: these paths are searched +# first when a target without any path info is given. Then standard system +# locations are also searched: PATH, Framework locations, /usr/lib... +# +# LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]]) # Print a message listing the prerequisites of <target>. # -# <target> is the name of a shared library or executable target or the -# full path to a shared library or executable file. If <recurse> is set -# to 1 all prerequisites will be found recursively, if set to 0 only -# direct prerequisites are listed. <exclude_system> must be 0 or 1 -# indicating whether to include or exclude "system" prerequisites. With -# <verbose> set to 0 only the full path names of the prerequisites are -# printed, set to 1 extra informatin will be displayed. -# -# :: -# -# LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>) -# -# Print the prerequisites of shared library and executable files -# matching a globbing pattern. <glob_arg> is GLOB or GLOB_RECURSE and -# <glob_exp> is a globbing expression used with "file(GLOB" or -# "file(GLOB_RECURSE" to retrieve a list of matching files. If a -# matching file is executable, its prerequisites are listed. +# <target> is the name of a shared library or executable target or the full +# path to a shared library or executable file. If <recurse> is set to 1 all +# prerequisites will be found recursively, if set to 0 only direct +# prerequisites are listed. <exclude_system> must be 0 or 1 indicating whether +# to include or exclude "system" prerequisites. With <verbose> set to 0 only +# the full path names of the prerequisites are printed, set to 1 extra +# informatin will be displayed. +# +# LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>) +# Print the prerequisites of shared library and executable files matching a +# globbing pattern. <glob_arg> is GLOB or GLOB_RECURSE and <glob_exp> is a +# globbing expression used with "file(GLOB" or "file(GLOB_RECURSE" to retrieve +# a list of matching files. If a matching file is executable, its prerequisites +# are listed. # # Any additional (optional) arguments provided are passed along as the # optional arguments to the list_prerequisites calls. # -# :: -# -# GP_APPEND_UNIQUE(<list_var> <value>) -# -# Append <value> to the list variable <list_var> only if the value is -# not already in the list. -# -# :: +# GP_APPEND_UNIQUE(<list_var> <value>) +# Append <value> to the list variable <list_var> only if the value is not +# already in the list. # -# IS_FILE_EXECUTABLE(<file> <result_var>) +# IS_FILE_EXECUTABLE(<file> <result_var>) +# Return 1 in <result_var> if <file> is a binary executable, 0 otherwise. # -# Return 1 in <result_var> if <file> is a binary executable, 0 -# otherwise. -# -# :: -# -# GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>) +# GP_IS_FILE_EXECUTABLE_EXCLUDE_REGEX can be set to a regular expression used +# to give a hint to identify more quickly if a given file is an executable or not. +# This is particularly useful on unix platform where it can avoid a lot of +# time-consuming call to "file" external process. For packages bundling hundreds +# of libraries, executables, resources and data, it largely speeds up the function +# "get_bundle_all_executables". +# On unix, a convenient command line allowing to collect recursively all file extensions +# useful to generate a regular expression like "\\.(dylib|py|pyc|so)$" is: +# find . -type f -name '*.*' | sed 's@.*/.*\.@@' | sort | uniq | tr "\\n" "|" # +# GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>) # Return the path that others should refer to the item by when the item # is embedded inside a bundle. # # Override on a per-project basis by providing a project-specific # gp_item_default_embedded_path_override function. # -# :: -# -# GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>) -# +# GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>) # Resolve an item into an existing full path file. # # Override on a per-project basis by providing a project-specific # gp_resolve_item_override function. # -# :: +# GP_RESOLVE_EMBEDDED_ITEM(<context> <embedded_item> <exepath> <resolved_embedded_item_var>) +# Resolve an embedded item into the full path within the full path. Since the item can be +# copied later, it doesn't have to exist when calling this function. # -# GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>) +# Override on a per-project basis by providing a project-specific +# gp_resolve_embedded_item_override function. +# +# If GP_RPATH_DIR variable is set then item matching '@rpath' are +# resolved using the provided directory. Currently setting this variable +# has an effect only on MacOSX when fixing up application bundle. The directory +# are also assumed to be located within the application bundle. It is +# usually the directory passed to the 'rpath' linker option. # -# Return the type of <file> with respect to <original_file>. String -# describing type of prerequisite is returned in variable named -# <type_var>. +# GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>) +# Return the type of <file> with respect to <original_file>. String +# describing type of prerequisite is returned in variable named <type_var>. # # Use <exepath> and <dirs> if necessary to resolve non-absolute <file> # values -- but only for non-embedded items. # # Possible types are: -# -# :: -# -# system -# local -# embedded -# other -# +# system +# local +# embedded +# other # Override on a per-project basis by providing a project-specific # gp_resolved_file_type_override function. # -# :: -# -# GP_FILE_TYPE(<original_file> <file> <type_var>) -# -# Return the type of <file> with respect to <original_file>. String -# describing type of prerequisite is returned in variable named -# <type_var>. +# GP_FILE_TYPE(<original_file> <file> <type_var>) +# Return the type of <file> with respect to <original_file>. String +# describing type of prerequisite is returned in variable named <type_var>. # # Possible types are: -# -# :: -# -# system -# local -# embedded -# other +# system +# local +# embedded +# other #============================================================================= # Copyright 2008-2009 Kitware, Inc. @@ -220,6 +192,14 @@ function(is_file_executable file result_var) # via the get_prerequisites macro. # if(UNIX) + + if(NOT "${GP_IS_FILE_EXECUTABLE_EXCLUDE_REGEX}" STREQUAL "") + if(${file_full} MATCHES "${GP_IS_FILE_EXECUTABLE_EXCLUDE_REGEX}") + set(${result_var} 0 PARENT_SCOPE) + return() + endif() + endif() + if(NOT file_cmd) find_program(file_cmd "file") mark_as_advanced(file_cmd) @@ -370,14 +350,29 @@ function(gp_resolve_item context item exepath dirs resolved_item_var) if(item MATCHES "@rpath") # # @rpath references are relative to the paths built into the binaries with -rpath - # We handle this case like we do for other Unixes + # We handle this case like we do for other Unixes. + # + # Two cases of item resolution are considered: + # + # (1) item has been copied into the bundle + # + # (2) item has NOT been copied into the bundle: Since the item can exist in a build or + # install tree outside of the bundle, the item is resolved using its name and the + # passed list of directories. # string(REPLACE "@rpath/" "" norpath_item "${item}") set(ri "ri-NOTFOUND") - find_file(ri "${norpath_item}" ${exepath} ${dirs} NO_DEFAULT_PATH) + if(EXISTS ${GP_RPATH_DIR}/${norpath_item}) + set(ri ${GP_RPATH_DIR}/${norpath_item}) + set(_msg "'find_file' in GP_RPATH_DIR (${ri})") + else() + get_filename_component(norpath_item_name ${norpath_item} NAME) + find_file(ri "${norpath_item_name}" ${exepath} ${dirs} NO_DEFAULT_PATH) + set(_msg "'find_file' in exepath/dirs (${ri})") + endif() if(ri) - #message(STATUS "info: 'find_file' in exepath/dirs (${ri})") + #message(STATUS "info: ${_msg}") set(resolved 1) set(resolved_item "${ri}") set(ri "ri-NOTFOUND") @@ -469,6 +464,46 @@ warning: cannot resolve item '${item}' set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE) endfunction() +function(gp_resolve_embedded_item context embedded_item exepath resolved_embedded_item_var) + #message(STATUS "**") + set(resolved 0) + set(resolved_embedded_item "${embedded_item}") + + if(embedded_item MATCHES "@executable_path") + string(REPLACE "@executable_path" "${exepath}" resolved_embedded_item "${embedded_item}") + set(resolved 1) + endif() + if(EXISTS "${GP_RPATH_DIR}" AND embedded_item MATCHES "@rpath") + string(REPLACE "@rpath" "${GP_RPATH_DIR}" resolved_embedded_item "${embedded_item}") + set(resolved 1) + endif() + + # Provide a hook so that projects can override embedded item resolution + # by whatever logic they choose: + # + if(COMMAND gp_resolve_embedded_item_override) + gp_resolve_embedded_item_override( + "${context}" "${embedded_item}" "${exepath}" resolved_embedded_item resolved) + endif() + + if(NOT resolved) + message(STATUS " +warning: cannot resolve embedded item '${embedded_item}' + possible problems: + need more directories? + need to use InstallRequiredSystemLibraries? + run in install tree instead of build tree? + + context='${context}' + embedded_item='${embedded_item}' + GP_RPATH_DIR='${GP_RPATH_DIR}' + exepath='${exepath}' + resolved_embedded_item_var='${resolved_embedded_item_var}' +") + endif() + + set(${resolved_embedded_item_var} "${resolved_embedded_item}" PARENT_SCOPE) +endfunction() function(gp_resolved_file_type original_file file exepath dirs type_var) #message(STATUS "**") @@ -483,7 +518,7 @@ function(gp_resolved_file_type original_file file exepath dirs type_var) set(resolved_file "${file}") - if("${file}" MATCHES "^@(executable|loader)_path") + if("${file}" MATCHES "^@(executable_|loader_|r)path") set(is_embedded 1) endif() @@ -496,13 +531,13 @@ function(gp_resolved_file_type original_file file exepath dirs type_var) string(TOLOWER "${resolved_file}" lower) if(UNIX) - if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/|/usr/bin/)") + if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11/|/usr/X11R6/|/usr/bin/|/usr/.*/lib/)") set(is_system 1) endif() endif() if(APPLE) - if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)") + if(resolved_file MATCHES "^(/System/Library/|/usr/lib/|/opt/X11/)") set(is_system 1) endif() endif() @@ -688,6 +723,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa set(gp_regex_fallback "") set(gp_regex_cmp_count 1) set(gp_tool_known 1) + set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE. endif() if("${gp_tool}" STREQUAL "objdump") @@ -738,11 +774,9 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa if("${gp_tool}" STREQUAL "ldd") set(old_ld_env "$ENV{LD_LIBRARY_PATH}") - set(new_ld_env "${exepath}") - foreach(dir ${dirs}) - set(new_ld_env "${new_ld_env}:${dir}") + foreach(dir ${exepath} ${dirs}) + set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}") endforeach() - set(ENV{LD_LIBRARY_PATH} "${new_ld_env}:$ENV{LD_LIBRARY_PATH}") endif() diff --git a/cmake/modules/bundle.cmake.in b/cmake/modules/bundle.cmake.in new file mode 100644 index 00000000000..96d72efd312 --- /dev/null +++ b/cmake/modules/bundle.cmake.in @@ -0,0 +1,21 @@ + + + + +message(STATUS "aaaa @INBUNDLE@") + +set(BU_CHMOD_BUNDLE_ITEMS True) +set(BU_COPY_FULL_FRAMEWORK_CONTENTS False) + +set(plugin_dest_dir @INBUNDLE@/Contents/PlugIns) +set(qtconf_dest_dir @INBUNDLE@/Contents/Resources) +set(APPS @CMAKE_INSTALL_PREFIX@/@INBUNDLE@) + + +file(GLOB_RECURSE QTPLUGINS "@CMAKE_INSTALL_PREFIX@/${plugin_dest_dir}/*@CMAKE_SHARED_LIBRARY_SUFFIX@") +message("AAAAA QTPLUGINS ${QTPLUGINS}") +message("AAAAA QTPLUGINS ${QTPLUGINS}") + +include(BundleUtilities) +fixup_bundle(${APPS} "${QTPLUGINS}" "@DIRS@") + -- GitLab