123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- #
- # Copyright (c) Contributors to the Open 3D Engine Project.
- # For complete copyright and license terms please see the LICENSE at the root of this distribution.
- #
- # SPDX-License-Identifier: Apache-2.0 OR MIT
- #
- #
- function(gp_resolve_item_override context item exepath dirs resolved_item_var resolved_var)
- # Qt frameworks could resolve the binary to eg qt/lib/QtCore.framework/Headers/QtCore instead of qt/lib/QtCore.framework/Versions/5/QtCore
- # This is because GetPrerequisites.cmake gp_resolve_item function searches for the first file that matches the "frameworks name"
- if(${${resolved_var}} AND ${item} MATCHES "/(Qt[^\\.]+\\.framework)/(.*)")
- set(qt_framework ${CMAKE_MATCH_1})
- set(qt_framework_subpath ${CMAKE_MATCH_2})
- string(REGEX REPLACE "(.*)/(Qt[^\\.]+\\.framework)/(.*)" "\\1/\\2/${qt_framework_subpath}" new_resolved_item "${${resolved_item_var}}")
- set(${resolved_item_var} ${new_resolved_item} PARENT_SCOPE)
- endif()
- endfunction()
- include(BundleUtilities)
- cmake_policy(SET CMP0012 NEW) # new policy for the if that evaluates a boolean out of the LY_BUILD_FIXUP_BUNDLE expansion
- cmake_policy(SET CMP0009 NEW) # do not traverse symlinks on GLOB_RECURSE
- set(anything_new FALSE)
- set(plugin_libs)
- set(plugin_dirs)
- set(depends_on_python FALSE)
- find_program(LY_INSTALL_NAME_TOOL install_name_tool)
- if (NOT LY_INSTALL_NAME_TOOL)
- message(FATAL_ERROR "Unable to locate 'install_name_tool'")
- endif()
- function(ly_copy source_file target_directory)
-
- get_filename_component(target_filename "${source_file}" NAME)
-
- # If target_directory is a bundle
- if("${target_directory}" MATCHES "\\.app/Contents/MacOS")
- set(target_is_bundle TRUE)
- if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]")
- if(NOT @LY_BUILD_FIXUP_BUNDLE@)
- return()
- endif()
- # fixup origin to copy the whole Framework folder and change destination to Contents/Frameworks
- string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}")
- get_filename_component(source_file_folder "${source_file}" DIRECTORY)
- # Python.framework produces a bug in BundleUtilities so it needs manual handling
- # https://gitlab.kitware.com/cmake/cmake/-/issues/20165
- if("${source_file}" MATCHES "Python.framework")
- # fixup the destination so it ends up in Contents/Frameworks
- string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/Frameworks" target_directory "${target_directory}")
- set(local_plugin_dirs ${plugin_dirs})
- list(APPEND local_plugin_dirs "${target_directory}/Python.framework")
- set(target_filename Python.framework)
- set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE)
- set(depends_on_python TRUE PARENT_SCOPE)
- else()
- set(local_plugin_dirs ${plugin_dirs})
- list(APPEND local_plugin_dirs "${source_file_folder}")
- set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE)
- return()
- endif()
- elseif("${source_file}" MATCHES "qt/plugins")
- if(NOT @LY_BUILD_FIXUP_BUNDLE@)
- return()
- endif()
- # fixup the destination so it ends up in Contents/PlugIns
- string(REGEX REPLACE "(.*\\.app/Contents)/MacOS" "\\1/PlugIns" target_directory "${target_directory}")
- set(local_plugin_dirs ${plugin_dirs})
- list(APPEND local_plugin_dirs "${target_directory}")
- set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE)
- set(local_plugin_libs ${plugin_libs})
- list(APPEND local_plugin_libs "${target_directory}/${target_filename}")
- set(plugin_libs ${local_plugin_libs} PARENT_SCOPE)
- elseif("${source_file}" MATCHES "qt/translations")
- return() # skip, is this used?
-
- elseif("${source_file}" MATCHES ".dylib")
-
- set(local_plugin_dirs ${plugin_dirs})
- list(APPEND local_plugin_dirs "${target_directory}")
- set(plugin_dirs ${local_plugin_dirs} PARENT_SCOPE)
- endif()
-
- else()
-
- # target is not a bundle
- set(target_is_bundle FALSE)
- if("${source_file}" MATCHES "\\.[Ff]ramework[^\\.]")
- # fixup origin to copy the whole Framework folder
- string(REGEX REPLACE "(.*\\.[Ff]ramework).*" "\\1" source_file "${source_file}")
- get_filename_component(target_filename "${source_file}" NAME)
- if("${source_file}" MATCHES "Python.framework")
- set(depends_on_python TRUE PARENT_SCOPE)
- endif()
-
- endif()
- endif()
- cmake_path(COMPARE "${source_file}" EQUAL "${target_directory}/${target_filename}" same_location)
- if(NOT ${same_location})
- if(NOT EXISTS "${target_directory}")
- file(MAKE_DIRECTORY "${target_directory}")
- endif()
- if(NOT EXISTS "${target_directory}/${target_filename}" OR "${source_file}" IS_NEWER_THAN "${target_directory}/${target_filename}")
- message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...")
- if(NOT target_is_bundle)
- # if it is a bundle, there is no contention about the files in the destination, each bundle target will copy everything
- # we dont want these files to invalidate the bundle and cause a new signature
- file(LOCK ${target_directory}/${target_filename}.lock GUARD FUNCTION TIMEOUT 300)
- endif()
- file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN)
- file(TOUCH_NOCREATE ${target_directory}/${target_filename})
- set(anything_new TRUE PARENT_SCOPE)
- endif()
- endif()
- endfunction()
- @LY_COPY_COMMANDS@
- if(NOT @LY_BUILD_FIXUP_BUNDLE@)
- return()
- endif()
- if(@target_file_dir@ MATCHES ".app/Contents/MacOS")
- string(REGEX REPLACE "(.*\\.app)/Contents/MacOS.*" "\\1" bundle_path "@target_file_dir@")
- set(fixup_timestamp_file "${bundle_path}.fixup.stamp")
- if(NOT anything_new)
- if(NOT EXISTS "${fixup_timestamp_file}" OR "${bundle_path}" IS_NEWER_THAN "${fixup_timestamp_file}")
- set(anything_new TRUE)
- endif()
- endif()
- if(anything_new)
- unset(fixup_bundle_ignore)
- # LYN-4505: Patch dxc, is configured in the wrong folder in 3p
- if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7)
- list(APPEND fixup_bundle_ignore dxc-3.7)
- endif()
- # LYN-4502: Patch python bundle, it contains some windows executables, some files that fixup_bundle doesnt like and has
- # other issues that produce signature problems
- if(depends_on_python)
- message(STATUS "Fixing ${bundle_path}/Contents/Frameworks/Python.framework...")
- list(APPEND fixup_bundle_ignore Python python3.7m python3.7)
- file(REMOVE_RECURSE
- ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current
- ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/Headers
- ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/Python
- ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/test
- ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/scipy/io/tests
- ${bundle_path}/Contents/Frameworks/Python.framework/Python
- ${bundle_path}/Contents/Frameworks/Python.framework/Resources
- ${bundle_path}/Contents/Frameworks/Python.framework/Headers
- )
- file(GLOB_RECURSE exe_file_list "${bundle_path}/Contents/Frameworks/Python.framework/**/*.exe")
- if(exe_file_list)
- file(REMOVE_RECURSE ${exe_file_list})
- endif()
- execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink include/python3.7m Headers
- WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/3.7
- )
- execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink 3.7 Current
- WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework/Versions/
- )
- execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Python Python
- WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework
- )
- execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers Headers
- WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework
- )
- execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Resources Resources
- WORKING_DIRECTORY ${bundle_path}/Contents/Frameworks/Python.framework
- )
- file(CHMOD ${bundle_path}/Contents/Frameworks/Python.framework/Versions/Current/Python
- PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
- )
- endif()
- list(REMOVE_DUPLICATES plugin_libs)
- list(REMOVE_DUPLICATES plugin_dirs)
- fixup_bundle("${bundle_path}" "${plugin_libs}" "${plugin_dirs}" IGNORE_ITEM ${fixup_bundle_ignore})
- file(TOUCH "${bundle_path}")
- file(TOUCH "${fixup_timestamp_file}")
- # fixup bundle ends up removing the rpath of dxc (despite we exclude it)
- if(EXISTS ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7)
- execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -add_rpath @executable_path/../lib ${bundle_path}/Contents/MacOS/Builders/DirectXShaderCompiler/bin/dxc-3.7)
- endif()
- # misplaced .DS_Store files can cause signing to fail
- # Interrupted signatures can leave cstemp files behind that fail next signature
- file(GLOB_RECURSE remove_file_list
- "${bundle_path}/**/.DS_Store"
- "${bundle_path/}**/*.cstemp"
- )
- if(remove_file_list)
- file(REMOVE_RECURSE ${remove_file_list})
- endif()
- endif()
- else() # Non-bundle case
- if(depends_on_python)
- # RPATH fix python
- execute_process(COMMAND ${LY_INSTALL_NAME_TOOL} -change @rpath/Python @rpath/Python.framework/Versions/Current/Python @target_file@)
- endif()
- endif()
|