2478c60793
* Updated the CrashLog directory path to save to the project user directory instead of the engine-root directory Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removing the custom OUTPUT_NAME for the Multiplayer Gem Builder target Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Changed the default value for the LY_3RDPARTY_PATH cache variable to be ~/.o3de/3rdParty This simplifies the first time user experience when running cmake Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed Windows only issue where using creating a VS Solution for an O3DE project on a different drive resulted in an unloaded "<drive letter>:" entry appearing in the solution explorer Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Refactored install layout logic for External Subdirectories Instead of performing a regular expression over the Gems/* directory, now the each external subdirectory including the project (external) directory is recursied over and scanned for any folders that aren't excluded. By default those folders are the [Cc]ache, [Bb]uild and [Uu]ser directories Afterwards the list files to copy over are then split into a directory list and a file list that is filtered by an include regex Next the directory list is iterated over and the directories are copied to the install layout Finally the file list is iterated and the list of files are also copied to the install layout Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed the o3de.bat script changing the working directory before running the o3de.py script Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed exception in engine-template.py script when the create-gem command is invoked with the --template-name parameter that does not correspond to a registered Template Updated the create-project command to register the project with the o3de_manifest.json and the engine with the project as the final step Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed register.py over-registration of non-engine directories when then --this-engine parameter is supplied. All the projects, gems and templates inside of the default o3de_manifest folder locations were being registered with the engine that was being registered Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed register.py register_project_path() method to return 0 when the project path is successfully registered. This issue was that the save_o3de_manifest method "return" value was being checked and that method doesn't actually return a value Added question mark to the engine_template.py to correct text around notifying the user if the project was registered Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Added doc comment on the new cmke ly_get_vs_folder_directory function() Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Added clarifying comment to the ly_setup_others() command logic to copy over directories and files from any external subdirectories(Gems) that are registered with the engine at the time of install Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed infinite recursion when trying to create a template with the source directory used to seed the template Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
332 lines
16 KiB
CMake
332 lines
16 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
|
|
#
|
|
#
|
|
|
|
# Do not overcomplicate searching for the 3rdParty path, if it is not easy to find,
|
|
# the user should define it.
|
|
|
|
#! get_default_third_party_folder: Stores the default 3rdParty directory into the supplied output variable
|
|
#
|
|
# \arg:output_third_party_path name of variable to set the default project directory into
|
|
# It defaults to the ~/.o3de/3rdParty directory
|
|
function(get_default_third_party_folder output_third_party_path)
|
|
cmake_path(SET home_directory "$ENV{USERPROFILE}") # Windows
|
|
if(NOT EXISTS ${home_directory})
|
|
cmake_path(SET home_directory "$ENV{HOME}") # Unix
|
|
if (NOT EXISTS ${home_directory})
|
|
return()
|
|
endif()
|
|
endif()
|
|
|
|
set(${output_third_party_path} ${home_directory}/.o3de/3rdParty PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
get_default_third_party_folder(o3de_default_third_party_path)
|
|
set(LY_3RDPARTY_PATH "${o3de_default_third_party_path}" CACHE PATH "Path to the 3rdParty folder")
|
|
|
|
if(LY_3RDPARTY_PATH)
|
|
file(TO_CMAKE_PATH ${LY_3RDPARTY_PATH} LY_3RDPARTY_PATH)
|
|
endif()
|
|
if(NOT EXISTS ${LY_3RDPARTY_PATH})
|
|
message(FATAL_ERROR "3rdParty folder: ${LY_3RDPARTY_PATH} does not exist, call cmake defining a valid LY_3RDPARTY_PATH or use cmake-gui to configure it")
|
|
endif()
|
|
|
|
#! ly_add_external_target_path: adds a path to module path so 3rdparty Find files can be added from paths different than cmake/3rdParty
|
|
#
|
|
# \arg:PATH path to add
|
|
#
|
|
function(ly_add_external_target_path PATH)
|
|
list(APPEND CMAKE_MODULE_PATH ${PATH})
|
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} PARENT_SCOPE)
|
|
set_property(GLOBAL APPEND PROPERTY LY_ADDITIONAL_MODULE_PATH ${PATH})
|
|
endfunction()
|
|
|
|
#! ly_add_external_target: adds a library interface that exposes external libraries to be used as cmake dependencies.
|
|
#
|
|
# \arg:NAME name of the external library
|
|
# \arg:VERSION version of the external library. Location will be defined by 3rdPartyPath/NAME/VERSION
|
|
# \arg:3RDPARTY_DIRECTORY overrides the path to use when searching in the 3rdPartyPath (instead of NAME).
|
|
# If not indicated, PACKAGE will be used, if not indicated, NAME will be used.
|
|
# \arg:3RDPARTY_ROOT_DIRECTORY overrides the root path to the external library directory. This will be used instead of ${LY_3RDPARTY_PATH}.
|
|
# \arg:INCLUDE_DIRECTORIES include folders (relative to the root path where the external library is: ${LY_3RDPARTY_PATH}/${NAME}/${VERSION})
|
|
# \arg:PACKAGE if defined, defines the name of the external library "package". This is used when a package exposes multiple interfaces
|
|
# if not defined, NAME is used
|
|
# \arg:COMPILE_DEFINITIONS compile definitions to be added to the interface
|
|
# \arg:BUILD_DEPENDENCIES list of interfaces this target depends on (could be a compilation dependency if the dependency is only
|
|
# exposing an include path, or could be a linking dependency is exposing a lib)
|
|
# \arg:RUNTIME_DEPENDENCIES list of files this target depends on (could be a dynamic libraries, text files, executables,
|
|
# applications, other 3rdParty targets, etc)
|
|
# \arg:OUTPUT_SUBDIRECTORY Subdirectory within bin/<Profile/Debug>/ where the ${PACKAGE_AND_NAME}_RUNTIME_DEPENDENCIES exported by the target will be copied to.
|
|
# If not specified, then the ${PACKAGE_AND_NAME}_RUNTIME_DEPENDENCIES will be copied directly under bin/<Profile/Debug>/.
|
|
# Each file listed in runtime dependencies can also customize its own output subfolder
|
|
# by adding "\n<subfolder path>" at the end of each listed file. OUTPUT_SUBDIRECTORY only works
|
|
# if such customized subfolder per file is NOT specified.
|
|
# Examples:
|
|
# 1- If there are 5 files listed in ${PACKAGE_AND_NAME}_RUNTIME_DEPENDENCIES, and all of them
|
|
# should be copied to the same output subfolder named "My/Output/Subfolder" then it is advisable
|
|
# to set OUTPUT_SUBDIRECTORY to "My/Output/Subfolder" instead of appending: "\nMy/Output/Subfolder"
|
|
# at the end of each listed file.
|
|
# 2- Assume there are 2 files listed in ${PACKAGE_AND_NAME}_RUNTIME_DEPENDENCIES, "fileA" must go to
|
|
# subdirectory "My/Output/Subfolder/lib" and "fileB" must go to subdirectory "My/Output/Subfolder/bin".
|
|
# In this case OUTPUT_SUBDIRECTORY should NOT be used, instead the files can be listed as:
|
|
# "fileA\nMy/Output/Subfolder/lib"
|
|
# "fileB\nMy/Output/Subfolder/bin"
|
|
#
|
|
function(ly_add_external_target)
|
|
|
|
set(options)
|
|
set(oneValueArgs NAME VERSION 3RDPARTY_DIRECTORY PACKAGE 3RDPARTY_ROOT_DIRECTORY OUTPUT_SUBDIRECTORY)
|
|
set(multiValueArgs HEADER_CHECK COMPILE_DEFINITIONS INCLUDE_DIRECTORIES BUILD_DEPENDENCIES RUNTIME_DEPENDENCIES)
|
|
|
|
cmake_parse_arguments(ly_add_external_target "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
|
|
|
# Validate input arguments
|
|
if(NOT ly_add_external_target_NAME)
|
|
message(FATAL_ERROR "You must provide a name for the 3rd party library")
|
|
endif()
|
|
|
|
if(NOT ly_add_external_target_PACKAGE)
|
|
set(ly_add_external_target_PACKAGE ${ly_add_external_target_NAME})
|
|
set(PACKAGE_AND_NAME "${ly_add_external_target_NAME}")
|
|
set(NAME_WITH_NAMESPACE "${ly_add_external_target_NAME}")
|
|
set(has_package FALSE)
|
|
else()
|
|
set(PACKAGE_AND_NAME "${ly_add_external_target_PACKAGE}_${ly_add_external_target_NAME}")
|
|
set(NAME_WITH_NAMESPACE "${ly_add_external_target_PACKAGE}::${ly_add_external_target_NAME}")
|
|
set(has_package TRUE)
|
|
endif()
|
|
string(TOUPPER ${PACKAGE_AND_NAME} PACKAGE_AND_NAME)
|
|
string(TOUPPER ${ly_add_external_target_PACKAGE} PACKAGE)
|
|
|
|
if(NOT TARGET 3rdParty::${NAME_WITH_NAMESPACE})
|
|
|
|
if(NOT DEFINED ly_add_external_target_VERSION AND NOT VERSION IN_LIST ly_add_external_target_KEYWORDS_MISSING_VALUES)
|
|
message(FATAL_ERROR "You must provide a version of the \"${ly_add_external_target_PACKAGE}\" 3rd party library")
|
|
endif()
|
|
|
|
if(NOT ly_add_external_target_3RDPARTY_ROOT_DIRECTORY)
|
|
if(NOT ly_add_external_target_3RDPARTY_DIRECTORY)
|
|
if(ly_add_external_target_PACKAGE)
|
|
set(ly_add_external_target_3RDPARTY_DIRECTORY ${ly_add_external_target_PACKAGE})
|
|
else()
|
|
set(ly_add_external_target_3RDPARTY_DIRECTORY ${ly_add_external_target_NAME})
|
|
endif()
|
|
endif()
|
|
set(BASE_PATH "${LY_3RDPARTY_PATH}/${ly_add_external_target_3RDPARTY_DIRECTORY}")
|
|
|
|
else()
|
|
ly_install_external_target(${ly_add_external_target_3RDPARTY_ROOT_DIRECTORY})
|
|
set(BASE_PATH "${ly_add_external_target_3RDPARTY_ROOT_DIRECTORY}")
|
|
endif()
|
|
|
|
if(ly_add_external_target_VERSION)
|
|
set(BASE_PATH "${BASE_PATH}/${ly_add_external_target_VERSION}")
|
|
endif()
|
|
|
|
# Setting BASE_PATH variable in the parent scope to allow for the Find<3rdParty>.cmake scripts to use them
|
|
set(BASE_PATH ${BASE_PATH} PARENT_SCOPE)
|
|
|
|
add_library(3rdParty::${NAME_WITH_NAMESPACE} INTERFACE IMPORTED GLOBAL)
|
|
|
|
if(ly_add_external_target_INCLUDE_DIRECTORIES)
|
|
list(TRANSFORM ly_add_external_target_INCLUDE_DIRECTORIES PREPEND ${BASE_PATH}/)
|
|
foreach(include_path ${ly_add_external_target_INCLUDE_DIRECTORIES})
|
|
if(NOT EXISTS ${include_path})
|
|
message(FATAL_ERROR "Cannot find include path ${include_path} for 3rdParty::${NAME_WITH_NAMESPACE}")
|
|
endif()
|
|
endforeach()
|
|
ly_target_include_system_directories(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
INTERFACE ${ly_add_external_target_INCLUDE_DIRECTORIES}
|
|
)
|
|
endif()
|
|
|
|
# Check if there is a pal file
|
|
ly_get_absolute_pal_filename(pal_file ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}/${ly_add_external_target_PACKAGE}_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
|
if(NOT EXISTS ${pal_file})
|
|
set(pal_file ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}/${ly_add_external_target_PACKAGE}_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
|
endif()
|
|
if(EXISTS ${pal_file})
|
|
include(${pal_file})
|
|
endif()
|
|
|
|
if(${PACKAGE_AND_NAME}_INCLUDE_DIRECTORIES)
|
|
list(TRANSFORM ${PACKAGE_AND_NAME}_INCLUDE_DIRECTORIES PREPEND ${BASE_PATH}/)
|
|
foreach(include_path ${${PACKAGE_AND_NAME}_INCLUDE_DIRECTORIES})
|
|
string(GENEX_STRIP ${include_path} include_genex_expr)
|
|
if(include_genex_expr STREQUAL include_path AND NOT EXISTS ${include_path}) # Exclude include paths that have generation expressions from validation
|
|
message(FATAL_ERROR "Cannot find include path ${include_path} for 3rdParty::${NAME_WITH_NAMESPACE}")
|
|
endif()
|
|
endforeach()
|
|
ly_target_include_system_directories(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
INTERFACE ${${PACKAGE_AND_NAME}_INCLUDE_DIRECTORIES}
|
|
)
|
|
endif()
|
|
|
|
if(has_package AND ${PACKAGE}_LIBS)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_LINK_LIBRARIES "${${PACKAGE}_LIBS}"
|
|
)
|
|
endif()
|
|
|
|
if(${PACKAGE_AND_NAME}_LIBS)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_LINK_LIBRARIES "${${PACKAGE_AND_NAME}_LIBS}"
|
|
)
|
|
endif()
|
|
|
|
if(has_package AND ${PACKAGE}_LINK_OPTIONS)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_LINK_OPTIONS "${${PACKAGE}_LINK_OPTIONS}"
|
|
)
|
|
endif()
|
|
if(${PACKAGE_AND_NAME}_LINK_OPTIONS)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_LINK_OPTIONS "${${PACKAGE_AND_NAME}_LINK_OPTIONS}"
|
|
)
|
|
endif()
|
|
|
|
if(has_package AND ${PACKAGE}_COMPILE_OPTIONS)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_COMPILE_OPTIONS "${${PACKAGE}_COMPILE_OPTIONS}"
|
|
)
|
|
endif()
|
|
if(${PACKAGE_AND_NAME}_COMPILE_OPTIONS)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_COMPILE_OPTIONS "${${PACKAGE_AND_NAME}_COMPILE_OPTIONS}"
|
|
)
|
|
endif()
|
|
|
|
unset(all_dependencies)
|
|
if(ly_add_external_target_RUNTIME_DEPENDENCIES)
|
|
list(APPEND all_dependencies ${ly_add_external_target_RUNTIME_DEPENDENCIES})
|
|
endif()
|
|
if(has_package AND ${PACKAGE}_RUNTIME_DEPENDENCIES)
|
|
list(APPEND all_dependencies ${${PACKAGE}_RUNTIME_DEPENDENCIES})
|
|
endif()
|
|
if(${PACKAGE_AND_NAME}_RUNTIME_DEPENDENCIES)
|
|
list(APPEND all_dependencies ${${PACKAGE_AND_NAME}_RUNTIME_DEPENDENCIES})
|
|
endif()
|
|
|
|
unset(locations)
|
|
unset(manual_dependencies)
|
|
if(all_dependencies)
|
|
foreach(dependency ${all_dependencies})
|
|
if(dependency MATCHES "3rdParty::")
|
|
list(APPEND manual_dependencies ${dependency})
|
|
else()
|
|
if(ly_add_external_target_OUTPUT_SUBDIRECTORY)
|
|
string(APPEND dependency "\n${ly_add_external_target_OUTPUT_SUBDIRECTORY}")
|
|
endif()
|
|
list(APPEND locations ${dependency})
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
if(locations)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_IMPORTED_LOCATION "${locations}"
|
|
)
|
|
endif()
|
|
if(manual_dependencies)
|
|
ly_add_dependencies(3rdParty::${NAME_WITH_NAMESPACE} ${manual_dependencies})
|
|
endif()
|
|
get_property(additional_dependencies GLOBAL PROPERTY LY_DELAYED_DEPENDENCIES_3rdParty::${NAME_WITH_NAMESPACE})
|
|
if(additional_dependencies)
|
|
ly_add_dependencies(3rdParty::${NAME_WITH_NAMESPACE} ${additional_dependencies})
|
|
# Clear the variable so we can track issues in case some dependency is added after
|
|
set_property(GLOBAL PROPERTY LY_DELAYED_DEPENDENCIES_3rdParty::${NAME_WITH_NAMESPACE})
|
|
endif()
|
|
|
|
if(ly_add_external_target_COMPILE_DEFINITIONS)
|
|
target_compile_definitions(3rdParty::${NAME_WITH_NAMESPACE}
|
|
INTERFACE ${ly_add_external_target_COMPILE_DEFINITIONS}
|
|
)
|
|
endif()
|
|
if(has_package AND ${PACKAGE}_COMPILE_DEFINITIONS)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_COMPILE_DEFINITIONS "${${PACKAGE}_COMPILE_DEFINITIONS}"
|
|
)
|
|
endif()
|
|
if(${PACKAGE_AND_NAME}_COMPILE_DEFINITIONS)
|
|
set_property(TARGET 3rdParty::${NAME_WITH_NAMESPACE}
|
|
APPEND PROPERTY
|
|
INTERFACE_COMPILE_DEFINITIONS "${${PACKAGE_AND_NAME}_COMPILE_DEFINITIONS}"
|
|
)
|
|
endif()
|
|
|
|
if(has_package AND ${PACKAGE}_BUILD_DEPENDENCIES)
|
|
list(APPEND ly_add_external_target_BUILD_DEPENDENCIES "${${PACKAGE}_BUILD_DEPENDENCIES}")
|
|
list(REMOVE_DUPLICATES ly_add_external_target_BUILD_DEPENDENCIES)
|
|
endif()
|
|
if(${PACKAGE_AND_NAME}_BUILD_DEPENDENCIES)
|
|
list(APPEND ly_add_external_target_BUILD_DEPENDENCIES "${${PACKAGE_AND_NAME}_BUILD_DEPENDENCIES}")
|
|
list(REMOVE_DUPLICATES ly_add_external_target_BUILD_DEPENDENCIES)
|
|
endif()
|
|
|
|
# Interface dependencies may require to find_packages. So far, we are just using packages for 3rdParty, so we will
|
|
# search for those and automatically bring those packages. The naming convention used is 3rdParty::PackageName::OptionalInterface
|
|
foreach(dependency ${ly_add_external_target_BUILD_DEPENDENCIES})
|
|
string(REPLACE "::" ";" dependency_list ${dependency})
|
|
list(GET dependency_list 0 dependency_namespace)
|
|
if(${dependency_namespace} STREQUAL "3rdParty")
|
|
list(GET dependency_list 1 dependency_package)
|
|
ly_download_associated_package(${dependency_package})
|
|
find_package(${dependency_package} REQUIRED MODULE)
|
|
endif()
|
|
endforeach()
|
|
|
|
if(ly_add_external_target_BUILD_DEPENDENCIES)
|
|
target_link_libraries(3rdParty::${NAME_WITH_NAMESPACE}
|
|
INTERFACE
|
|
${ly_add_external_target_BUILD_DEPENDENCIES}
|
|
)
|
|
endif()
|
|
|
|
endif()
|
|
|
|
endfunction()
|
|
|
|
#! ly_install_external_target: external libraries which are not part of 3rdParty need to be installed
|
|
#
|
|
# \arg:3RDPARTY_ROOT_DIRECTORY custom 3rd party directory which needs to be installed
|
|
function(ly_install_external_target 3RDPARTY_ROOT_DIRECTORY)
|
|
|
|
# Install the Find file to our <install_location>/cmake directory
|
|
install(FILES ${CMAKE_CURRENT_LIST_FILE}
|
|
DESTINATION cmake
|
|
)
|
|
|
|
# We only want to install external targets that are part of our source tree
|
|
# Checking for relative path beginning with "../" also works when the path
|
|
# given is on another drive letter on windows(i.e., RELATIVE_PATH returns an absolute path)
|
|
file(RELATIVE_PATH rel_path ${CMAKE_SOURCE_DIR} ${3RDPARTY_ROOT_DIRECTORY})
|
|
if (NOT ${rel_path} MATCHES "^../")
|
|
get_filename_component(rel_path ${rel_path} DIRECTORY)
|
|
install(DIRECTORY ${3RDPARTY_ROOT_DIRECTORY}
|
|
DESTINATION ${rel_path}
|
|
)
|
|
endif()
|
|
|
|
endfunction()
|
|
|
|
# Add the 3rdParty folder to find the modules
|
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/3rdParty)
|
|
ly_get_absolute_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/3rdParty/Platform/${PAL_PLATFORM_NAME})
|
|
list(APPEND CMAKE_MODULE_PATH ${pal_dir})
|
|
|
|
if(NOT INSTALLED_ENGINE)
|
|
# Add the 3rdParty cmake files to the IDE
|
|
ly_include_cmake_file_list(cmake/3rdParty/cmake_files.cmake)
|
|
ly_get_absolute_pal_filename(pal_3rdparty_dir ${CMAKE_CURRENT_SOURCE_DIR}/cmake/3rdParty/Platform/${PAL_PLATFORM_NAME})
|
|
ly_include_cmake_file_list(${pal_3rdparty_dir}/cmake_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake)
|
|
endif() |