You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/cmake/Platform/Mac/runtime_dependencies_mac.cm...

242 lines
11 KiB
CMake

#
# 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)
cmake_path(GET source_file FILENAME target_filename)
# 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(APPEND target_file "${target_directory}" "${target_filename}")
cmake_path(COMPARE "${source_file}" EQUAL "${target_file}" same_location)
if(NOT ${same_location})
if(NOT EXISTS "${target_directory}")
file(MAKE_DIRECTORY "${target_directory}")
endif()
set(is_framework FALSE)
if("${source_file}" MATCHES "\\.[Ff]ramework")
set(is_framework TRUE)
endif()
if(NOT is_framework)
# 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_file}.lock GUARD FUNCTION TIMEOUT 300)
file(SIZE "${source_file}" source_file_size)
if(EXISTS "${target_file}")
file(SIZE "${target_file}" target_file_size)
else()
set(target_file_size 0)
endif()
else()
set(source_file_size 0)
set(target_file_size 0)
endif()
if((NOT source_file_size EQUAL target_file_size) OR "${source_file}" IS_NEWER_THAN "${target_file}")
message(STATUS "Copying \"${source_file}\" to \"${target_directory}\"...")
file(MAKE_DIRECTORY "${target_directory}")
file(COPY "${source_file}" DESTINATION "${target_directory}" FILE_PERMISSIONS @LY_COPY_PERMISSIONS@ FOLLOW_SYMLINK_CHAIN)
file(TOUCH_NOCREATE "${target_file}")
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()