file(GENERATE): Setting source file properties on genex-expanded OUTPUT files
Followup for: #23130 (closed)
I have the following code
# Note: Don't use cmake_path, generator expression will break it.
# Additionally, this variable must be defined before configure_file is called.
set(REGISTER_MODULE_CPP "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${TARGETNAME}_mreg.cpp")
cmake_path(SET REGISTER_MODULE_CPP_IN NORMALIZE "${CMAKE_SOURCE_DIR}/cmake/templates/register_module.cpp.in")
cmake_path(SET REGISTER_MODULE_CPP_INTERMEDIATE NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/${TARGETNAME}_INTR_mreg.cpp")
configure_file(${REGISTER_MODULE_CPP_IN} ${REGISTER_MODULE_CPP_INTERMEDIATE})
file(GENERATE
OUTPUT ${REGISTER_MODULE_CPP}
INPUT ${REGISTER_MODULE_CPP_INTERMEDIATE}
TARGET ${TARGETNAME})
# And now add the register module file to the build.
target_sources(${TARGETNAME} PRIVATE ${REGISTER_MODULE_CPP})
# set_source_files_properties() doesn't work with files that have generator expressions in their filepath...
# As a result, the file path substitution commands below need to match REGISTER_MODULE_CPP above!
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(IS_MULTI_CONFIG)
foreach(config ${CMAKE_CONFIGURATION_TYPES})
# Add the necessary include dirs
set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/${config}/${TARGETNAME}_mreg.cpp" TARGET_DIRECTORY ${TARGETNAME} PROPERTIES INCLUDE_DIRECTORIES ${THE_INCLUDE_DIRS})
# Dont include in unity builds, it's generally not going to have a matching include directory list
set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/${config}/${TARGETNAME}_mreg.cpp" TARGET_DIRECTORY ${TARGETNAME} PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
endforeach()
else()
# Add the necessary include dirs
set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${TARGETNAME}_mreg.cpp" TARGET_DIRECTORY ${TARGETNAME} PROPERTIES INCLUDE_DIRECTORIES ${THE_INCLUDE_DIRS})
# Dont include in unity builds, it's generally not going to have a matching include directory list
set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${TARGETNAME}_mreg.cpp" TARGET_DIRECTORY ${TARGETNAME} PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
endif()
I want it to look like this
# Note: Don't use cmake_path, generator expression will break it.
# Additionally, this variable must be defined before configure_file is called.
set(REGISTER_MODULE_CPP "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${TARGETNAME}_mreg.cpp")
cmake_path(SET REGISTER_MODULE_CPP_IN NORMALIZE "${CMAKE_SOURCE_DIR}/cmake/templates/register_module.cpp.in")
cmake_path(SET REGISTER_MODULE_CPP_INTERMEDIATE NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/${TARGETNAME}_INTR_mreg.cpp")
configure_file(${REGISTER_MODULE_CPP_IN} ${REGISTER_MODULE_CPP_INTERMEDIATE})
file(GENERATE
OUTPUT ${REGISTER_MODULE_CPP}
INPUT ${REGISTER_MODULE_CPP_INTERMEDIATE}
TARGET ${TARGETNAME})
# And now add the register module file to the build.
target_sources(${TARGETNAME} PRIVATE ${REGISTER_MODULE_CPP})
# Add the necessary include dirs
set_source_files_properties(${REGISTER_MODULE_CPP} PROPERTIES INCLUDE_DIRECTORIES ${THE_INCLUDE_DIRS})
# Dont include in unity builds, it's generally not going to have a matching include directory list
set_source_files_properties(${REGISTER_MODULE_CPP} PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
Since generator expressions can be used for the OUTPUT parameter of file(GENERATE)
, and then the result of file(GENERATE) can be used in target_sources()
it should be possible to use a generator expression for set_source_files_properties()
.
Alternatively, I would be happy to see a PROPERTIES parameter to file(GENERATE) so I can add these properties to the file at generation time.
As things stand now, set_source_files_properties()
happily, and silently, applies properties to source files that don't, and never will, exist, violating the principal of least surprise.
Edited by Brad King