Fixed creation of paths in the install layout for external source paths (#2152)
* Fixed creation of paths in the install layout for external source paths Any source path that is not within the engine root is now copied to an External directory within the engine root Updated the gem copy regex to include the preview.png file and Editor/Scripts directory Added an ly_add_install_paths function for installing a list of paths to the install layout Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Moved the ly_get_last_path_segment_concat_sha256 and ly_get_engine_relative_source_dir functions to cmake/FileUtil.cmake Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
91de09cff5
commit
fcef9333a7
@@ -124,3 +124,42 @@ function(ly_file_read path content)
|
||||
set(${content} ${file_content} PARENT_SCOPE)
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${path})
|
||||
endfunction()
|
||||
|
||||
|
||||
#! ly_get_last_path_segment_concat_sha256 : Concatenates the last path segment of the absolute path
|
||||
# with the first 8 characters of the absolute path SHA256 hash to make a unique relative path segment
|
||||
function(ly_get_last_path_segment_concat_sha256 absolute_path output_path)
|
||||
string(SHA256 target_source_hash ${absolute_path})
|
||||
string(SUBSTRING ${target_source_hash} 0 8 target_source_hash)
|
||||
cmake_path(GET absolute_path FILENAME last_path_segment)
|
||||
cmake_path(SET last_path_segment_sha256_path "${last_path_segment}-${target_source_hash}")
|
||||
|
||||
set(${output_path} ${last_path_segment_sha256_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
|
||||
function(ly_get_engine_relative_source_dir absolute_target_source_dir output_source_dir)
|
||||
|
||||
set(options)
|
||||
set(oneValueArgs BASE_DIRECTORY)
|
||||
set(multiValueArgs)
|
||||
cmake_parse_arguments(ly_get_engine_relative_source_dir "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
if(NOT ly_get_engine_relative_source_dir_BASE_DIRECTORY)
|
||||
set(ly_get_engine_relative_source_dir_BASE_DIRECTORY ${LY_ROOT_FOLDER})
|
||||
endif()
|
||||
|
||||
# Get a relative target source directory to the LY root folder if possible
|
||||
# Otherwise use the final component name
|
||||
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)
|
||||
unset(relative_target_source_dir)
|
||||
cmake_path(APPEND relative_target_source_dir "External" ${target_source_dir_last_path_segment})
|
||||
endif()
|
||||
|
||||
set(${output_source_dir} ${relative_target_source_dir} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#
|
||||
#
|
||||
|
||||
include(cmake/FileUtil.cmake)
|
||||
|
||||
set(CMAKE_INSTALL_MESSAGE NEVER) # Simplify messages to reduce output noise
|
||||
|
||||
ly_set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Core)
|
||||
@@ -18,26 +20,6 @@ cmake_path(RELATIVE_PATH CMAKE_LIBRARY_OUTPUT_DIRECTORY BASE_DIRECTORY ${CMAKE_B
|
||||
set(install_output_folder "\${CMAKE_INSTALL_PREFIX}/${runtime_output_directory}/${PAL_PLATFORM_NAME}/$<CONFIG>")
|
||||
|
||||
|
||||
function(ly_get_engine_relative_source_dir absolute_target_source_dir output_source_dir)
|
||||
# Get a relative target source directory to the LY root folder if possible
|
||||
# Otherwise use the final component name
|
||||
cmake_path(IS_PREFIX LY_ROOT_FOLDER ${absolute_target_source_dir} is_target_prefix_of_engine_root)
|
||||
if(is_target_prefix_of_engine_root)
|
||||
cmake_path(RELATIVE_PATH absolute_target_source_dir BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE relative_target_source_dir)
|
||||
else()
|
||||
# In this case the target source directory is outside of the engine root of the target source directory and concatenate the first
|
||||
# is used first 8 characters of the absolute path SHA256 hash to make a unique relative directory
|
||||
# that can be used to install the generated CMakeLists.txt
|
||||
# of a SHA256 hash
|
||||
string(SHA256 target_source_hash ${absolute_target_source_dir})
|
||||
string(SUBSTRING ${target_source_hash} 0 8 target_source_hash)
|
||||
cmake_path(GET absolute_target_source_dir FILENAME target_source_dirname)
|
||||
cmake_path(SET relative_target_source_dir "${target_source_dirname}-${target_source_hash}")
|
||||
endif()
|
||||
|
||||
set(${output_source_dir} ${relative_target_source_dir} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#! ly_setup_target: Setup the data needed to re-create the cmake target commands for a single target
|
||||
function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_target_source_dir)
|
||||
# De-alias target name
|
||||
@@ -254,7 +236,6 @@ endfunction()
|
||||
|
||||
#! ly_setup_subdirectory: setup all targets in the subdirectory
|
||||
function(ly_setup_subdirectory absolute_target_source_dir)
|
||||
# Get the target source directory relative to the LY roo folder
|
||||
ly_get_engine_relative_source_dir(${absolute_target_source_dir} relative_target_source_dir)
|
||||
|
||||
# The builtin BUILDSYSTEM_TARGETS property isn't being used here as that returns the de-alised
|
||||
@@ -540,56 +521,74 @@ function(ly_setup_others)
|
||||
)
|
||||
# Exclude transient artifacts that shouldn't be copied to the install layout
|
||||
list(FILTER external_subdir_files EXCLUDE REGEX "/([Bb]uild|[Cc]ache|[Uu]ser)$")
|
||||
list(APPEND filtered_asset_paths ${external_subdir_files})
|
||||
# Storing a "mapping" of gem candidate directories, to external_subdirectory files using
|
||||
# a DIRECTORY property for the "value" and the GLOBAL property for the "key"
|
||||
set_property(DIRECTORY ${gem_candidate_dir} APPEND PROPERTY directory_filtered_asset_paths "${external_subdir_files}")
|
||||
set_property(GLOBAL APPEND PROPERTY global_gem_candidate_dirs_prop ${gem_candidate_dir})
|
||||
endforeach()
|
||||
|
||||
# At this point the filtered_assets_paths contains the list of all directories and files
|
||||
# that are non-excluded candidates that can be scanned for target directories and files
|
||||
# to copy over to the install layout
|
||||
foreach(filtered_asset_path IN LISTS filtered_asset_paths)
|
||||
if(IS_DIRECTORY ${filtered_asset_path})
|
||||
file(GLOB_RECURSE
|
||||
recurse_assets_paths
|
||||
LIST_DIRECTORIES TRUE
|
||||
"${filtered_asset_path}/*"
|
||||
)
|
||||
set(gem_file_paths ${recurse_assets_paths})
|
||||
# Make sure to prepend the current path iteration to the gem_dirs_path to filter
|
||||
set(gem_dir_paths ${filtered_asset_path} ${recurse_assets_paths})
|
||||
# Iterate over each gem candidate directories and read 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)
|
||||
|
||||
# At this point the filtered_assets_paths contains the list of all directories and files
|
||||
# that are non-excluded candidates that can be scanned for target directories and files
|
||||
# to copy over to the install layout
|
||||
foreach(filtered_asset_path IN LISTS filtered_asset_paths)
|
||||
if(IS_DIRECTORY ${filtered_asset_path})
|
||||
file(GLOB_RECURSE
|
||||
recurse_assets_paths
|
||||
LIST_DIRECTORIES TRUE
|
||||
"${filtered_asset_path}/*"
|
||||
)
|
||||
set(gem_file_paths ${recurse_assets_paths})
|
||||
# Make sure to prepend the current path iteration to the gem_dirs_path to filter
|
||||
set(gem_dir_paths ${filtered_asset_path} ${recurse_assets_paths})
|
||||
|
||||
# Gather directories to copy over
|
||||
# Currently only the Assets, Registry and Config directories are copied over
|
||||
list(FILTER gem_dir_paths INCLUDE REGEX "/(Assets|Registry|Config)$")
|
||||
list(APPEND gems_assets_dir_path ${gem_dir_paths})
|
||||
else()
|
||||
set(gem_file_paths ${filtered_asset_path})
|
||||
endif()
|
||||
# Gather directories to copy over
|
||||
# Currently only the Assets, Registry and Config directories are copied over
|
||||
list(FILTER gem_dir_paths INCLUDE REGEX "/(Assets|Registry|Config|Editor/Scripts)$")
|
||||
set_property(DIRECTORY ${gem_candidate_dir} APPEND PROPERTY gems_assets_paths ${gem_dir_paths})
|
||||
else()
|
||||
set(gem_file_paths ${filtered_asset_path})
|
||||
endif()
|
||||
|
||||
# Gather files to copy over
|
||||
# Currently only the gem.json file is copied over
|
||||
list(FILTER gem_file_paths INCLUDE REGEX "/(gem.json)$")
|
||||
list(APPEND gems_assets_file_path "${gem_file_paths}")
|
||||
endforeach()
|
||||
# Gather files to copy over
|
||||
# Currently only the gem.json file is copied over
|
||||
list(FILTER gem_file_paths INCLUDE REGEX "/(gem.json|preview.png)$")
|
||||
set_property(DIRECTORY ${gem_candidate_dir} APPEND PROPERTY gems_assets_paths "${gem_file_paths}")
|
||||
endforeach()
|
||||
|
||||
# gem directories to install
|
||||
foreach(gem_absolute_dir_path ${gems_assets_dir_path})
|
||||
cmake_path(RELATIVE_PATH gem_absolute_dir_path BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE gem_relative_dir_path)
|
||||
if (EXISTS ${gem_absolute_dir_path})
|
||||
# The trailing slash is IMPORTANT here as that is needed to prevent
|
||||
# the "Assets" folder from being copied underneath the <gem-root>/Assets folder
|
||||
install(DIRECTORY "${gem_absolute_dir_path}/"
|
||||
DESTINATION ${gem_relative_dir_path}
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
# gem directories and files to install
|
||||
get_property(gems_assets_dir_path 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)
|
||||
unset(gem_install_dest_dir)
|
||||
cmake_path(APPEND gem_install_dest_dir "External" ${last_gem_root_path_segment} ${gem_relative_path})
|
||||
endif()
|
||||
|
||||
cmake_path(GET gem_install_dest_dir PARENT_PATH gem_install_dest_dir)
|
||||
if (NOT gem_install_dest_dir)
|
||||
cmake_path(SET gem_install_dest_dir .)
|
||||
endif()
|
||||
if(IS_DIRECTORY ${gem_absolute_path})
|
||||
install(DIRECTORY "${gem_absolute_path}" DESTINATION ${gem_install_dest_dir})
|
||||
elseif (EXISTS ${gem_absolute_path})
|
||||
install(FILES ${gem_absolute_path} DESTINATION ${gem_install_dest_dir})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# gem files to install
|
||||
foreach(gem_absolute_file_path ${gems_assets_file_path})
|
||||
cmake_path(RELATIVE_PATH gem_absolute_file_path BASE_DIRECTORY ${LY_ROOT_FOLDER} OUTPUT_VARIABLE gem_relative_file_path)
|
||||
cmake_path(GET gem_relative_file_path PARENT_PATH gem_relative_parent_dir)
|
||||
install(FILES ${gem_absolute_file_path}
|
||||
DESTINATION ${gem_relative_parent_dir}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Templates
|
||||
@@ -626,3 +625,46 @@ function(ly_setup_target_generator)
|
||||
)
|
||||
|
||||
endfunction()
|
||||
|
||||
#! ly_add_install_paths: Adds the list of path to copy to the install layout relative to the same folder
|
||||
# \arg:PATHS - Paths to copy over to the install layout. The DESTINATION sub argument is optional
|
||||
# The INPUT sub-argument is required
|
||||
# \arg:BASE_DIRECTORY(Optional) - Absolute path where a relative path from the each input path will be
|
||||
# based off of. Defaults to LY_ROOT_FOLDER if not supplied
|
||||
function(ly_add_install_paths)
|
||||
set(options)
|
||||
set(oneValueArgs BASE_DIRECTORY)
|
||||
set(multiValueArgs PATHS)
|
||||
cmake_parse_arguments(ly_add_install_paths "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
if(NOT ly_add_install_paths_PATHS)
|
||||
message(FATAL_ERROR "ly_add_install_paths requires at least one input path to copy to the destination")
|
||||
endif()
|
||||
|
||||
# The default is the "." directory if not supplied
|
||||
if(NOT ly_add_install_paths_BASE_DIRECTORY)
|
||||
cmake_path(SET ly_add_install_paths_BASE_DIRECTORY ${LY_ROOT_FOLDER})
|
||||
endif()
|
||||
|
||||
# Separate each path into an INPUT and DESTINATION parameter
|
||||
set(options)
|
||||
set(oneValueArgs INPUT DESTINATION)
|
||||
set(multiValueArgs)
|
||||
foreach(install_path IN LISTS ly_add_install_paths_PATHS)
|
||||
string(REPLACE " " ";" install_path ${install_path})
|
||||
cmake_parse_arguments(install "${options}" "${oneValueArgs}" "${multiValueArgs}" ${install_path})
|
||||
if(NOT install_DESTINATION)
|
||||
ly_get_engine_relative_source_dir(${install_INPUT} rel_to_root_input_path
|
||||
BASE_DIRECTORY ${ly_add_install_paths_BASE_DIRECTORY})
|
||||
cmake_path(GET rel_to_root_input_path PARENT_PATH install_DESTINATION)
|
||||
endif()
|
||||
if(NOT install_DESTINATION)
|
||||
cmake_path(SET install_DESTINATION .)
|
||||
endif()
|
||||
if(IS_DIRECTORY ${install_INPUT})
|
||||
install(DIRECTORY ${install_INPUT} DESTINATION ${install_DESTINATION})
|
||||
elseif(EXISTS ${install_INPUT})
|
||||
install(FILES ${install_INPUT} DESTINATION ${install_DESTINATION})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
endfunction()
|
||||
|
||||
Reference in New Issue
Block a user