1

Why version.cmake are called twice in the setup detailed bellow? How do I correct this to call it just one time?

Details: The objective is to call version.cmake in every build once, regardless of any dependency (this trick was adapted from here). This module verify the current git version and if it differs from a previous version.cpp file, it write a new file. The version.cpp are a dependency of the main program test.cpp and are linked together. This way, if the version stay the same, nothing need to be compiled or linked, if differs, it get recompiled and relinked with the main cpp. A reconfiguration isn't needed.

Note: To make this more easy to explain/reproduce, and be more focused in the related problem, the version.cmake bellow was greatly simplified, not depending of git. It just write a new version.cpp every time it is called.

CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(test)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.cpp
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/version.cmake
    DEPENDS dummy_always_rebuild
)

add_custom_command(
    OUTPUT dummy_always_rebuild
    COMMAND true > /dev/null
)

add_library(libversion OBJECT
        ${CMAKE_CURRENT_BINARY_DIR}/version.cpp
)

add_executable(test test.cpp)
target_link_libraries(test PRIVATE libversion)

version.cmake:

message("version.cmake called")

# (not showed here) get sw version, **IF** it differs from existing 'version.cpp', write a new file:
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/version.cpp" "const char* version=\"xx.yy.zz\";")

test.cpp:

#include <iostream>
extern const char* version;
int main(int argc, char **argv) {
        std::cout << "version=" << version << std::endl;
        return 0;
}

Console output for the make command (after a cmake run). Observe that version.cmake are called twice:

[ 20%] Generating dummy_always_rebuild
[ 40%] Generating version.cpp
version.cmake called
Scanning dependencies of target libversion
[ 40%] Generating dummy_always_rebuild
[ 40%] Generating version.cpp
version.cmake called
[ 60%] Building CXX object CMakeFiles/libversion.dir/version.cpp.o
[ 60%] Built target libversion
[ 80%] Linking CXX executable test
[100%] Built target test

Setup info: Linux OS, cmake version 3.12.0, GNU Make version 4.2.1.

Berk7871
  • 187
  • 1
  • 2
  • 14
  • You need to `touch` the output `${CMAKE_CURRENT_BINARY_DIR}/version.cpp` in any case. – Dmitry Sokolov Jun 02 '20 at 18:54
  • @DmitrySokolov Why? Is there a way to avoid it? – Berk7871 Jun 03 '20 at 20:02
  • If a custom command output file will be older than CMakeLists.txt then this custom command will be executed every time you run the build. – Dmitry Sokolov Jun 03 '20 at 20:20
  • I oversimplified `version.cmake` here. In my actual configuration, `version.cpp` is updated/touched only when the GIT revision is changed. Even when `version.cpp` it is not updated/touched, `version.cmake` is called twice every time I run make. – Berk7871 Jun 04 '20 at 15:59

0 Answers0