diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake index b1610e2dfe..5d6f402f10 100644 --- a/Modules/BundleUtilities.cmake +++ b/Modules/BundleUtilities.cmake @@ -624,6 +624,33 @@ function(get_bundle_keys app libs dirs keys_var) endif() endforeach() + # preserve library symlink structure + foreach(key ${${keys_var}}) + if("${${key}_COPYFLAG}" STREQUAL 1) + if(IS_SYMLINK "${${key}_RESOLVED_ITEM}") + get_filename_component(target "${${key}_RESOLVED_ITEM}" REALPATH) + set_bundle_key_values(${keys_var} "${exe}" "${target}" "${exepath}" "${dirs}" 1 "${exe_rpaths}") + get_item_key("${target}" targetkey) + + if(WIN32) + # ignore case on Windows + string(TOLOWER "${${key}_RESOLVED_ITEM}" resolved_item_compare) + string(TOLOWER "${${targetkey}_RESOLVED_EMBEDDED_ITEM}" resolved_embedded_item_compare) + else() + set(resolved_item_compare "${${key}_RESOLVED_ITEM}") + set(resolved_embedded_item_compare "${${targetkey}_RESOLVED_EMBEDDED_ITEM}") + endif() + get_filename_component(resolved_item_compare "${resolved_item_compare}" NAME) + get_filename_component(resolved_embedded_item_compare "${resolved_embedded_item_compare}" NAME) + + if(NOT "${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}") + set(${key}_COPYFLAG "2") + set(${key}_RESOLVED_ITEM "${${targetkey}_RESOLVED_EMBEDDED_ITEM}") + endif() + + endif() + endif() + endforeach() # Propagate values to caller's scope: # set(${keys_var} ${${keys_var}} PARENT_SCOPE) @@ -640,6 +667,24 @@ function(get_bundle_keys app libs dirs keys_var) endif() endfunction() +function(link_resolved_item_into_bundle resolved_item resolved_embedded_item) + if(WIN32) + # ignore case on Windows + string(TOLOWER "${resolved_item}" resolved_item_compare) + string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare) + else() + set(resolved_item_compare "${resolved_item}") + set(resolved_embedded_item_compare "${resolved_embedded_item}") + endif() + + if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}") + message(STATUS "warning: resolved_item == resolved_embedded_item - not linking...") + else() + get_filename_component(target_dir "${resolved_embedded_item}" DIRECTORY) + file(RELATIVE_PATH symlink_target "${target_dir}" "${resolved_item}") + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${symlink_target}" "${resolved_embedded_item}") + endif() +endfunction() function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item) if(WIN32) @@ -854,7 +899,9 @@ function(fixup_bundle app libs dirs) set(i 0) foreach(key ${keys}) math(EXPR i ${i}+1) - if(${${key}_COPYFLAG}) + if("${${key}_COPYFLAG}" STREQUAL "2") + message(STATUS "${i}/${n}: linking '${${key}_RESOLVED_ITEM}' -> '${${key}_RESOLVED_EMBEDDED_ITEM}'") + elseif(${${key}_COPYFLAG}) message(STATUS "${i}/${n}: copying '${${key}_RESOLVED_ITEM}'") else() message(STATUS "${i}/${n}: *NOT* copying '${${key}_RESOLVED_ITEM}'") @@ -872,7 +919,10 @@ function(fixup_bundle app libs dirs) message(STATUS "") endif() - if(${${key}_COPYFLAG}) + if("${${key}_COPYFLAG}" STREQUAL "2") + link_resolved_item_into_bundle("${${key}_RESOLVED_ITEM}" + "${${key}_RESOLVED_EMBEDDED_ITEM}") + elseif(${${key}_COPYFLAG}) set(item "${${key}_ITEM}") if(item MATCHES "[^/]+\\.framework/") copy_resolved_framework_into_bundle("${${key}_RESOLVED_ITEM}" @@ -889,7 +939,9 @@ function(fixup_bundle app libs dirs) math(EXPR i ${i}+1) if(APPLE) message(STATUS "${i}/${n}: fixing up '${${key}_RESOLVED_EMBEDDED_ITEM}'") - fixup_bundle_item("${${key}_RESOLVED_EMBEDDED_ITEM}" "${exepath}" "${dirs}") + if(NOT "${${key}_COPYFLAG}" STREQUAL "2") + fixup_bundle_item("${${key}_RESOLVED_EMBEDDED_ITEM}" "${exepath}" "${dirs}") + endif() else() message(STATUS "${i}/${n}: fix-up not required on this platform '${${key}_RESOLVED_EMBEDDED_ITEM}'") endif()