144 lines
8.1 KiB
CMake
144 lines
8.1 KiB
CMake
function(package_collect_matches output root pattern)
|
|
string(REPLACE "\\" "/" pattern "${pattern}")
|
|
string(REGEX REPLACE "^/+" "" pattern "${pattern}")
|
|
if(pattern STREQUAL "")
|
|
set(${output} PARENT_SCOPE)
|
|
return()
|
|
endif()
|
|
if(pattern MATCHES "/$")
|
|
string(REGEX REPLACE "/+$" "" pattern "${pattern}")
|
|
file(GLOB_RECURSE matched_files LIST_DIRECTORIES false RELATIVE "${root}" "${root}/${pattern}/*")
|
|
else()
|
|
string(FIND "${pattern}" "*" wildcard_star)
|
|
string(FIND "${pattern}" "?" wildcard_question)
|
|
if(NOT wildcard_star EQUAL -1 OR NOT wildcard_question EQUAL -1)
|
|
file(GLOB_RECURSE matched_files LIST_DIRECTORIES false RELATIVE "${root}" "${root}/${pattern}")
|
|
elseif(EXISTS "${root}/${pattern}" AND NOT IS_DIRECTORY "${root}/${pattern}")
|
|
set(matched_files "${pattern}")
|
|
else()
|
|
set(matched_files)
|
|
endif()
|
|
endif()
|
|
set(${output} ${matched_files} PARENT_SCOPE)
|
|
endfunction()
|
|
if(PACKAGE_ZIP_RUN)
|
|
file(STRINGS "${PACKAGE_INCLUDE_FILE}" package_includes)
|
|
file(STRINGS "${PACKAGE_EXCLUDE_FILE}" package_excludes)
|
|
set(package_files)
|
|
foreach(include_pattern IN LISTS package_includes)
|
|
package_collect_matches(matched_files "${PACKAGE_ROOT}" "${include_pattern}")
|
|
list(APPEND package_files ${matched_files})
|
|
endforeach()
|
|
list(REMOVE_DUPLICATES package_files)
|
|
set(excluded_files)
|
|
foreach(exclude_pattern IN LISTS package_excludes)
|
|
package_collect_matches(matched_files "${PACKAGE_ROOT}" "${exclude_pattern}")
|
|
list(APPEND excluded_files ${matched_files})
|
|
endforeach()
|
|
if(excluded_files)
|
|
list(REMOVE_DUPLICATES excluded_files)
|
|
list(REMOVE_ITEM package_files ${excluded_files})
|
|
endif()
|
|
foreach(internal_file IN ITEMS "${PACKAGE_OUTPUT_FILE}" "${PACKAGE_FILE_LIST}" "${PACKAGE_INCLUDE_FILE}" "${PACKAGE_EXCLUDE_FILE}")
|
|
file(RELATIVE_PATH internal_relative "${PACKAGE_ROOT}" "${internal_file}")
|
|
string(REPLACE "\\" "/" internal_relative "${internal_relative}")
|
|
if(NOT internal_relative MATCHES "^\\.\\./")
|
|
list(REMOVE_ITEM package_files "${internal_relative}")
|
|
endif()
|
|
endforeach()
|
|
set(package_archive_root "${PACKAGE_ROOT}")
|
|
if(DEFINED PACKAGE_OVERLAY_ROOT AND NOT PACKAGE_OVERLAY_ROOT STREQUAL "")
|
|
if(NOT DEFINED PACKAGE_OVERLAY_PREFIX OR PACKAGE_OVERLAY_PREFIX STREQUAL "" OR PACKAGE_OVERLAY_PREFIX MATCHES "(^|/)\.\.(/|$)")
|
|
message(FATAL_ERROR "PACKAGE_OVERLAY_PREFIX must be a non-empty relative path")
|
|
endif()
|
|
file(STRINGS "${PACKAGE_OVERLAY_INCLUDE_FILE}" package_overlay_includes)
|
|
file(STRINGS "${PACKAGE_OVERLAY_EXCLUDE_FILE}" package_overlay_excludes)
|
|
set(package_overlay_files)
|
|
foreach(include_pattern IN LISTS package_overlay_includes)
|
|
package_collect_matches(matched_files "${PACKAGE_OVERLAY_ROOT}" "${include_pattern}")
|
|
list(APPEND package_overlay_files ${matched_files})
|
|
endforeach()
|
|
list(REMOVE_DUPLICATES package_overlay_files)
|
|
set(package_overlay_excluded_files)
|
|
foreach(exclude_pattern IN LISTS package_overlay_excludes)
|
|
package_collect_matches(matched_files "${PACKAGE_OVERLAY_ROOT}" "${exclude_pattern}")
|
|
list(APPEND package_overlay_excluded_files ${matched_files})
|
|
endforeach()
|
|
if(package_overlay_excluded_files)
|
|
list(REMOVE_DUPLICATES package_overlay_excluded_files)
|
|
list(REMOVE_ITEM package_overlay_files ${package_overlay_excluded_files})
|
|
endif()
|
|
set(package_stage "${PACKAGE_FILE_LIST}.stage")
|
|
file(REMOVE_RECURSE "${package_stage}")
|
|
file(MAKE_DIRECTORY "${package_stage}")
|
|
foreach(relative_path IN LISTS package_files)
|
|
get_filename_component(destination_dir "${package_stage}/${relative_path}" DIRECTORY)
|
|
file(MAKE_DIRECTORY "${destination_dir}")
|
|
configure_file("${PACKAGE_ROOT}/${relative_path}" "${package_stage}/${relative_path}" COPYONLY)
|
|
endforeach()
|
|
foreach(relative_path IN LISTS package_overlay_files)
|
|
set(destination "${package_stage}/${PACKAGE_OVERLAY_PREFIX}/${relative_path}")
|
|
get_filename_component(destination_dir "${destination}" DIRECTORY)
|
|
file(MAKE_DIRECTORY "${destination_dir}")
|
|
configure_file("${PACKAGE_OVERLAY_ROOT}/${relative_path}" "${destination}" COPYONLY)
|
|
endforeach()
|
|
file(GLOB_RECURSE package_files LIST_DIRECTORIES false RELATIVE "${package_stage}" "${package_stage}/*")
|
|
set(package_archive_root "${package_stage}")
|
|
endif()
|
|
list(SORT package_files)
|
|
string(REPLACE ";" "\n" package_file_list_content "${package_files}")
|
|
file(WRITE "${PACKAGE_FILE_LIST}" "${package_file_list_content}\n")
|
|
get_filename_component(package_output_dir "${PACKAGE_OUTPUT_FILE}" DIRECTORY)
|
|
file(MAKE_DIRECTORY "${package_output_dir}")
|
|
file(REMOVE "${PACKAGE_OUTPUT_FILE}")
|
|
execute_process(COMMAND "${CMAKE_COMMAND}" -E tar cf "${PACKAGE_OUTPUT_FILE}" --format=zip "--files-from=${PACKAGE_FILE_LIST}" WORKING_DIRECTORY "${package_archive_root}" RESULT_VARIABLE package_result)
|
|
if(NOT package_result EQUAL 0)
|
|
message(FATAL_ERROR "Failed to create ${PACKAGE_OUTPUT_FILE}")
|
|
endif()
|
|
return()
|
|
endif()
|
|
function(add_project_zip_target target_name output_file root_directory include_list_name exclude_list_name)
|
|
if(IS_ABSOLUTE "${root_directory}")
|
|
get_filename_component(package_root "${root_directory}" ABSOLUTE)
|
|
else()
|
|
get_filename_component(package_root "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${root_directory}" ABSOLUTE)
|
|
endif()
|
|
if(IS_ABSOLUTE "${output_file}")
|
|
get_filename_component(package_output_file "${output_file}" ABSOLUTE)
|
|
else()
|
|
get_filename_component(package_output_file "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${output_file}" ABSOLUTE)
|
|
endif()
|
|
set(package_file_list "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.files")
|
|
set(package_include_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.includes")
|
|
set(package_exclude_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.excludes")
|
|
string(REPLACE ";" "\n" package_include_content "${${include_list_name}}")
|
|
string(REPLACE ";" "\n" package_exclude_content "${${exclude_list_name}}")
|
|
file(WRITE "${package_include_file}" "${package_include_content}\n")
|
|
file(WRITE "${package_exclude_file}" "${package_exclude_content}\n")
|
|
set(package_overlay_arguments)
|
|
if(ARGC GREATER 5)
|
|
if(ARGC LESS 9)
|
|
message(FATAL_ERROR "Package overlay requires root, prefix, include-list name and exclude-list name")
|
|
endif()
|
|
get_filename_component(package_overlay_root "${ARGV5}" ABSOLUTE)
|
|
set(package_overlay_prefix "${ARGV6}")
|
|
set(package_overlay_include_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.overlay.includes")
|
|
set(package_overlay_exclude_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.overlay.excludes")
|
|
string(REPLACE ";" "\n" package_overlay_include_content "${${ARGV7}}")
|
|
string(REPLACE ";" "\n" package_overlay_exclude_content "${${ARGV8}}")
|
|
file(WRITE "${package_overlay_include_file}" "${package_overlay_include_content}\n")
|
|
file(WRITE "${package_overlay_exclude_file}" "${package_overlay_exclude_content}\n")
|
|
list(APPEND package_overlay_arguments
|
|
"-DPACKAGE_OVERLAY_ROOT=${package_overlay_root}"
|
|
"-DPACKAGE_OVERLAY_PREFIX=${package_overlay_prefix}"
|
|
"-DPACKAGE_OVERLAY_INCLUDE_FILE=${package_overlay_include_file}"
|
|
"-DPACKAGE_OVERLAY_EXCLUDE_FILE=${package_overlay_exclude_file}")
|
|
endif()
|
|
add_custom_target(${target_name}
|
|
COMMAND "${CMAKE_COMMAND}" -DPACKAGE_ZIP_RUN=ON "-DPACKAGE_ROOT=${package_root}" "-DPACKAGE_OUTPUT_FILE=${package_output_file}" "-DPACKAGE_FILE_LIST=${package_file_list}" "-DPACKAGE_INCLUDE_FILE=${package_include_file}" "-DPACKAGE_EXCLUDE_FILE=${package_exclude_file}" ${package_overlay_arguments} -P "${CMAKE_CURRENT_FUNCTION_LIST_FILE}"
|
|
BYPRODUCTS "${package_output_file}"
|
|
COMMENT "Creating ${package_output_file}"
|
|
VERBATIM
|
|
)
|
|
endfunction()
|