diff --git a/CMakeLists.txt b/CMakeLists.txt index d743a8ab57..83c9d7d14f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,11 +53,22 @@ include(cmake/Monolithic.cmake) include(cmake/SettingsRegistry.cmake) include(cmake/TestImpactFramework/LYTestImpactFramework.cmake) include(cmake/CMakeFiles.cmake) +include(cmake/O3DEJson.cmake) ################################################################################ # Subdirectory processing ################################################################################ +function(add_engine_json_external_subdirectories) + read_json_external_subdirs(external_subdis ${LY_ROOT_FOLDER}/engine.json) + foreach(external_subdir ${external_subdis}) + file(REAL_PATH ${external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER}) + list(APPEND engine_external_subdirs ${real_external_subdir}) + endforeach() + + set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${engine_external_subdirs}) +endfunction() + # Add the projects first so the Launcher can find them include(cmake/Projects.cmake) @@ -73,11 +84,11 @@ if(NOT INSTALLED_ENGINE) add_subdirectory(Tools/RemoteConsole/ly_remote_console/tests/) endif() - include(cmake/EngineJson.cmake) # Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra # external subdirectories - read_engine_external_subdirs(engine_external_subdirectories) - list(APPEND LY_EXTERNAL_SUBDIRS ${engine_external_subdirectories}) + add_engine_json_external_subdirectories() + get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS) + list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs}) # Loop over the additional external subdirectories and invoke add_subdirectory on them foreach(external_directory ${LY_EXTERNAL_SUBDIRS}) diff --git a/Templates/DefaultGem/Template/CMakeLists.txt b/Templates/DefaultGem/Template/CMakeLists.txt index fb63008782..1a24bd488f 100644 --- a/Templates/DefaultGem/Template/CMakeLists.txt +++ b/Templates/DefaultGem/Template/CMakeLists.txt @@ -11,7 +11,7 @@ set(o3de_gem_path ${CMAKE_CURRENT_LIST_DIR}) set(o3de_gem_json ${o3de_gem_path}/gem.json) -o3de_gem_name(${o3de_gem_json} o3de_gem_name) +o3de_read_json_key(o3de_gem_name ${o3de_gem_json} "gem_name") o3de_restricted_path(${o3de_gem_json} o3de_gem_restricted_path) # Currently we are in the DefaultProjectSource folder: ${CMAKE_CURRENT_LIST_DIR} diff --git a/cmake/O3DEJson.cmake b/cmake/O3DEJson.cmake new file mode 100644 index 0000000000..5d748e9681 --- /dev/null +++ b/cmake/O3DEJson.cmake @@ -0,0 +1,55 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +include_guard() + +set(LY_EXTERNAL_SUBDIRS "" CACHE STRING "List of subdirectories to recurse into when running cmake against the engine's CMakeLists.txt") + +#! read_json_external_subdirs +# Read the "external_subdirectories" array from a *.json file +# External subdirectories are any folders with CMakeLists.txt in them +# This could be regular subdirectories, Gems(contains an additional gem.json), +# Restricted folders(contains an additional restricted.json), etc... +# +# \arg:output_external_subdirs name of output variable to store external subdirectories into +# \arg:input_json_path path to the *.json file to load and read the external subdirectories from +# \return: external subdirectories as is from the json file. +function(read_json_external_subdirs output_external_subdirs input_json_path) + file(READ ${input_json_path} manifest_json_data) + string(JSON external_subdirs_count ERROR_VARIABLE manifest_json_error + LENGTH ${manifest_json_data} "external_subdirectories") + if(manifest_json_error) + # There is "external_subdirectories" key, so theire are no subdirectories to read + return() + endif() + + if(external_subdirs_count GREATER 0) + math(EXPR external_subdir_range "${external_subdirs_count}-1") + foreach(external_subdir_index RANGE ${external_subdir_range}) + string(JSON external_subdir ERROR_VARIABLE manifest_json_error + GET ${manifest_json_data} "external_subdirectories" "${external_subdir_index}") + if(manifest_json_error) + message(FATAL_ERROR "Error reading field at index ${external_subdir_index} in \"external_subdirectories\" JSON array: ${manifest_json_error}") + endif() + list(APPEND external_subdirs ${external_subdir}) + endforeach() + endif() + set(${output_external_subdirs} ${external_subdirs} PARENT_SCOPE) +endfunction() + +function(o3de_read_json_key output_value input_json_path key) + file(READ ${input_json_path} manifest_json_data) + string(JSON value ERROR_VARIABLE manifest_json_error GET ${manifest_json_data} ${key}) + if(manifest_json_error) + message(FATAL_ERROR "Error reading field at key ${key} in file \"${input_json_path}\" : ${manifest_json_error}") + endif() + set(${output_value} ${value} PARENT_SCOPE) +endfunction() diff --git a/cmake/Projects.cmake b/cmake/Projects.cmake index 781fee3711..297dad4ddf 100644 --- a/cmake/Projects.cmake +++ b/cmake/Projects.cmake @@ -105,6 +105,7 @@ function(ly_add_project_dependencies) ) endfunction() + #template for generating the project build_path setreg set(project_build_path_template [[ { @@ -120,7 +121,6 @@ set(project_build_path_template [[ }]] ) - #! ly_generate_project_build_path_setreg: Generates a .setreg file that contains an absolute path to the ${CMAKE_BINARY_DIR} # This allows locate the directory where the project it's binaries are built to be located within the engine. # Which are the shared libraries and launcher executables @@ -136,18 +136,32 @@ set(project_build_path_template [[ # can only run on the host platform # \arg:project_real_path Full path to the o3de project directory function(ly_generate_project_build_path_setreg project_real_path) - # The build path isn't needed on non-monolithic platforms - # Nor on any non-host platforms - if (LY_MONOLITHIC_GAME OR NOT PAL_TRAIT_BUILD_HOST_TOOLS) - return() - endif() + # The build path isn't needed on non-monolithic platforms + # Nor on any non-host platforms + if (LY_MONOLITHIC_GAME OR NOT PAL_TRAIT_BUILD_HOST_TOOLS) + return() + endif() + + # Set the project_bin_path to the ${CMAKE_BINARY_DIR} to provide the configure template + # with the project build directory + set(project_bin_path ${CMAKE_BINARY_DIR}) + string(CONFIGURE ${project_build_path_template} project_build_path_setreg_content @ONLY) + set(project_user_build_path_setreg_file ${project_real_path}/user/Registry/Platform/${PAL_PLATFORM_NAME}/build_path.setreg) + file(GENERATE OUTPUT ${project_user_build_path_setreg_file} CONTENT ${project_build_path_setreg_content}) +endfunction() + - # Set the project_bin_path to the ${CMAKE_BINARY_DIR} to provide the configure template - # with the project build directory - set(project_bin_path ${CMAKE_BINARY_DIR}) - string(CONFIGURE ${project_build_path_template} project_build_path_setreg_content @ONLY) - set(project_user_build_path_setreg_file ${project_real_path}/user/Registry/Platform/${PAL_PLATFORM_NAME}/build_path.setreg) - file(GENERATE OUTPUT ${project_user_build_path_setreg_file} CONTENT ${project_build_path_setreg_content}) +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(external_subdirs ${project_path}/project.json) + foreach(external_subdir ${external_subdirs}) + file(REAL_PATH ${external_subdir} real_external_subdir BASE_DIRECTORY ${project_path}) + list(APPEND project_external_subdirs ${real_external_subdir}) + endforeach() + + set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${project_external_subdirs}) + endif() endfunction() # Add the projects here so the above function is found @@ -163,5 +177,6 @@ foreach(project ${LY_PROJECTS}) 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}) endforeach() ly_set(LY_PROJECTS_FOLDER_NAME ${LY_PROJECTS_FOLDER_NAME})