[cmake,configure_file] fix change checks

* Create temporary configuration files in a different build directory
* Copy the currently required configuration file only if it is different
  from the currently set one
* Use copy_if_different for build target configuration update
This commit is contained in:
akallabeth
2024-12-10 12:38:43 +01:00
parent 9eaf7d5656
commit e16085762d

View File

@@ -10,17 +10,28 @@ function(cleaning_configure_file RSRC RDST)
get_filename_component(SRC "${RSRC}" ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
get_filename_component(DST "${RDST}" ABSOLUTE BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
get_filename_component(DST_DIR "${DST}" DIRECTORY)
get_filename_component(DST_NAME ${DST} NAME)
# ensure the temporary configuration files are in a different directory
set(CFG_DIR "${CMAKE_CURRENT_BINARY_DIR}/cfg")
file(MAKE_DIRECTORY "${CFG_DIR}")
# Generate the temporary configuration files
if(CMAKE_CONFIGURATION_TYPES)
foreach(CFG ${CMAKE_CONFIGURATION_TYPES})
set(CURRENT_BUILD_CONFIG ${CFG})
if(NOT SOURCE_CFG_INIT)
set(SOURCE_CFG_INIT "${CFG_DIR}/${DST_NAME}_${CFG}")
endif()
cflagstovar(CURRENT_C_FLAGS ${CURRENT_BUILD_CONFIG})
configure_file(${SRC} ${DST}_${CFG} ${ARGN})
configure_file(${SRC} "${CFG_DIR}/${DST_NAME}_${CFG}" ${ARGN})
unset(CURRENT_BUILD_CONFIG)
unset(CURRENT_C_FLAGS)
endforeach()
set(SOURCE_CFG "${CFG_DIR}/${DST_NAME}_$<CONFIG>")
else()
# We call this also from CMake scripts without a CMAKE_BUILD_TYPE
# Fall back to an explicitly unsupported build type to point out something is wrond
# Fall back to an explicitly unsupported build type to point out something is wrong
# if this variable is used during such a call
if(CMAKE_BUILD_TYPE)
set(CURRENT_BUILD_CONFIG ${CMAKE_BUILD_TYPE})
@@ -28,20 +39,32 @@ function(cleaning_configure_file RSRC RDST)
set(CURRENT_BUILD_CONFIG "InvalidBuildType")
endif()
cflagstovar(CURRENT_C_FLAGS ${CURRENT_BUILD_CONFIG})
configure_file(${SRC} ${DST}_${CMAKE_BUILD_TYPE} ${ARGN})
set(SOURCE_CFG "${CFG_DIR}/${DST_NAME}_${CMAKE_BUILD_TYPE}")
set(SOURCE_CFG_INIT "${SOURCE_CFG}")
configure_file(${SRC} "${SOURCE_CFG}" ${ARGN})
unset(CURRENT_BUILD_CONFIG)
unset(CURRENT_C_FLAGS)
endif()
configure_file(${SRC} ${DST} ${ARGN})
# Fallback for older CMake: we want to copy only if the destination is different.
# First do an initial copy during configuration
file(MAKE_DIRECTORY "${DST_DIR}")
if(CMAKE_VERSION VERSION_LESS "3.21.0")
get_filename_component(CFG_VAR ${SOURCE_CFG_INIT} NAME)
file(COPY ${SOURCE_CFG_INIT} DESTINATION ${DST_DIR})
set(CFG_VAR_ABS "${DST_DIR}/${CFG_VAR}")
file(RENAME ${CFG_VAR_ABS} ${DST})
else()
file(COPY_FILE ${SOURCE_CFG_INIT} ${DST} ONLY_IF_DIFFERENT)
endif()
# Create a target to recreate the configuration file if something changes.
string(SHA256 DST_HASH "${DST}")
if(NOT TARGET ct-${DST_HASH})
add_custom_target(
ct-${DST_HASH} ALL COMMAND ${CMAKE_COMMAND} "-E" "make_directory" "${DST_DIR}"
COMMAND ${CMAKE_COMMAND} "-E" "copy" "${DST}_$<CONFIG>" "${DST}" COMMAND ${CMAKE_COMMAND} "-E" "sha256sum"
"${DST}_$<CONFIG>" > ${DST}.hash
DEPENDS ${DST} BYPRODUCTS ${DST}.hash
COMMAND ${CMAKE_COMMAND} "-E" "copy_if_different" "${SOURCE_CFG}" "${DST}" DEPENDS ${SOURCE_CFG}
BYPRODUCTS ${DST}
)
endif()
endfunction()