Merge topic 'fix-OSX-bundle-rpaths-and-Qt5'
631fadea
Help: Add notes for topic 'fix-OSX-bundle-rpaths-and-Qt5'50e261dd
OSX: Warn when attempting to change runtime paths on OS X 10.59b98fd52
cmake-gui: Make sure we bundle Qt5 Cocoa platform plugin83a06bb4
BundleUtilities: Framework codesign Resources/Info.plist & Currentf7df82ac
BundleUtilities: Resolve & replace @rpath placeholders14bc686f
GetPrerequisites: Make sure dyld placeholders are prefixes6c313797
BundleUtilities: Use find on UNIX for fast executable lookup
This commit is contained in:
commit
26bffa6e74
|
@ -0,0 +1,6 @@
|
||||||
|
fix-OSX-bundle-rpaths-and-Qt5
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
* The :module:`BundleUtilities` module learned to resolve and replace
|
||||||
|
``@rpath`` placeholders on OS X to correctly bundle applications
|
||||||
|
using them.
|
|
@ -19,6 +19,7 @@
|
||||||
# get_bundle_and_executable
|
# get_bundle_and_executable
|
||||||
# get_bundle_all_executables
|
# get_bundle_all_executables
|
||||||
# get_item_key
|
# get_item_key
|
||||||
|
# get_item_rpaths
|
||||||
# clear_bundle_keys
|
# clear_bundle_keys
|
||||||
# set_bundle_key_values
|
# set_bundle_key_values
|
||||||
# get_bundle_keys
|
# get_bundle_keys
|
||||||
|
@ -124,7 +125,7 @@
|
||||||
# ::
|
# ::
|
||||||
#
|
#
|
||||||
# SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs>
|
# SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs>
|
||||||
# <copyflag>)
|
# <copyflag> [<rpaths>])
|
||||||
#
|
#
|
||||||
# Add a key to the list (if necessary) for the given item. If added,
|
# Add a key to the list (if necessary) for the given item. If added,
|
||||||
# also set all the variables associated with that key.
|
# also set all the variables associated with that key.
|
||||||
|
@ -378,7 +379,25 @@ endfunction()
|
||||||
function(get_bundle_all_executables bundle exes_var)
|
function(get_bundle_all_executables bundle exes_var)
|
||||||
set(exes "")
|
set(exes "")
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
find_program(find_cmd "find")
|
||||||
|
mark_as_advanced(find_cmd)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# find command is much quicker than checking every file one by one on Unix
|
||||||
|
# which can take long time for large bundles, and since anyway we expect
|
||||||
|
# executable to have execute flag set we can narrow the list much quicker.
|
||||||
|
if(find_cmd)
|
||||||
|
execute_process(COMMAND "${find_cmd}" "${bundle}"
|
||||||
|
-type f \( -perm -0100 -o -perm -0010 -o -perm -0001 \)
|
||||||
|
OUTPUT_VARIABLE file_list
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
string(REPLACE "\n" ";" file_list "${file_list}")
|
||||||
|
else()
|
||||||
file(GLOB_RECURSE file_list "${bundle}/*")
|
file(GLOB_RECURSE file_list "${bundle}/*")
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(f ${file_list})
|
foreach(f ${file_list})
|
||||||
is_file_executable("${f}" is_executable)
|
is_file_executable("${f}" is_executable)
|
||||||
if(is_executable)
|
if(is_executable)
|
||||||
|
@ -390,6 +409,29 @@ function(get_bundle_all_executables bundle exes_var)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
function(get_item_rpaths item rpaths_var)
|
||||||
|
if(APPLE)
|
||||||
|
find_program(otool_cmd "otool")
|
||||||
|
mark_as_advanced(otool_cmd)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(otool_cmd)
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${otool_cmd}" -l "${item}"
|
||||||
|
OUTPUT_VARIABLE load_cmds_ov
|
||||||
|
)
|
||||||
|
string(REGEX REPLACE "[^\n]+cmd LC_RPATH\n[^\n]+\n[^\n]+path ([^\n]+) \\(offset[^\n]+\n" "rpath \\1\n" load_cmds_ov "${load_cmds_ov}")
|
||||||
|
string(REGEX MATCHALL "rpath [^\n]+" load_cmds_ov "${load_cmds_ov}")
|
||||||
|
string(REGEX REPLACE "rpath " "" load_cmds_ov "${load_cmds_ov}")
|
||||||
|
if(load_cmds_ov)
|
||||||
|
gp_append_unique(${rpaths_var} "${load_cmds_ov}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(${rpaths_var} ${${rpaths_var}} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
function(get_item_key item key_var)
|
function(get_item_key item key_var)
|
||||||
get_filename_component(item_name "${item}" NAME)
|
get_filename_component(item_name "${item}" NAME)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -408,12 +450,14 @@ function(clear_bundle_keys keys_var)
|
||||||
set(${key}_EMBEDDED_ITEM PARENT_SCOPE)
|
set(${key}_EMBEDDED_ITEM PARENT_SCOPE)
|
||||||
set(${key}_RESOLVED_EMBEDDED_ITEM PARENT_SCOPE)
|
set(${key}_RESOLVED_EMBEDDED_ITEM PARENT_SCOPE)
|
||||||
set(${key}_COPYFLAG PARENT_SCOPE)
|
set(${key}_COPYFLAG PARENT_SCOPE)
|
||||||
|
set(${key}_RPATHS PARENT_SCOPE)
|
||||||
endforeach()
|
endforeach()
|
||||||
set(${keys_var} PARENT_SCOPE)
|
set(${keys_var} PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
function(set_bundle_key_values keys_var context item exepath dirs copyflag)
|
function(set_bundle_key_values keys_var context item exepath dirs copyflag)
|
||||||
|
set(rpaths "${ARGV6}")
|
||||||
get_filename_component(item_name "${item}" NAME)
|
get_filename_component(item_name "${item}" NAME)
|
||||||
|
|
||||||
get_item_key("${item}" key)
|
get_item_key("${item}" key)
|
||||||
|
@ -423,10 +467,12 @@ function(set_bundle_key_values keys_var context item exepath dirs copyflag)
|
||||||
list(LENGTH ${keys_var} length_after)
|
list(LENGTH ${keys_var} length_after)
|
||||||
|
|
||||||
if(NOT length_before EQUAL length_after)
|
if(NOT length_before EQUAL length_after)
|
||||||
gp_resolve_item("${context}" "${item}" "${exepath}" "${dirs}" resolved_item)
|
gp_resolve_item("${context}" "${item}" "${exepath}" "${dirs}" resolved_item "${rpaths}")
|
||||||
|
|
||||||
gp_item_default_embedded_path("${item}" default_embedded_path)
|
gp_item_default_embedded_path("${item}" default_embedded_path)
|
||||||
|
|
||||||
|
get_item_rpaths("${resolved_item}" item_rpaths)
|
||||||
|
|
||||||
if(item MATCHES "[^/]+\\.framework/")
|
if(item MATCHES "[^/]+\\.framework/")
|
||||||
# For frameworks, construct the name under the embedded path from the
|
# For frameworks, construct the name under the embedded path from the
|
||||||
# opening "${item_name}.framework/" to the closing "/${item_name}":
|
# opening "${item_name}.framework/" to the closing "/${item_name}":
|
||||||
|
@ -462,6 +508,8 @@ function(set_bundle_key_values keys_var context item exepath dirs copyflag)
|
||||||
set(${key}_EMBEDDED_ITEM "${embedded_item}" PARENT_SCOPE)
|
set(${key}_EMBEDDED_ITEM "${embedded_item}" PARENT_SCOPE)
|
||||||
set(${key}_RESOLVED_EMBEDDED_ITEM "${resolved_embedded_item}" PARENT_SCOPE)
|
set(${key}_RESOLVED_EMBEDDED_ITEM "${resolved_embedded_item}" PARENT_SCOPE)
|
||||||
set(${key}_COPYFLAG "${copyflag}" PARENT_SCOPE)
|
set(${key}_COPYFLAG "${copyflag}" PARENT_SCOPE)
|
||||||
|
set(${key}_RPATHS "${item_rpaths}" PARENT_SCOPE)
|
||||||
|
set(${key}_RDEP_RPATHS "${rpaths}" PARENT_SCOPE)
|
||||||
else()
|
else()
|
||||||
#message("warning: item key '${key}' already in the list, subsequent references assumed identical to first")
|
#message("warning: item key '${key}' already in the list, subsequent references assumed identical to first")
|
||||||
endif()
|
endif()
|
||||||
|
@ -482,18 +530,27 @@ function(get_bundle_keys app libs dirs keys_var)
|
||||||
#
|
#
|
||||||
get_bundle_all_executables("${bundle}" exes)
|
get_bundle_all_executables("${bundle}" exes)
|
||||||
|
|
||||||
|
# Set keys for main executable first:
|
||||||
|
#
|
||||||
|
set_bundle_key_values(${keys_var} "${executable}" "${executable}" "${exepath}" "${dirs}" 0)
|
||||||
|
|
||||||
|
# Get rpaths specified by main executable:
|
||||||
|
#
|
||||||
|
get_item_key("${executable}" executable_key)
|
||||||
|
set(main_rpaths "${${executable_key}_RPATHS}")
|
||||||
|
|
||||||
# For each extra lib, accumulate a key as well and then also accumulate
|
# For each extra lib, accumulate a key as well and then also accumulate
|
||||||
# any of its prerequisites. (Extra libs are typically dynamically loaded
|
# any of its prerequisites. (Extra libs are typically dynamically loaded
|
||||||
# plugins: libraries that are prerequisites for full runtime functionality
|
# plugins: libraries that are prerequisites for full runtime functionality
|
||||||
# but that do not show up in otool -L output...)
|
# but that do not show up in otool -L output...)
|
||||||
#
|
#
|
||||||
foreach(lib ${libs})
|
foreach(lib ${libs})
|
||||||
set_bundle_key_values(${keys_var} "${lib}" "${lib}" "${exepath}" "${dirs}" 0)
|
set_bundle_key_values(${keys_var} "${lib}" "${lib}" "${exepath}" "${dirs}" 0 "${main_rpaths}")
|
||||||
|
|
||||||
set(prereqs "")
|
set(prereqs "")
|
||||||
get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}")
|
get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}" "${main_rpaths}")
|
||||||
foreach(pr ${prereqs})
|
foreach(pr ${prereqs})
|
||||||
set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1)
|
set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1 "${main_rpaths}")
|
||||||
endforeach()
|
endforeach()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
@ -502,16 +559,27 @@ function(get_bundle_keys app libs dirs keys_var)
|
||||||
# binaries in the bundle have been analyzed.
|
# binaries in the bundle have been analyzed.
|
||||||
#
|
#
|
||||||
foreach(exe ${exes})
|
foreach(exe ${exes})
|
||||||
|
# Main executable is scanned first above:
|
||||||
|
#
|
||||||
|
if(NOT "${exe}" STREQUAL "${executable}")
|
||||||
# Add the exe itself to the keys:
|
# Add the exe itself to the keys:
|
||||||
#
|
#
|
||||||
set_bundle_key_values(${keys_var} "${exe}" "${exe}" "${exepath}" "${dirs}" 0)
|
set_bundle_key_values(${keys_var} "${exe}" "${exe}" "${exepath}" "${dirs}" 0 "${main_rpaths}")
|
||||||
|
|
||||||
|
# Get rpaths specified by executable:
|
||||||
|
#
|
||||||
|
get_item_key("${exe}" exe_key)
|
||||||
|
set(exe_rpaths "${main_rpaths}" "${${exe_key}_RPATHS}")
|
||||||
|
else()
|
||||||
|
set(exe_rpaths "${main_rpaths}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Add each prerequisite to the keys:
|
# Add each prerequisite to the keys:
|
||||||
#
|
#
|
||||||
set(prereqs "")
|
set(prereqs "")
|
||||||
get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}")
|
get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}" "${exe_rpaths}")
|
||||||
foreach(pr ${prereqs})
|
foreach(pr ${prereqs})
|
||||||
set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1)
|
set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1 "${exe_rpaths}")
|
||||||
endforeach()
|
endforeach()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
@ -525,6 +593,8 @@ function(get_bundle_keys app libs dirs keys_var)
|
||||||
set(${key}_EMBEDDED_ITEM "${${key}_EMBEDDED_ITEM}" PARENT_SCOPE)
|
set(${key}_EMBEDDED_ITEM "${${key}_EMBEDDED_ITEM}" PARENT_SCOPE)
|
||||||
set(${key}_RESOLVED_EMBEDDED_ITEM "${${key}_RESOLVED_EMBEDDED_ITEM}" PARENT_SCOPE)
|
set(${key}_RESOLVED_EMBEDDED_ITEM "${${key}_RESOLVED_EMBEDDED_ITEM}" PARENT_SCOPE)
|
||||||
set(${key}_COPYFLAG "${${key}_COPYFLAG}" PARENT_SCOPE)
|
set(${key}_COPYFLAG "${${key}_COPYFLAG}" PARENT_SCOPE)
|
||||||
|
set(${key}_RPATHS "${${key}_RPATHS}" PARENT_SCOPE)
|
||||||
|
set(${key}_RDEP_RPATHS "${${key}_RDEP_RPATHS}" PARENT_SCOPE)
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
@ -580,11 +650,30 @@ function(copy_resolved_framework_into_bundle resolved_item resolved_embedded_ite
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
|
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
|
||||||
|
|
||||||
# Plus Resources, if they exist:
|
# Plus Resources, if they exist:
|
||||||
string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Resources" resolved_resources "${resolved_item}")
|
string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources" resolved_resources "${resolved_item}")
|
||||||
string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Resources" resolved_embedded_resources "${resolved_embedded_item}")
|
string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources" resolved_embedded_resources "${resolved_embedded_item}")
|
||||||
if(EXISTS "${resolved_resources}")
|
if(EXISTS "${resolved_resources}")
|
||||||
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_resources}' '${resolved_embedded_resources}'")
|
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_resources}' '${resolved_embedded_resources}'")
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${resolved_resources}" "${resolved_embedded_resources}")
|
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${resolved_resources}" "${resolved_embedded_resources}")
|
||||||
|
else()
|
||||||
|
# Otherwise try at least copy Contents/Info.plist to Resources/Info.plist, if it exists:
|
||||||
|
string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Contents/Info.plist" resolved_info_plist "${resolved_item}")
|
||||||
|
string(REGEX REPLACE "^(.*)/[^/]+$" "\\1/Resources/Info.plist" resolved_embedded_info_plist "${resolved_embedded_item}")
|
||||||
|
if(EXISTS "${resolved_info_plist}")
|
||||||
|
#message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_info_plist}' '${resolved_embedded_info_plist}'")
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_info_plist}" "${resolved_embedded_info_plist}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Check if framework is versioned and fix it layout
|
||||||
|
string(REGEX REPLACE "^.*/([^/]+)/[^/]+$" "\\1" resolved_embedded_version "${resolved_embedded_item}")
|
||||||
|
string(REGEX REPLACE "^(.*)/[^/]+/[^/]+$" "\\1" resolved_embedded_versions "${resolved_embedded_item}")
|
||||||
|
string(REGEX REPLACE "^.*/([^/]+)/[^/]+/[^/]+$" "\\1" resolved_embedded_versions_basename "${resolved_embedded_item}")
|
||||||
|
if(resolved_embedded_versions_basename STREQUAL "Versions")
|
||||||
|
# Ensure Current symlink points to the framework version
|
||||||
|
if(NOT EXISTS "${resolved_embedded_versions}/Current")
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${resolved_embedded_version}" "${resolved_embedded_versions}/Current")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
|
@ -630,8 +719,10 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs)
|
||||||
message(FATAL_ERROR "cannot fixup an item that is not in the bundle...")
|
message(FATAL_ERROR "cannot fixup an item that is not in the bundle...")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(rpaths "${${ikey}_RPATHS}" "${${ikey}_RDEP_RPATHS}")
|
||||||
|
|
||||||
set(prereqs "")
|
set(prereqs "")
|
||||||
get_prerequisites("${resolved_embedded_item}" prereqs 1 0 "${exepath}" "${dirs}")
|
get_prerequisites("${resolved_embedded_item}" prereqs 1 0 "${exepath}" "${dirs}" "${rpaths}")
|
||||||
|
|
||||||
set(changes "")
|
set(changes "")
|
||||||
|
|
||||||
|
@ -651,12 +742,28 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs)
|
||||||
execute_process(COMMAND chmod u+w "${resolved_embedded_item}")
|
execute_process(COMMAND chmod u+w "${resolved_embedded_item}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Only if install_name_tool supports -delete_rpath:
|
||||||
|
#
|
||||||
|
execute_process(COMMAND install_name_tool
|
||||||
|
OUTPUT_VARIABLE install_name_tool_usage
|
||||||
|
ERROR_VARIABLE install_name_tool_usage
|
||||||
|
)
|
||||||
|
if(install_name_tool_usage MATCHES ".*-delete_rpath.*")
|
||||||
|
foreach(rpath ${${ikey}_RPATHS})
|
||||||
|
set(changes ${changes} -delete_rpath "${rpath}")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${ikey}_EMBEDDED_ITEM)
|
||||||
|
set(changes ${changes} -id "${${ikey}_EMBEDDED_ITEM}")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Change this item's id and all of its references in one call
|
# Change this item's id and all of its references in one call
|
||||||
# to install_name_tool:
|
# to install_name_tool:
|
||||||
#
|
#
|
||||||
execute_process(COMMAND install_name_tool
|
if(changes)
|
||||||
${changes} -id "${${ikey}_EMBEDDED_ITEM}" "${resolved_embedded_item}"
|
execute_process(COMMAND install_name_tool ${changes} "${resolved_embedded_item}")
|
||||||
)
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
@ -747,10 +854,8 @@ function(verify_bundle_prerequisites bundle result_var info_var)
|
||||||
|
|
||||||
get_bundle_main_executable("${bundle}" main_bundle_exe)
|
get_bundle_main_executable("${bundle}" main_bundle_exe)
|
||||||
|
|
||||||
file(GLOB_RECURSE file_list "${bundle}/*")
|
get_bundle_all_executables("${bundle}" file_list)
|
||||||
foreach(f ${file_list})
|
foreach(f ${file_list})
|
||||||
is_file_executable("${f}" is_executable)
|
|
||||||
if(is_executable)
|
|
||||||
get_filename_component(exepath "${f}" PATH)
|
get_filename_component(exepath "${f}" PATH)
|
||||||
math(EXPR count "${count} + 1")
|
math(EXPR count "${count} + 1")
|
||||||
|
|
||||||
|
@ -789,7 +894,6 @@ function(verify_bundle_prerequisites bundle result_var info_var)
|
||||||
set(result 0)
|
set(result 0)
|
||||||
set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
|
set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
# ::
|
# ::
|
||||||
#
|
#
|
||||||
# GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse>
|
# GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse>
|
||||||
# <exepath> <dirs>)
|
# <exepath> <dirs> [<rpaths>])
|
||||||
#
|
#
|
||||||
# Get the list of shared library files required by <target>. The list
|
# Get the list of shared library files required by <target>. The list
|
||||||
# in the variable named <prerequisites_var> should be empty on first
|
# in the variable named <prerequisites_var> should be empty on first
|
||||||
|
@ -113,7 +113,8 @@
|
||||||
#
|
#
|
||||||
# ::
|
# ::
|
||||||
#
|
#
|
||||||
# GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>)
|
# GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>
|
||||||
|
# [<rpaths>])
|
||||||
#
|
#
|
||||||
# Resolve an item into an existing full path file.
|
# Resolve an item into an existing full path file.
|
||||||
#
|
#
|
||||||
|
@ -122,7 +123,8 @@
|
||||||
#
|
#
|
||||||
# ::
|
# ::
|
||||||
#
|
#
|
||||||
# GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>)
|
# GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>
|
||||||
|
# [<rpaths>])
|
||||||
#
|
#
|
||||||
# Return the type of <file> with respect to <original_file>. String
|
# Return the type of <file> with respect to <original_file>. String
|
||||||
# describing type of prerequisite is returned in variable named
|
# describing type of prerequisite is returned in variable named
|
||||||
|
@ -321,6 +323,7 @@ endfunction()
|
||||||
function(gp_resolve_item context item exepath dirs resolved_item_var)
|
function(gp_resolve_item context item exepath dirs resolved_item_var)
|
||||||
set(resolved 0)
|
set(resolved 0)
|
||||||
set(resolved_item "${item}")
|
set(resolved_item "${item}")
|
||||||
|
set(rpaths "${ARGV5}")
|
||||||
|
|
||||||
# Is it already resolved?
|
# Is it already resolved?
|
||||||
#
|
#
|
||||||
|
@ -329,7 +332,7 @@ function(gp_resolve_item context item exepath dirs resolved_item_var)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT resolved)
|
if(NOT resolved)
|
||||||
if(item MATCHES "@executable_path")
|
if(item MATCHES "^@executable_path")
|
||||||
#
|
#
|
||||||
# @executable_path references are assumed relative to exepath
|
# @executable_path references are assumed relative to exepath
|
||||||
#
|
#
|
||||||
|
@ -347,7 +350,7 @@ function(gp_resolve_item context item exepath dirs resolved_item_var)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT resolved)
|
if(NOT resolved)
|
||||||
if(item MATCHES "@loader_path")
|
if(item MATCHES "^@loader_path")
|
||||||
#
|
#
|
||||||
# @loader_path references are assumed relative to the
|
# @loader_path references are assumed relative to the
|
||||||
# PATH of the given "context" (presumably another library)
|
# PATH of the given "context" (presumably another library)
|
||||||
|
@ -367,7 +370,7 @@ function(gp_resolve_item context item exepath dirs resolved_item_var)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT resolved)
|
if(NOT resolved)
|
||||||
if(item MATCHES "@rpath")
|
if(item MATCHES "^@rpath")
|
||||||
#
|
#
|
||||||
# @rpath references are relative to the paths built into the binaries with -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
|
||||||
|
@ -375,9 +378,9 @@ function(gp_resolve_item context item exepath dirs resolved_item_var)
|
||||||
string(REPLACE "@rpath/" "" norpath_item "${item}")
|
string(REPLACE "@rpath/" "" norpath_item "${item}")
|
||||||
|
|
||||||
set(ri "ri-NOTFOUND")
|
set(ri "ri-NOTFOUND")
|
||||||
find_file(ri "${norpath_item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
|
find_file(ri "${norpath_item}" ${exepath} ${dirs} ${rpaths} NO_DEFAULT_PATH)
|
||||||
if(ri)
|
if(ri)
|
||||||
#message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
|
#message(STATUS "info: 'find_file' in exepath/dirs/rpaths (${ri})")
|
||||||
set(resolved 1)
|
set(resolved 1)
|
||||||
set(resolved_item "${ri}")
|
set(resolved_item "${ri}")
|
||||||
set(ri "ri-NOTFOUND")
|
set(ri "ri-NOTFOUND")
|
||||||
|
@ -471,6 +474,7 @@ endfunction()
|
||||||
|
|
||||||
|
|
||||||
function(gp_resolved_file_type original_file file exepath dirs type_var)
|
function(gp_resolved_file_type original_file file exepath dirs type_var)
|
||||||
|
set(rpaths "${ARGV5}")
|
||||||
#message(STATUS "**")
|
#message(STATUS "**")
|
||||||
|
|
||||||
if(NOT IS_ABSOLUTE "${original_file}")
|
if(NOT IS_ABSOLUTE "${original_file}")
|
||||||
|
@ -489,7 +493,7 @@ function(gp_resolved_file_type original_file file exepath dirs type_var)
|
||||||
|
|
||||||
if(NOT is_embedded)
|
if(NOT is_embedded)
|
||||||
if(NOT IS_ABSOLUTE "${file}")
|
if(NOT IS_ABSOLUTE "${file}")
|
||||||
gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
|
gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file "${rpaths}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(TOLOWER "${original_file}" original_lower)
|
string(TOLOWER "${original_file}" original_lower)
|
||||||
|
@ -612,6 +616,7 @@ endfunction()
|
||||||
function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
|
function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
|
||||||
set(verbose 0)
|
set(verbose 0)
|
||||||
set(eol_char "E")
|
set(eol_char "E")
|
||||||
|
set(rpaths "${ARGV6}")
|
||||||
|
|
||||||
if(NOT IS_ABSOLUTE "${target}")
|
if(NOT IS_ABSOLUTE "${target}")
|
||||||
message("warning: target '${target}' is not absolute...")
|
message("warning: target '${target}' is not absolute...")
|
||||||
|
@ -834,7 +839,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
|
||||||
|
|
||||||
if(add_item AND ${exclude_system})
|
if(add_item AND ${exclude_system})
|
||||||
set(type "")
|
set(type "")
|
||||||
gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
|
gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type "${rpaths}")
|
||||||
|
|
||||||
if("${type}" STREQUAL "system")
|
if("${type}" STREQUAL "system")
|
||||||
set(add_item 0)
|
set(add_item 0)
|
||||||
|
@ -855,7 +860,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
|
||||||
# that the analysis tools can simply accept it as input.
|
# that the analysis tools can simply accept it as input.
|
||||||
#
|
#
|
||||||
if(NOT list_length_before_append EQUAL list_length_after_append)
|
if(NOT list_length_before_append EQUAL list_length_after_append)
|
||||||
gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item)
|
gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item "${rpaths}")
|
||||||
set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
|
set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -874,7 +879,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa
|
||||||
if(${recurse})
|
if(${recurse})
|
||||||
set(more_inputs ${unseen_prereqs})
|
set(more_inputs ${unseen_prereqs})
|
||||||
foreach(input ${more_inputs})
|
foreach(input ${more_inputs})
|
||||||
get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
|
get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}" "${rpaths}")
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,32 @@ if (Qt5Widgets_FOUND)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
||||||
|
|
||||||
|
# We need to install Cocoa platform plugin and add qt.conf for Qt5 on Mac.
|
||||||
|
# FIXME: This should be part of Qt5 CMake scripts, but unfortunatelly
|
||||||
|
# Qt5 Mac support is missing there.
|
||||||
|
if(APPLE)
|
||||||
|
macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
|
||||||
|
get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
|
||||||
|
if(EXISTS "${_qt_plugin_path}")
|
||||||
|
get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
|
||||||
|
get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
|
||||||
|
get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
|
||||||
|
set(_qt_plugin_dest "${CMAKE_INSTALL_PREFIX}/PlugIns/${_qt_plugin_type}")
|
||||||
|
install(FILES "${_qt_plugin_path}"
|
||||||
|
DESTINATION "${_qt_plugin_dest}")
|
||||||
|
set(${_qt_plugins_var}
|
||||||
|
"${${_qt_plugins_var}};${_qt_plugin_dest}/${_qt_plugin_file}")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
|
||||||
|
"[Paths]\nPlugins = PlugIns\n")
|
||||||
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WIN32 AND TARGET Qt5::Core)
|
if(WIN32 AND TARGET Qt5::Core)
|
||||||
get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
|
get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
|
||||||
get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
|
get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
|
||||||
|
@ -168,7 +194,7 @@ if(APPLE OR WIN32)
|
||||||
install(CODE "
|
install(CODE "
|
||||||
include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
|
include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
|
||||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||||
fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
|
fixup_bundle(\"${fixup_exe}\" \"${QT_PLUGINS}\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
|
||||||
")
|
")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -677,23 +677,47 @@ cmInstallTargetGenerator
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this->Target->GetMakefile()->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
cmMakefile* mf = this->Target->GetMakefile();
|
||||||
|
|
||||||
|
if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
|
||||||
{
|
{
|
||||||
// If using install_name_tool, set up the rules to modify the rpaths.
|
// If using install_name_tool, set up the rules to modify the rpaths.
|
||||||
std::string installNameTool =
|
std::string installNameTool =
|
||||||
this->Target->GetMakefile()->
|
mf->GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
|
||||||
GetSafeDefinition("CMAKE_INSTALL_NAME_TOOL");
|
|
||||||
|
|
||||||
std::vector<std::string> oldRuntimeDirs, newRuntimeDirs;
|
std::vector<std::string> oldRuntimeDirs, newRuntimeDirs;
|
||||||
cli->GetRPath(oldRuntimeDirs, false);
|
cli->GetRPath(oldRuntimeDirs, false);
|
||||||
cli->GetRPath(newRuntimeDirs, true);
|
cli->GetRPath(newRuntimeDirs, true);
|
||||||
|
|
||||||
// Note: These paths are kept unique to avoid install_name_tool corruption.
|
std::string darwin_major_version_s =
|
||||||
|
mf->GetSafeDefinition("DARWIN_MAJOR_VERSION");
|
||||||
|
|
||||||
|
std::stringstream ss(darwin_major_version_s);
|
||||||
|
int darwin_major_version;
|
||||||
|
ss >> darwin_major_version;
|
||||||
|
if(!ss.fail() && darwin_major_version <= 9 &&
|
||||||
|
(!oldRuntimeDirs.empty() || !newRuntimeDirs.empty())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cmOStringStream msg;
|
||||||
|
msg << "WARNING: Target \"" << this->Target->GetName()
|
||||||
|
<< "\" has runtime paths which cannot be changed during install. "
|
||||||
|
<< "To change runtime paths, OS X version 10.6 or newer is required. "
|
||||||
|
<< "Therefore, runtime paths will not be changed when installing. "
|
||||||
|
<< "CMAKE_BUILD_WITH_INSTALL_RPATH may be used to work around"
|
||||||
|
" this limitation.";
|
||||||
|
mf->IssueMessage(cmake::WARNING, msg.str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Note: These paths are kept unique to avoid
|
||||||
|
// install_name_tool corruption.
|
||||||
std::set<std::string> runpaths;
|
std::set<std::string> runpaths;
|
||||||
for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
|
for(std::vector<std::string>::const_iterator i = oldRuntimeDirs.begin();
|
||||||
i != oldRuntimeDirs.end(); ++i)
|
i != oldRuntimeDirs.end(); ++i)
|
||||||
{
|
{
|
||||||
std::string runpath = this->Target->GetMakefile()->GetLocalGenerator()->
|
std::string runpath =
|
||||||
|
mf->GetLocalGenerator()->
|
||||||
GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
|
GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
|
||||||
|
|
||||||
if(runpaths.find(runpath) == runpaths.end())
|
if(runpaths.find(runpath) == runpaths.end())
|
||||||
|
@ -709,7 +733,8 @@ cmInstallTargetGenerator
|
||||||
for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
|
for(std::vector<std::string>::const_iterator i = newRuntimeDirs.begin();
|
||||||
i != newRuntimeDirs.end(); ++i)
|
i != newRuntimeDirs.end(); ++i)
|
||||||
{
|
{
|
||||||
std::string runpath = this->Target->GetMakefile()->GetLocalGenerator()->
|
std::string runpath =
|
||||||
|
mf->GetLocalGenerator()->
|
||||||
GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
|
GetGlobalGenerator()->ExpandCFGIntDir(*i, config);
|
||||||
|
|
||||||
if(runpaths.find(runpath) == runpaths.end())
|
if(runpaths.find(runpath) == runpaths.end())
|
||||||
|
@ -720,6 +745,7 @@ cmInstallTargetGenerator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Construct the original rpath string to be replaced.
|
// Construct the original rpath string to be replaced.
|
||||||
|
|
|
@ -109,7 +109,8 @@ if(APPLE AND NOT CMAKE_SYSTEM_VERSION VERSION_LESS 9.0)
|
||||||
target_link_libraries(testbundleutils3 shared-3 framework-3 ${CMAKE_DL_LIBS})
|
target_link_libraries(testbundleutils3 shared-3 framework-3 ${CMAKE_DL_LIBS})
|
||||||
|
|
||||||
set_target_properties(testbundleutils3 module3 PROPERTIES
|
set_target_properties(testbundleutils3 module3 PROPERTIES
|
||||||
LINK_FLAGS "-Wl,-rpath,@loader_path/")
|
LINK_FLAGS "-Wl,-rpath,@loader_path/"
|
||||||
|
BUILD_WITH_INSTALL_RPATH 1)
|
||||||
|
|
||||||
# add custom target to install and test the app
|
# add custom target to install and test the app
|
||||||
add_custom_target(testbundleutils3_test ALL
|
add_custom_target(testbundleutils3_test ALL
|
||||||
|
|
Loading…
Reference in New Issue