We are using CMake and ninja to build our project. We wanted to regenerate a cpp file at every build, containing the build timestamp, so that our executable can log it. We came up with this:
####################
# Embed build time #
####################
find_package(Python3 REQUIRED COMPONENTS Interpreter)
set(TIMESTAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated_timestamp)
set(TIMESTAMP_CPP ${TIMESTAMP_DIR}/timestamp.cpp)
set(TIMESTAMP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/generate_timestamp.py)
file(MAKE_DIRECTORY ${TIMESTAMP_DIR})
add_custom_target(generate_timestamp_files
COMMAND ${Python3_EXECUTABLE} ${TIMESTAMP_SCRIPT} ${TIMESTAMP_CPP}
DEPENDS ${TIMESTAMP_SCRIPT}
COMMENT "Generating timestamp source and header"
)
set_source_files_properties(
${TIMESTAMP_CPP}
PROPERTIES
GENERATED TRUE
)
add_library(timestamp_lib
${TIMESTAMP_CPP}
)
add_dependencies(timestamp_lib generate_timestamp_files) # HERE
target_include_directories(timestamp_lib
PUBLIC
include
)
target_link_libraries(main_target
timestamp_lib
)
Notice the call to add_dependencies. Now this configuration works, the cpp file is regenerated at every build, but the library only gets recompiled every two builds. Why? My understanding is that add_dependencies should force ninja to wait to check for the library until the file has been regenerated, at which point the timestamp should be newer than the library. Apparently the are working in parallel? The CMake manual mentions:
add_dependencies([...] Changed in version 3.9: The Ninja Generators use weaker ordering than other generators in order to improve available concurrency. They only guarantee that the dependencies' custom commands are finished before sources in start compiling; this ensures generated sources are available....)
But isn't this sufficient? Thanks!