Implemented Support to allow project's to reference gems via the gem name (#7109)
* Implemented Support to allow project's to reference gems via the gem name Updated the enable-gem command to add the name of the enabled gem to the "gem_names" array in the project.json Updated the enable-gem test to validate this functionality Centralized the CMake logic for locating external subdirectories to the Subdirectories.cmake script Added an option to the edit-project-properties and edit-engine-properties o3de.py commands to add/remove/replace the "gem_names" field in the project.json and engine.json respectively Added a CMake function to determine the root CMake "subdirectory" of any input path which is a parent of it. This logic has been used to improve the installation of external gems to the <install-root>/External directory. Tested out the install layout before submitting PR fixes #7108 Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed the enable-gem test on Linux to resolve the mock path. Renamed all of the o3de python test from "unit_test*.py" to "test*.py" to faciliate the python unittest module picking up the test automatically. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Adding test for the disable_gem command. Fixed some typos in engine_properties.py scrip. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d605b5636d
commit
62775add6d
+38
-6
@@ -153,6 +153,36 @@ function(ly_get_last_path_segment_concat_sha256 absolute_path output_path)
|
||||
set(${output_path} ${last_path_segment_sha256_path} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#! ly_get_root_subdirectory_which_is_parent: Locates the root source directory added the input directory
|
||||
# as a subdirectory of the build, which an actual prefix of the input directory
|
||||
# This is done by recursing through the PARENT_DIRECTORY "DIRECTORY" property
|
||||
# The use for this is to locate the top most directory which called add_subdirectory from any input path
|
||||
# i.e Given an
|
||||
# LY_ROOT_FOLDER = D:\o3de
|
||||
# EXTERNAL_SUBDIRS = [D:\TestGem, D:\o3de\Gems\MyGem]
|
||||
# The LY_ROOT_FOLDER is responsible for invoking add_subdirectory on the external subdirectories
|
||||
# so it in the PARENT_DIRECTORY property, of the subdirectory, though it might not be an actual "parent"
|
||||
# If the input path to this function is D:\TestGem\Code, then the return value is D:\TestGem
|
||||
# If the input path to this function is D:\o3de\Gems\MyGem, then the return value is D:\o3de
|
||||
|
||||
# \arg:absolute_path - directory to locate top most parent "subdirectory", which is an "parent" of the input
|
||||
# \return:output_path- top most parent subdirectory, which is actual parent(i.e a prefix)
|
||||
function(ly_get_root_subdirectory_which_is_parent absolute_path output_path)
|
||||
# Walk up the parent add_subdirectory calls until a parent directory which is not a prefix of the target directory
|
||||
# is found
|
||||
cmake_path(SET candidate_path ${absolute_path})
|
||||
get_property(parent_subdir DIRECTORY ${candidate_path} PROPERTY PARENT_DIRECTORY)
|
||||
cmake_path(IS_PREFIX parent_subdir ${candidate_path} is_parent_subdir)
|
||||
while(parent_subdir AND is_parent_subdir)
|
||||
cmake_path(SET candidate_path "${parent_subdir}")
|
||||
get_property(parent_subdir DIRECTORY ${candidate_path} PROPERTY PARENT_DIRECTORY)
|
||||
cmake_path(IS_PREFIX parent_subdir ${candidate_path} is_parent_subdir)
|
||||
endwhile()
|
||||
|
||||
message(DEBUG "Root subdirectory of path \"${absolute_path}\" is \"${candidate_path}\"")
|
||||
set(${output_path} ${candidate_path} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#! ly_get_engine_relative_source_dir: Attempts to form a path relative to the BASE_DIRECTORY.
|
||||
# If that fails the last path segment of the absolute_target_source_dir concatenated with a SHA256 hash to form a target directory
|
||||
# \arg:BASE_DIRECTORY - Directory to base relative path against. Defaults to LY_ROOT_FOLDER
|
||||
@@ -167,14 +197,16 @@ function(ly_get_engine_relative_source_dir absolute_target_source_dir output_sou
|
||||
endif()
|
||||
|
||||
# Get a relative target source directory to the LY root folder if possible
|
||||
# Otherwise use the final component name
|
||||
# Otherwise use the top most source directory which led to calling add_subdirectory on the input directory
|
||||
ly_get_root_subdirectory_which_is_parent(${absolute_target_source_dir} root_subdir_of_target)
|
||||
cmake_path(RELATIVE_PATH absolute_target_source_dir BASE_DIRECTORY ${root_subdir_of_target} OUTPUT_VARIABLE relative_target_source_dir)
|
||||
|
||||
cmake_path(IS_PREFIX LY_ROOT_FOLDER ${absolute_target_source_dir} is_target_source_dir_subdirectory_of_engine)
|
||||
if(is_target_source_dir_subdirectory_of_engine)
|
||||
cmake_path(RELATIVE_PATH absolute_target_source_dir BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE relative_target_source_dir)
|
||||
else()
|
||||
ly_get_last_path_segment_concat_sha256(${absolute_target_source_dir} target_source_dir_last_path_segment)
|
||||
if(NOT is_target_source_dir_subdirectory_of_engine)
|
||||
cmake_path(GET root_subdir_of_target FILENAME root_subdir_dirname)
|
||||
set(relative_subdir ${relative_target_source_dir})
|
||||
unset(relative_target_source_dir)
|
||||
cmake_path(APPEND relative_target_source_dir "External" ${target_source_dir_last_path_segment})
|
||||
cmake_path(APPEND relative_target_source_dir "External" ${root_subdir_dirname} ${relative_subdir})
|
||||
endif()
|
||||
|
||||
set(${output_source_dir} ${relative_target_source_dir} PARENT_SCOPE)
|
||||
|
||||
+9
-37
@@ -51,49 +51,21 @@ function(o3de_read_manifest o3de_manifest_json_data)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#! o3de_recurse_gems: returns the gem paths
|
||||
#
|
||||
# \arg:object json path
|
||||
# \arg:gems returns the gems from the external subdirectory elements from the manifest
|
||||
function(o3de_recurse_gems object_json_path gems)
|
||||
get_filename_component(object_json_parent_path ${object_json_path} DIRECTORY)
|
||||
ly_file_read(${object_json_path} json_data)
|
||||
string(JSON external_subdirectories_count ERROR_VARIABLE json_error LENGTH ${json_data} "external_subdirectories")
|
||||
if(NOT json_error)
|
||||
if(external_subdirectories_count GREATER 0)
|
||||
math(EXPR external_subdirectories_range "${external_subdirectories_count}-1")
|
||||
foreach(external_subdirectories_index RANGE ${external_subdirectories_range})
|
||||
string(JSON external_subdirectories_entry ERROR_VARIABLE json_error GET ${json_data} "external_subdirectories" "${external_subdirectories_index}")
|
||||
cmake_path(IS_RELATIVE external_subdirectories_entry is_relative)
|
||||
if(${is_relative})
|
||||
cmake_path(ABSOLUTE_PATH external_subdirectories_entry BASE_DIRECTORY ${object_json_parent_path} NORMALIZE OUTPUT_VARIABLE external_subdirectories_entry)
|
||||
endif()
|
||||
if(EXISTS ${external_subdirectories_entry}/gem.json)
|
||||
list(APPEND gem_entries ${external_subdirectories_entry})
|
||||
o3de_recurse_gems(${external_subdirectories_entry}/gem.json gem_entries)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
set(${gems} ${gem_entries} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#! o3de_find_gem: returns the gem path
|
||||
#
|
||||
# \arg:gem_name the gem name to find
|
||||
# \arg:the path of the gem
|
||||
function(o3de_find_gem gem_name gem_path)
|
||||
o3de_get_manifest_path(manifest_path)
|
||||
if(EXISTS ${manifest_path})
|
||||
o3de_recurse_gems(${manifest_path} gems)
|
||||
endif()
|
||||
o3de_recurse_gems(${LY_ROOT_FOLDER}/engine.json gems)
|
||||
foreach(gem ${gems})
|
||||
ly_file_read(${gem}/gem.json json_data)
|
||||
string(JSON gem_json_name ERROR_VARIABLE json_error GET ${json_data} "gem_name")
|
||||
if(gem_json_name STREQUAL gem_name)
|
||||
set(${gem_path} ${gem} PARENT_SCOPE)
|
||||
return()
|
||||
get_all_external_subdirectories(all_external_subdirs)
|
||||
foreach(external_subdir IN LISTS all_external_subdirs)
|
||||
set(candidate_gem_path ${external_subdir}/gem.json)
|
||||
if(EXISTS ${candidate_gem_path})
|
||||
o3de_read_json_key(gem_json_name ${candidate_gem_path} "gem_name")
|
||||
if(gem_json_name STREQUAL gem_name)
|
||||
set(${gem_path} ${external_subdir} PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
@@ -448,9 +448,27 @@ function(ly_setup_cmake_install)
|
||||
# Transform the LY_EXTERNAL_SUBDIRS global property list into a json array
|
||||
set(indent " ")
|
||||
get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
list(REMOVE_DUPLICATES external_subdirs)
|
||||
foreach(external_subdir ${external_subdirs})
|
||||
cmake_path(RELATIVE_PATH external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE engine_rel_external_subdir)
|
||||
list(APPEND relative_external_subdirs "\"${engine_rel_external_subdir}\"")
|
||||
# If an external subdirectory is not a subdirectory of the engine root, then
|
||||
# prepend "External" to its subdirectory root
|
||||
ly_get_root_subdirectory_which_is_parent(${external_subdir} root_subdir_of_external_subdir)
|
||||
cmake_path(RELATIVE_PATH external_subdir BASE_DIRECTORY ${root_subdir_of_external_subdir} OUTPUT_VARIABLE engine_rel_external_subdir)
|
||||
|
||||
cmake_path(IS_PREFIX LY_ROOT_FOLDER ${external_subdir} is_subdirectory_of_engine)
|
||||
if(NOT is_subdirectory_of_engine)
|
||||
cmake_path(GET root_subdir_of_external_subdir FILENAME root_subdir_dirname)
|
||||
set(relative_subdir ${engine_rel_external_subdir})
|
||||
unset(engine_rel_external_subdir)
|
||||
cmake_path(APPEND engine_rel_external_subdir "External" ${root_subdir_dirname} ${relative_subdir})
|
||||
endif()
|
||||
|
||||
set(quoted_engine_rel_external_subdir "\"${engine_rel_external_subdir}\"")
|
||||
if (quoted_engine_rel_external_subdir IN_LIST relative_external_subdirs)
|
||||
message(WARNING "An external subdirectory \"${external_subdir}\" has been found twice when generating the engine.json for the install layout")
|
||||
else()
|
||||
list(APPEND relative_external_subdirs "\"${engine_rel_external_subdir}\"")
|
||||
endif()
|
||||
endforeach()
|
||||
list(JOIN relative_external_subdirs ",\n${indent}" LY_INSTALL_EXTERNAL_SUBDIRS)
|
||||
|
||||
@@ -507,7 +525,17 @@ function(ly_setup_cmake_install)
|
||||
# Add to find_subdirectories all directories in which ly_add_target were called in
|
||||
get_property(all_subdirectories GLOBAL PROPERTY LY_ALL_TARGET_DIRECTORIES)
|
||||
foreach(target_subdirectory IN LISTS all_subdirectories)
|
||||
cmake_path(RELATIVE_PATH target_subdirectory BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE relative_target_subdirectory)
|
||||
ly_get_root_subdirectory_which_is_parent(${target_subdirectory} root_subdir_of_target)
|
||||
cmake_path(RELATIVE_PATH target_subdirectory BASE_DIRECTORY ${root_subdir_of_target} OUTPUT_VARIABLE relative_target_subdirectory)
|
||||
|
||||
cmake_path(IS_PREFIX LY_ROOT_FOLDER ${target_subdirectory} is_subdirectory_of_engine)
|
||||
if(NOT is_subdirectory_of_engine)
|
||||
cmake_path(GET root_subdir_of_target FILENAME root_subdir_dirname)
|
||||
set(relative_subdir ${relative_target_subdirectory})
|
||||
unset(relative_target_subdirectory)
|
||||
cmake_path(APPEND relative_target_subdirectory "External" ${root_subdir_dirname} ${relative_subdir})
|
||||
endif()
|
||||
|
||||
string(APPEND find_subdirectories "add_subdirectory(${relative_target_subdirectory})\n")
|
||||
endforeach()
|
||||
set(permutation_find_subdirectories ${CMAKE_CURRENT_BINARY_DIR}/cmake/Platform/${PAL_PLATFORM_NAME}/${LY_BUILD_PERMUTATION}/o3de_subdirectories_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
|
||||
@@ -657,12 +685,12 @@ function(ly_setup_assets)
|
||||
set_property(GLOBAL APPEND PROPERTY global_gem_candidate_dirs_prop ${gem_candidate_dir})
|
||||
endforeach()
|
||||
|
||||
# Iterate over each gem candidate directories and read populate a directory property
|
||||
# Iterate over each gem candidate directories and populate a directory property
|
||||
# containing the files to copy over
|
||||
get_property(gem_candidate_dirs GLOBAL PROPERTY global_gem_candidate_dirs_prop)
|
||||
foreach(gem_candidate_dir IN LISTS gem_candidate_dirs)
|
||||
get_property(filtered_asset_paths DIRECTORY ${gem_candidate_dir} PROPERTY directory_filtered_asset_paths)
|
||||
ly_get_last_path_segment_concat_sha256(${gem_candidate_dir} last_gem_root_path_segment)
|
||||
|
||||
# Check if the gem is a subdirectory of the engine
|
||||
cmake_path(IS_PREFIX LY_ROOT_FOLDER ${gem_candidate_dir} is_gem_subdirectory_of_engine)
|
||||
|
||||
@@ -697,15 +725,16 @@ function(ly_setup_assets)
|
||||
# gem directories and files to install
|
||||
get_property(gems_assets_paths DIRECTORY ${gem_candidate_dir} PROPERTY gems_assets_paths)
|
||||
foreach(gem_absolute_path IN LISTS gems_assets_paths)
|
||||
if(is_gem_subdirectory_of_engine)
|
||||
cmake_path(RELATIVE_PATH gem_absolute_path BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE gem_install_dest_dir)
|
||||
else()
|
||||
# The gem resides outside of the LY_ROOT_FOLDER, so the destination is made relative to the
|
||||
# gem candidate directory and placed under the "External" directory"
|
||||
# directory
|
||||
cmake_path(RELATIVE_PATH gem_absolute_path BASE_DIRECTORY ${gem_candidate_dir} OUTPUT_VARIABLE gem_relative_path)
|
||||
# If an external subdirectory is not a subdirectory of the engine root, then
|
||||
# prepend "External" to its subdirectory root
|
||||
ly_get_root_subdirectory_which_is_parent(${gem_candidate_dir} root_subdir_of_gem)
|
||||
cmake_path(RELATIVE_PATH gem_absolute_path BASE_DIRECTORY ${root_subdir_of_gem} OUTPUT_VARIABLE gem_install_dest_dir)
|
||||
|
||||
if(NOT is_gem_subdirectory_of_engine)
|
||||
cmake_path(GET root_subdir_of_gem FILENAME root_subdir_dirname)
|
||||
set(relative_subdir ${gem_install_dest_dir})
|
||||
unset(gem_install_dest_dir)
|
||||
cmake_path(APPEND gem_install_dest_dir "External" ${last_gem_root_path_segment} ${gem_relative_path})
|
||||
cmake_path(APPEND gem_install_dest_dir "External" ${root_subdir_dirname} ${relative_subdir})
|
||||
endif()
|
||||
|
||||
cmake_path(GET gem_install_dest_dir PARENT_PATH gem_install_dest_dir)
|
||||
|
||||
+3
-27
@@ -118,30 +118,6 @@ function(ly_generate_project_build_path_setreg project_real_path)
|
||||
file(GENERATE OUTPUT ${project_user_build_path_setreg_file} CONTENT ${project_build_path_setreg_content})
|
||||
endfunction()
|
||||
|
||||
function(add_gem_json_external_subdirectories gem_path)
|
||||
set(gem_json_path ${gem_path}/gem.json)
|
||||
if(EXISTS ${gem_json_path})
|
||||
read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json)
|
||||
foreach(gem_external_subdir ${gem_external_subdirs})
|
||||
file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path})
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
|
||||
add_gem_json_external_subdirectories(${real_external_subdir})
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(add_project_json_external_subdirectories project_path)
|
||||
set(project_json_path ${project_path}/project.json)
|
||||
if(EXISTS ${project_json_path})
|
||||
read_json_external_subdirs(project_external_subdirs ${project_path}/project.json)
|
||||
foreach(project_external_subdir ${project_external_subdirs})
|
||||
file(REAL_PATH ${project_external_subdir} real_external_subdir BASE_DIRECTORY ${project_path})
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
|
||||
add_gem_json_external_subdirectories(${real_external_subdir})
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(install_project_asset_artifacts project_real_path)
|
||||
# The cmake tar command has a bit of a flaw
|
||||
# Any paths within the archive files it creates are relative to the current working directory.
|
||||
@@ -212,16 +188,16 @@ foreach(project ${LY_PROJECTS})
|
||||
# when the external subdirectory contains relative paths of significant length
|
||||
string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash)
|
||||
|
||||
get_filename_component(project_folder_name ${project} NAME)
|
||||
cmake_path(GET project FILENAME project_folder_name )
|
||||
list(APPEND LY_PROJECTS_FOLDER_NAME ${project_folder_name})
|
||||
add_subdirectory(${project} "${project_folder_name}-${full_directory_hash}")
|
||||
ly_generate_project_build_path_setreg(${full_directory_path})
|
||||
add_project_json_external_subdirectories(${full_directory_path})
|
||||
|
||||
# Get project name
|
||||
o3de_read_json_key(project_name ${full_directory_path}/project.json "project_name")
|
||||
add_project_json_external_subdirectories(${full_directory_path} "${project_name}")
|
||||
|
||||
install_project_asset_artifacts(${full_directory_path})
|
||||
install_project_asset_artifacts(${full_directory_path})
|
||||
|
||||
endforeach()
|
||||
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
#
|
||||
# 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_guard()
|
||||
|
||||
################################################################################
|
||||
# Subdirectory processing
|
||||
################################################################################
|
||||
|
||||
# this function is building up the LY_EXTERNAL_SUBDIRS global property
|
||||
function(add_engine_gem_json_external_subdirectories gem_path)
|
||||
set(gem_json_path ${gem_path}/gem.json)
|
||||
if(EXISTS ${gem_json_path})
|
||||
read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json)
|
||||
foreach(gem_external_subdir ${gem_external_subdirs})
|
||||
file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path})
|
||||
|
||||
# Append external subdirectory if it is not in global property
|
||||
get_property(current_external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
if(NOT real_external_subdir IN_LIST current_external_subdirs)
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
|
||||
# Also append the project external subdirectores to the LY_EXTERNAL_SUBDIRS_ENGINE property
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS_ENGINE ${real_external_subdir})
|
||||
add_engine_gem_json_external_subdirectories(${real_external_subdir})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(add_engine_json_external_subdirectories)
|
||||
set(engine_json_path ${LY_ROOT_FOLDER}/engine.json)
|
||||
if(EXISTS ${engine_json_path})
|
||||
read_json_external_subdirs(engine_external_subdirs ${engine_json_path})
|
||||
foreach(engine_external_subdir ${engine_external_subdirs})
|
||||
file(REAL_PATH ${engine_external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER})
|
||||
|
||||
# Append external subdirectory if it is not in global property
|
||||
get_property(current_external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
if(NOT real_external_subdir IN_LIST current_external_subdirs)
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
|
||||
# Also append the project external subdirectores to the LY_EXTERNAL_SUBDIRS_ENGINE property
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS_ENGINE ${real_external_subdir})
|
||||
add_engine_gem_json_external_subdirectories(${real_external_subdir})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(add_project_gem_json_external_subdirectories gem_path project_name)
|
||||
set(gem_json_path ${gem_path}/gem.json)
|
||||
if(EXISTS ${gem_json_path})
|
||||
read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json)
|
||||
foreach(gem_external_subdir ${gem_external_subdirs})
|
||||
file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path})
|
||||
|
||||
# Append external subdirectory if it is not in global property
|
||||
get_property(current_external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
if(NOT real_external_subdir IN_LIST current_external_subdirs)
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
|
||||
# Also append the project external subdirectores to the LY_EXTERNAL_SUBDIRS_${project_name} property
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS_${project_name} ${real_external_subdir})
|
||||
add_project_gem_json_external_subdirectories(${real_external_subdir} "${project_name}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(add_project_json_external_subdirectories project_path project_name)
|
||||
set(project_json_path ${project_path}/project.json)
|
||||
if(EXISTS ${project_json_path})
|
||||
read_json_external_subdirs(project_external_subdirs ${project_path}/project.json)
|
||||
foreach(project_external_subdir ${project_external_subdirs})
|
||||
file(REAL_PATH ${project_external_subdir} real_external_subdir BASE_DIRECTORY ${project_path})
|
||||
|
||||
# Append external subdirectory if it is not in global property
|
||||
get_property(current_external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
if(NOT real_external_subdir IN_LIST current_external_subdirs)
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${real_external_subdir})
|
||||
# Also append the project external subdirectores to the LY_EXTERNAL_SUBDIRS_${project_name} property
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS_${project_name} ${real_external_subdir})
|
||||
add_project_gem_json_external_subdirectories(${real_external_subdir} "${project_name}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
#! add_o3de_manifest_gem_json_external_subdirectories : Recurses through external subdirectories
|
||||
#! originally found in the add_o3de_manifest_json_external_subdirectories command
|
||||
function(add_o3de_manifest_gem_json_external_subdirectories gem_path)
|
||||
set(gem_json_path ${gem_path}/gem.json)
|
||||
if(EXISTS ${gem_json_path})
|
||||
read_json_external_subdirs(gem_external_subdirs ${gem_path}/gem.json)
|
||||
foreach(gem_external_subdir ${gem_external_subdirs})
|
||||
file(REAL_PATH ${gem_external_subdir} real_external_subdir BASE_DIRECTORY ${gem_path})
|
||||
|
||||
# Append external subdirectory ONLY to LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST PROPERTY
|
||||
# It is not appended to LY_EXTERNAL_SUBDIRS unless that gem is used by the project
|
||||
get_property(current_external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST)
|
||||
if(NOT real_external_subdir IN_LIST current_external_subdirs)
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST ${real_external_subdir})
|
||||
add_o3de_manifest_gem_json_external_subdirectories(${real_external_subdir})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#! add_o3de_manifest_json_external_subdirectories : Adds the list of external_subdirectories
|
||||
#! in the user o3de_manifest.json to the LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST property
|
||||
function(add_o3de_manifest_json_external_subdirectories)
|
||||
o3de_get_manifest_path(manifest_path)
|
||||
if(EXISTS ${manifest_path})
|
||||
read_json_external_subdirs(o3de_manifest_external_subdirs ${manifest_path})
|
||||
foreach(manifest_external_subdir ${o3de_manifest_external_subdirs})
|
||||
file(REAL_PATH ${manifest_external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER})
|
||||
|
||||
# Append external subdirectory ONLY to LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST PROPERTY
|
||||
# It is not appended to LY_EXTERNAL_SUBDIRS unless that gem is used by the project
|
||||
get_property(current_external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST)
|
||||
if(NOT real_external_subdir IN_LIST current_external_subdirs)
|
||||
set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST ${real_external_subdir})
|
||||
add_o3de_manifest_gem_json_external_subdirectories(${real_external_subdir})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#! Gather unique_list of all external subdirectories that is union
|
||||
#! of the engine.json, project.json, o3de_manifest.json and any gem.json files found visiting
|
||||
function(get_all_external_subdirectories output_subdirs)
|
||||
get_property(all_external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
get_property(manifest_external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS_O3DE_MANIFEST)
|
||||
list(APPEND all_external_subdirs ${manifest_external_subdirs})
|
||||
list(REMOVE_DUPLICATES all_external_subdirs)
|
||||
set(${output_subdirs} ${all_external_subdirs} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#! add_registered_gems_to_external_subdirs:
|
||||
#! Accepts a list of gem_names (which can be read from the project.json or engine.json)
|
||||
#! and cross checks them against union of all external subdirectories to determine the gem path.
|
||||
#! If that gem exist it is appended to LY_EXTERNAL_SUBDIRS so that that the build generator
|
||||
#! adds to the generated build project.
|
||||
#! Otherwise a fatal error is logged indicating that is not gem could not be found in the list of external subdirectories
|
||||
function(add_registered_gems_to_external_subdirs gem_names)
|
||||
if (gem_names)
|
||||
get_all_external_subdirectories(all_external_subdirs)
|
||||
foreach(gem_name IN LISTS gem_names)
|
||||
unset(gem_path)
|
||||
o3de_find_gem(${gem_name} gem_path)
|
||||
if (gem_path)
|
||||
set_property(GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS ${gem_path} APPEND)
|
||||
else()
|
||||
list(JOIN all_external_subdirs "\n" external_subdirs_formatted)
|
||||
message(SEND_ERROR "The gem \"${gem_name}\" from the \"gem_names\" field in the engine.json/project.json "
|
||||
" could not be found in any gem.json from the following list of registered external subdirectories:\n"
|
||||
"${external_subdirs_formatted}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(add_subdirectory_on_external_subdirs)
|
||||
# Lookup the paths of "gem_names" array all project.json files and engine.json
|
||||
# and append them to the LY_EXTERNAL_SUBDIRS property
|
||||
foreach(project ${LY_PROJECTS})
|
||||
file(REAL_PATH ${project} full_directory_path BASE_DIRECTORY ${CMAKE_SOURCE_DIR})
|
||||
o3de_read_json_array(gem_names ${full_directory_path}/project.json "gem_names")
|
||||
add_registered_gems_to_external_subdirs("${gem_names}")
|
||||
endforeach()
|
||||
o3de_read_json_array(gem_names ${LY_ROOT_FOLDER}/engine.json "gem_names")
|
||||
add_registered_gems_to_external_subdirs("${gem_names}")
|
||||
|
||||
get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS)
|
||||
list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs})
|
||||
list(REMOVE_DUPLICATES LY_EXTERNAL_SUBDIRS)
|
||||
# Loop over the additional external subdirectories and invoke add_subdirectory on them
|
||||
foreach(external_directory ${LY_EXTERNAL_SUBDIRS})
|
||||
# Hash the external_directory name and append it to the Binary Directory section of add_subdirectory
|
||||
# This is to deal with potential situations where multiple external directories has the same last directory name
|
||||
# For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory
|
||||
file(REAL_PATH ${external_directory} full_directory_path)
|
||||
string(SHA256 full_directory_hash ${full_directory_path})
|
||||
# Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit
|
||||
# when the external subdirectory contains relative paths of significant length
|
||||
string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash)
|
||||
# Use the last directory as the suffix path to use for the Binary Directory
|
||||
cmake_path(GET external_directory FILENAME directory_name)
|
||||
add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash})
|
||||
endforeach()
|
||||
endfunction()
|
||||
@@ -35,6 +35,7 @@ set(FILES
|
||||
Projects.cmake
|
||||
RuntimeDependencies.cmake
|
||||
SettingsRegistry.cmake
|
||||
Subdirectories.cmake
|
||||
UnitTest.cmake
|
||||
Version.cmake
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user