[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 <srikkant@amazon.com> * 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 <srikkant@amazon.com> * 1. Add more detailed comments.2. Use a custom ly_copy for Mac and leave the default as is. Signed-off-by: amzn-sj <srikkant@amazon.com> * Address some feedback from review Signed-off-by: amzn-sj <srikkant@amazon.com>
This commit is contained in:
+1
-1
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -3,7 +3,7 @@
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Editor</string>
|
||||
<string>EditorDummy</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.O3DE.Editor</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
|
||||
@@ -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 <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
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<AZStd::string> 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;
|
||||
}
|
||||
|
||||
@@ -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. <ProjectPath>/Cache
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+15
-23
@@ -24,7 +24,9 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h> // for iopolicy
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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<char*, MaxEnvVariables>;
|
||||
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];
|
||||
|
||||
@@ -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)
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>ASPR</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>AssetProcessor</string>
|
||||
<string>AssetProcessorDummy</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.Amazon.AssetProcessor</string>
|
||||
</dict>
|
||||
|
||||
@@ -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 <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Process/ProcessWatcher.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
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<AZStd::string> 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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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/$<CONFIG>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]]
|
||||
)
|
||||
|
||||
unset(target_conf_dir)
|
||||
foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES)
|
||||
string(TOUPPER ${conf} UCONF)
|
||||
string(APPEND target_conf_dir $<$<CONFIG:${conf}>:${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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user