From 44b053df58e135e087870910514b0dae3d8bbd76 Mon Sep 17 00:00:00 2001 From: SJ Date: Tue, 10 Aug 2021 08:10:37 -0700 Subject: [PATCH] [Mac] Building and running game projects from an SDK (#2943) * 1. Initial support for loading dylibs outside the bundle. 2. Child processes inherit parent's environment if no environment is explicitly specified(should change to append the parent's environment even if environment variables are explicitly specified). 3. Update some time functions to use system uptime instead of wall clock time when computing elapsed time. This fixes false timeouts when the OS goes to sleep. 4. Increase wait times for AssetBuilders and some Atom tools to connect to the AssetProcessor. This is needed because GateKeeper slows down first time bootup which results in asset processing failures. With this change we'll be able to run Editor and AssetProcessor from an install on Mac and we will also be able to build and run projects using the installed engine as an SDK. Signed-off-by: amzn-sj * 1. Remove debug messages. 2. Fix license 3. Pass parent's environment variables to child processes by default(on Mac). Signed-off-by: amzn-sj * 1. Add more detailed comments.2. Use a custom ly_copy for Mac and leave the default as is. Signed-off-by: amzn-sj * Address some feedback from review Signed-off-by: amzn-sj --- CMakeLists.txt | 2 +- Code/Editor/Platform/Mac/editor_mac.cmake | 24 ++++++ Code/Editor/Platform/Mac/gui_info.plist | 2 +- Code/Editor/Platform/Mac/main_dummy.cpp | 75 +++++++++++++++++++ .../Settings/SettingsRegistryMergeUtils.h | 1 + .../Common/Apple/AzCore/std/time_Apple.cpp | 48 +----------- .../Process/ProcessWatcher_Mac.cpp | 38 ++++------ .../Platform/Mac/assetprocessor_mac.cmake | 24 ++++++ .../Platform/Mac/gui_info.plist | 2 +- .../Platform/Mac/main_dummy.cpp | 75 +++++++++++++++++++ .../native/utilities/BuilderManager.cpp | 2 +- Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp | 2 +- cmake/Platform/Common/Install_common.cmake | 8 +- cmake/Platform/Mac/Install_mac.cmake | 50 +++++++++++++ cmake/Platform/Mac/LYWrappers_mac.cmake | 1 + 15 files changed, 278 insertions(+), 76 deletions(-) create mode 100644 Code/Editor/Platform/Mac/main_dummy.cpp create mode 100644 Code/Tools/AssetProcessor/Platform/Mac/main_dummy.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a38177714..bd02eeb7ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,8 @@ include(cmake/FileUtil.cmake) include(cmake/PAL.cmake) include(cmake/PALTools.cmake) include(cmake/RuntimeDependencies.cmake) -include(cmake/Install.cmake) include(cmake/Configurations.cmake) # Requires to be after PAL so we get platform variable definitions +include(cmake/Install.cmake) include(cmake/Dependencies.cmake) include(cmake/Deployment.cmake) include(cmake/3rdParty.cmake) diff --git a/Code/Editor/Platform/Mac/editor_mac.cmake b/Code/Editor/Platform/Mac/editor_mac.cmake index 2afbee4251..fdccfafb46 100644 --- a/Code/Editor/Platform/Mac/editor_mac.cmake +++ b/Code/Editor/Platform/Mac/editor_mac.cmake @@ -13,3 +13,27 @@ set_target_properties(Editor PROPERTIES RESOURCE ${CMAKE_CURRENT_LIST_DIR}/Images.xcassets XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME EditorAppIcon ) + +# We cannot use ly_add_target here because we're already including this file from inside ly_add_target +# So we need to setup target, dependencies and install logic manually. +add_executable(EditorDummy Platform/Mac/main_dummy.cpp) +add_executable(AZ::EditorDummy ALIAS EditorDummy) + +ly_target_link_libraries(EditorDummy + PRIVATE + AZ::AzCore + AZ::AzFramework) + +ly_add_dependencies(Editor EditorDummy) + +# Store the aliased target into a DIRECTORY property +set_property(DIRECTORY APPEND PROPERTY LY_DIRECTORY_TARGETS AZ::EditorDummy) + +# Store the directory path in a GLOBAL property so that it can be accessed +# in the layout install logic. Skip if the directory has already been added +get_property(ly_all_target_directories GLOBAL PROPERTY LY_ALL_TARGET_DIRECTORIES) +if(NOT CMAKE_CURRENT_SOURCE_DIR IN_LIST ly_all_target_directories) + set_property(GLOBAL APPEND PROPERTY LY_ALL_TARGET_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +ly_install_add_install_path_setreg(Editor) \ No newline at end of file diff --git a/Code/Editor/Platform/Mac/gui_info.plist b/Code/Editor/Platform/Mac/gui_info.plist index 5b5f94e977..cc87cbbb47 100644 --- a/Code/Editor/Platform/Mac/gui_info.plist +++ b/Code/Editor/Platform/Mac/gui_info.plist @@ -3,7 +3,7 @@ CFBundleExecutable - Editor + EditorDummy CFBundleIdentifier org.O3DE.Editor CFBundlePackageType diff --git a/Code/Editor/Platform/Mac/main_dummy.cpp b/Code/Editor/Platform/Mac/main_dummy.cpp new file mode 100644 index 0000000000..fb4a431295 --- /dev/null +++ b/Code/Editor/Platform/Mac/main_dummy.cpp @@ -0,0 +1,75 @@ +/* + * 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 + * + */ + +#include +#include +#include +#include +#include + +#include + +int main(int argc, char* argv[]) +{ + // Create a ComponentApplication to initialize the AZ::SystemAllocator and initialize the SettingsRegistry + AZ::ComponentApplication::Descriptor desc; + AZ::ComponentApplication application; + application.Create(desc); + + AZStd::vector envVars; + + const char* homePath = std::getenv("HOME"); + envVars.push_back(AZStd::string::format("HOME=%s", homePath)); + + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + const char* dyldLibPathOrig = std::getenv("DYLD_LIBRARY_PATH"); + AZStd::string dyldSearchPath = AZStd::string::format("DYLD_LIBRARY_PATH=%s", dyldLibPathOrig); + if (AZ::IO::FixedMaxPath projectModulePath; + settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath)) + { + dyldSearchPath.append(":"); + dyldSearchPath.append(projectModulePath.c_str()); + } + + if (AZ::IO::FixedMaxPath installedBinariesFolder; + settingsRegistry->Get(installedBinariesFolder.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_InstalledBinaryFolder)) + { + if (AZ::IO::FixedMaxPath engineRootFolder; + settingsRegistry->Get(engineRootFolder.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder)) + { + installedBinariesFolder = engineRootFolder / installedBinariesFolder; + dyldSearchPath.append(":"); + dyldSearchPath.append(installedBinariesFolder.c_str()); + } + } + envVars.push_back(dyldSearchPath); + } + + AZStd::string commandArgs; + for (int i = 1; i < argc; i++) + { + commandArgs.append(argv[i]); + commandArgs.append(" "); + } + + AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo; + AZ::IO::Path processPath{ AZ::IO::PathView(AZ::Utils::GetExecutableDirectory()) }; + processPath /= "Editor"; + processLaunchInfo.m_processExecutableString = AZStd::move(processPath.Native()); + processLaunchInfo.m_commandlineParameters = commandArgs; + processLaunchInfo.m_environmentVariables = &envVars; + processLaunchInfo.m_showWindow = true; + + AzFramework::ProcessWatcher* processWatcher = AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE); + + application.Destroy(); + + return 0; +} + diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h index 2926a40252..02346c2ba1 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h @@ -28,6 +28,7 @@ namespace AZ::SettingsRegistryMergeUtils inline static constexpr char FilePathsRootKey[] = "/Amazon/AzCore/Runtime/FilePaths"; inline static constexpr char FilePathKey_BinaryFolder[] = "/Amazon/AzCore/Runtime/FilePaths/BinaryFolder"; inline static constexpr char FilePathKey_EngineRootFolder[] = "/Amazon/AzCore/Runtime/FilePaths/EngineRootFolder"; + inline static constexpr char FilePathKey_InstalledBinaryFolder[] = "/Amazon/AzCore/Runtime/FilePaths/InstalledBinariesFolder"; //! Stores the absolute path to root of a project's cache. No asset platform in this path, this is where the asset database file lives. //! i.e. /Cache diff --git a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/std/time_Apple.cpp b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/std/time_Apple.cpp index 4c67c5cfc5..a8a6ffea21 100644 --- a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/std/time_Apple.cpp +++ b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/std/time_Apple.cpp @@ -25,29 +25,7 @@ namespace AZStd AZStd::sys_time_t GetTimeNowTicks() { AZStd::sys_time_t timeNow; - struct timespec ts; - clock_serv_t cclock; - mach_timespec_t mts; - kern_return_t ret = host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - if (ret == KERN_SUCCESS) - { - ret = clock_get_time(cclock, &mts); - if (ret == KERN_SUCCESS) - { - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; - } - else - { - AZ_Assert(false, "clock_get_time error: %d\n", ret); - } - mach_port_deallocate(mach_task_self(), cclock); - } - else - { - AZ_Assert(false, "clock_get_time error: %d\n", ret); - } - timeNow = ts.tv_sec * GetTimeTicksPerSecond() + ts.tv_nsec; + timeNow = clock_gettime_nsec_np(CLOCK_UPTIME_RAW); return timeNow; } @@ -62,29 +40,7 @@ namespace AZStd AZStd::sys_time_t GetTimeNowSecond() { AZStd::sys_time_t timeNowSecond; - struct timespec ts; - clock_serv_t cclock; - mach_timespec_t mts; - kern_return_t ret = host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - if (ret == KERN_SUCCESS) - { - ret = clock_get_time(cclock, &mts); - if (ret == KERN_SUCCESS) - { - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; - } - else - { - AZ_Assert(false, "clock_get_time error: %d\n", ret); - } - mach_port_deallocate(mach_task_self(), cclock); - } - else - { - AZ_Assert(false, "clock_get_time error: %d\n", ret); - } - timeNowSecond = ts.tv_sec; + timeNowSecond = GetTimeNowTicks()/GetTimeTicksPerSecond(); return timeNowSecond; } diff --git a/Code/Framework/AzFramework/Platform/Mac/AzFramework/Process/ProcessWatcher_Mac.cpp b/Code/Framework/AzFramework/Platform/Mac/AzFramework/Process/ProcessWatcher_Mac.cpp index 68e7c4e483..148b1cbdfe 100644 --- a/Code/Framework/AzFramework/Platform/Mac/AzFramework/Process/ProcessWatcher_Mac.cpp +++ b/Code/Framework/AzFramework/Platform/Mac/AzFramework/Process/ProcessWatcher_Mac.cpp @@ -24,7 +24,9 @@ #include #include // for iopolicy #include +#include +extern char **environ; namespace AzFramework { @@ -45,7 +47,7 @@ namespace AzFramework // result == 0 means child PID is still running, nothing to check if (result == -1) { - AZ_TracePrintf("ProcessWatcher", "IsChildProcessDone could not determine child process status (waitpid errno %d). assuming process either failed to launch or terminated unexpectedly\n", errno); + AZ_TracePrintf("ProcessWatcher", "IsChildProcessDone could not determine child process status (waitpid errno %d(%s)). assuming process either failed to launch or terminated unexpectedly\n", errno, strerror(errno)); exitCode = 0; } else if (result == childProcessId) @@ -274,28 +276,27 @@ namespace AzFramework azstrcat(commandAndArgs[i], token.size(), token.c_str()); } commandAndArgs[commandTokens.size()] = nullptr; - - char** environmentVariables = nullptr; - int numEnvironmentVars = 0; + + constexpr int MaxEnvVariables = 128; + using EnvironmentVariableContainer = AZStd::fixed_vector; + EnvironmentVariableContainer environmentVariables; + for (char **env = ::environ; *env; env++) + { + environmentVariables.push_back(*env); + } if (processLaunchInfo.m_environmentVariables) { - const int numEnvironmentVars = processLaunchInfo.m_environmentVariables->size(); - // Adding one more as exec expects the array to have a nullptr as the last element - environmentVariables = new char*[numEnvironmentVars + 1]; - for (int i = 0; i < numEnvironmentVars; i++) + for (AZStd::string& processLaunchEnv : *processLaunchInfo.m_environmentVariables) { - const AZStd::string& envVarString = processLaunchInfo.m_environmentVariables->at(i); - environmentVariables[i] = new char[envVarString.size() + 1]; - environmentVariables[i][0] = '\0'; - azstrcat(environmentVariables[i], envVarString.size(), envVarString.c_str()); + environmentVariables.push_back(processLaunchEnv.data()); } - environmentVariables[numEnvironmentVars] = NULL; } + environmentVariables.push_back(nullptr); pid_t child_pid = fork(); if (IsIdChildProcess(child_pid)) { - ExecuteCommandAsChild(commandAndArgs, environmentVariables, processLaunchInfo, processData.m_startupInfo); + ExecuteCommandAsChild(commandAndArgs, environmentVariables.data(), processLaunchInfo, processData.m_startupInfo); } processData.m_childProcessId = child_pid; @@ -303,15 +304,6 @@ namespace AzFramework // Close these handles as they are only to be used by the child process processData.m_startupInfo.CloseAllHandles(); - if (processLaunchInfo.m_environmentVariables) - { - for (int i = 0; i < numEnvironmentVars; i++) - { - delete [] environmentVariables[i]; - } - delete [] environmentVariables; - } - for (int i = 0; i < commandTokens.size(); i++) { delete [] commandAndArgs[i]; diff --git a/Code/Tools/AssetProcessor/Platform/Mac/assetprocessor_mac.cmake b/Code/Tools/AssetProcessor/Platform/Mac/assetprocessor_mac.cmake index 54ed70c496..e34ce9d341 100644 --- a/Code/Tools/AssetProcessor/Platform/Mac/assetprocessor_mac.cmake +++ b/Code/Tools/AssetProcessor/Platform/Mac/assetprocessor_mac.cmake @@ -13,3 +13,27 @@ set_target_properties(AssetProcessor PROPERTIES RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Platform/Mac/Images.xcassets XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AssetProcessorAppIcon ) + +# We cannot use ly_add_target here because we're already including this file from inside ly_add_target +# So we need to setup target, dependencies and install logic manually. +add_executable(AssetProcessorDummy Platform/Mac/main_dummy.cpp) +add_executable(AZ::AssetProcessorDummy ALIAS AssetProcessorDummy) + +ly_target_link_libraries(AssetProcessorDummy + PRIVATE + AZ::AzCore + AZ::AzFramework) + +ly_add_dependencies(AssetProcessor AssetProcessorDummy) + +# Store the aliased target into a DIRECTORY property +set_property(DIRECTORY APPEND PROPERTY LY_DIRECTORY_TARGETS AZ::AssetProcessorDummy) + +# Store the directory path in a GLOBAL property so that it can be accessed +# in the layout install logic. Skip if the directory has already been added +get_property(ly_all_target_directories GLOBAL PROPERTY LY_ALL_TARGET_DIRECTORIES) +if(NOT CMAKE_CURRENT_SOURCE_DIR IN_LIST ly_all_target_directories) + set_property(GLOBAL APPEND PROPERTY LY_ALL_TARGET_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}) +endif() + +ly_install_add_install_path_setreg(AssetProcessor) \ No newline at end of file diff --git a/Code/Tools/AssetProcessor/Platform/Mac/gui_info.plist b/Code/Tools/AssetProcessor/Platform/Mac/gui_info.plist index 665abea1d3..301f0c5cee 100644 --- a/Code/Tools/AssetProcessor/Platform/Mac/gui_info.plist +++ b/Code/Tools/AssetProcessor/Platform/Mac/gui_info.plist @@ -11,7 +11,7 @@ CFBundleSignature ASPR CFBundleExecutable - AssetProcessor + AssetProcessorDummy CFBundleIdentifier com.Amazon.AssetProcessor diff --git a/Code/Tools/AssetProcessor/Platform/Mac/main_dummy.cpp b/Code/Tools/AssetProcessor/Platform/Mac/main_dummy.cpp new file mode 100644 index 0000000000..12832cc488 --- /dev/null +++ b/Code/Tools/AssetProcessor/Platform/Mac/main_dummy.cpp @@ -0,0 +1,75 @@ +/* + * 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 + * + */ + +#include +#include +#include +#include +#include + +#include + +int main(int argc, char* argv[]) +{ + // Create a ComponentApplication to initialize the AZ::SystemAllocator and initialize the SettingsRegistry + AZ::ComponentApplication::Descriptor desc; + AZ::ComponentApplication application; + application.Create(desc); + + AZStd::vector envVars; + + const char* homePath = std::getenv("HOME"); + envVars.push_back(AZStd::string::format("HOME=%s", homePath)); + + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + const char* dyldLibPathOrig = std::getenv("DYLD_LIBRARY_PATH"); + AZStd::string dyldSearchPath = AZStd::string::format("DYLD_LIBRARY_PATH=%s", dyldLibPathOrig); + if (AZ::IO::FixedMaxPath projectModulePath; + settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath)) + { + dyldSearchPath.append(":"); + dyldSearchPath.append(projectModulePath.c_str()); + } + + if (AZ::IO::FixedMaxPath installedBinariesFolder; + settingsRegistry->Get(installedBinariesFolder.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_InstalledBinaryFolder)) + { + if (AZ::IO::FixedMaxPath engineRootFolder; + settingsRegistry->Get(engineRootFolder.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder)) + { + installedBinariesFolder = engineRootFolder / installedBinariesFolder; + dyldSearchPath.append(":"); + dyldSearchPath.append(installedBinariesFolder.c_str()); + } + } + envVars.push_back(dyldSearchPath); + } + + AZStd::string commandArgs; + for (int i = 1; i < argc; i++) + { + commandArgs.append(argv[i]); + commandArgs.append(" "); + } + + AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo; + AZ::IO::Path processPath{ AZ::IO::PathView(AZ::Utils::GetExecutableDirectory()) }; + processPath /= "AssetProcessor"; + processLaunchInfo.m_processExecutableString = AZStd::move(processPath.Native()); + processLaunchInfo.m_commandlineParameters = commandArgs; + processLaunchInfo.m_environmentVariables = &envVars; + processLaunchInfo.m_showWindow = true; + + AzFramework::ProcessWatcher* processWatcher = AzFramework::ProcessWatcher::LaunchProcess(processLaunchInfo, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE); + + application.Destroy(); + + return 0; +} + diff --git a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp index 5ef2ebd2f4..751afc1a5d 100644 --- a/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/BuilderManager.cpp @@ -28,7 +28,7 @@ namespace AssetProcessor //! Amount of time in seconds to wait for a builder to start up and connect // sometimes, builders take a long time to start because of things like virus scanners scanning each // builder DLL, so we give them a large margin. - static const int s_StartupConnectionWaitTimeS = 120; + static const int s_StartupConnectionWaitTimeS = 300; static const int s_MillisecondsInASecond = 1000; diff --git a/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp b/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp index 5cc69bc9a1..8c64f1611f 100644 --- a/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp @@ -304,7 +304,7 @@ namespace AZ uint32_t exitCode = 0; bool timedOut = false; - const AZStd::sys_time_t maxWaitTimeSeconds = 120; + const AZStd::sys_time_t maxWaitTimeSeconds = 300; const AZStd::sys_time_t startTimeSeconds = AZStd::GetTimeNowSecond(); const AZStd::sys_time_t startTime = AZStd::GetTimeNowTicks(); diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 353c015fd3..2b56a1f0b4 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -448,11 +448,15 @@ endfunction() function(ly_setup_runtime_dependencies) # Common functions used by the bellow code - install(CODE + if(COMMAND ly_install_code_function_override) + ly_install_code_function_override() + else() + install(CODE "function(ly_copy source_file target_directory) file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) endfunction()" - ) + ) + endif() unset(runtime_commands) get_property(all_targets GLOBAL PROPERTY LY_ALL_TARGETS) diff --git a/cmake/Platform/Mac/Install_mac.cmake b/cmake/Platform/Mac/Install_mac.cmake index 808299e09d..c7f22e9149 100644 --- a/cmake/Platform/Mac/Install_mac.cmake +++ b/cmake/Platform/Mac/Install_mac.cmake @@ -6,6 +6,34 @@ # # +# This is used to generate a setreg file which will be placed inside the bundle +# for targets that request it(eg. AssetProcessor/Editor). This is the relative path +# to the bundle from the installed engine's root. This will be used to compute the +# absolute path to bundle which may contain dependent dylibs(eg. Gems) used by a project. +set(installed_binaries_path_template [[ +{ + "Amazon": { + "AzCore": { + "Runtime": { + "FilePaths": { + "InstalledBinariesFolder": "bin/Mac/$" + } + } + } + } +}]] +) + +unset(target_conf_dir) +foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER ${conf} UCONF) + string(APPEND target_conf_dir $<$:${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${UCONF}}>) +endforeach() + +set(installed_binaries_setreg_path ${target_conf_dir}/Registry/installed_binaries_path.setreg) + +file(GENERATE OUTPUT ${installed_binaries_setreg_path} CONTENT ${installed_binaries_path_template}) + #! ly_install_target_override: Mac specific target installation function(ly_install_target_override) @@ -49,4 +77,26 @@ function(ly_install_target_override) endif() endfunction() +#! ly_install_add_install_path_setreg: Adds the install path setreg file as a dependency +function(ly_install_add_install_path_setreg NAME) + set_property(TARGET ${NAME} APPEND PROPERTY INTERFACE_LY_TARGET_FILES "${installed_binaries_setreg_path}\nRegistry") +endfunction() + +#! ly_install_code_function_override: Mac specific copy function to handle frameworks +function(ly_install_code_function_override) + + install(CODE +"function(ly_copy source_file target_directory) + 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) + + endif() + file(COPY \"\${source_file}\" DESTINATION \"\${target_directory}\" FILE_PERMISSIONS ${LY_COPY_PERMISSIONS}) +endfunction()") + +endfunction() + include(cmake/Platform/Common/Install_common.cmake) diff --git a/cmake/Platform/Mac/LYWrappers_mac.cmake b/cmake/Platform/Mac/LYWrappers_mac.cmake index 2254d422b0..578f6fe041 100644 --- a/cmake/Platform/Mac/LYWrappers_mac.cmake +++ b/cmake/Platform/Mac/LYWrappers_mac.cmake @@ -11,6 +11,7 @@ function(ly_apply_platform_properties target) set_target_properties(${target} PROPERTIES BUILD_RPATH "@executable_path/;@executable_path/../Frameworks" + INSTALL_RPATH "@executable_path/;@executable_path/../Frameworks" ) endfunction()