8

I want to generate some compile time constants. The first answer to another question gets me quite close. From my CMakeLists.txt:

add_library(${PROJECT_NAME} STATIC ${CXX_SRCS} compile_time.hpp)
add_custom_command(OUTPUT compile_time.hpp
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/compile_time.cmake)

This works in the sense that the first time I run make, it generates compile_time.hpp, so that the values of the variables are defined when I run make and not cmake. But compile_time.hpp is not remade when I rerun make or even cmake to redo the makefiles.

How can I make the target compile_time.cpp be marked as phony so that it is always remade? I tried

add_custom_target(compile_time.hpp)

to no effect.

Community
  • 1
  • 1
pythonic metaphor
  • 10,296
  • 18
  • 68
  • 110

1 Answers1

9

add_custom_target creates a "phony" target: It has no output and is always built. For make some target depended from the "phony" one, use add_dependencies() call:

add_custom_target(compile_time
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/compile_time.cmake
)
# Because we use *target-level* dependency, there is no needs in specifying
# header file for 'add_library()' call.
add_library(${PROJECT_NAME} STATIC ${CXX_SRCS})
add_dependencies(${PROJECT_NAME} compile_time)

Library's dependency from the header compile_time.h will be detected automatically by headers scanning. Because script compile_time.cmake updates this header unconditionally, the library will be rebuilt every time.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • According to the [documentation](https://cmake.org/cmake/help/latest/command/add_custom_target.html), this will be PHONY also when you *do* use `DEPENDS`. It says: The target has no output file and is always considered out of date even if the commands try to create a file with the name of the target. – Carlo Wood Dec 13 '19 at 21:39
  • Thanks for the notice. Not sure why I have added notion about absence of `DEPENDS`, but "no `OUTPUT`" seems to describe the situation better. The answer is fixed now. – Tsyvarev Dec 13 '19 at 22:04
  • Unfortunately, it turns out that cmake does NOT create real `.PHONY` targets and there is no way to make it do so. What it does is create a rule for the `OUTPUT` file and then never create that file, so that it is "always out of date". If said file is created, cmake removes it again. I think that was a bad choice because it stops me from doing certain things (as a result I can't use the ExternalProject stuff). – Carlo Wood Mar 08 '20 at 18:56