title: CMake: how to handle add_custom_command sub-builds when building with Ninja
body: <p>I'm using CMake to build a C++ project (on Linux). The project consists of numerous sub-projects, each of which may invoke a function to create a useful <code>link_date.c</code> source file, which contains the timestamp when the link took place. I use this as a way to reliably embed the build time into the binary regardless of what source changes have occurred since the last build.</p>
  <p>This function is declared thusly:</p>
  <pre><code>function(add_link_date TARGET)
      file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/link_date.c.in &quot;
      const char *link_date() { return(\&quot;@LINK_DATE@\&quot;); }
      &quot;)
      file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/link_date.cmake &quot;
      EXECUTE_PROCESS(
          COMMAND date
          OUTPUT_VARIABLE LINK_DATE
          OUTPUT_STRIP_TRAILING_WHITESPACE
      )
      CONFIGURE_FILE(\${SRC} \${DST} @ONLY)
      &quot;)
      add_custom_command(
          OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/link_date.c
          COMMAND ${CMAKE_COMMAND} -DSRC=link_date.c.in -DDST=link_date.c
          -P link_date.cmake
          DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/link_date.c.in)
      add_library(link_date-${TARGET} STATIC EXCLUDE_FROM_ALL link_date.c)
      target_link_libraries(${TARGET} link_date-${TARGET})
      add_custom_command(
          TARGET ${TARGET}
          PRE_LINK
          COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/link_date.c.in
          COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR} --target link_date-${TARGET})
  endfunction()
  </code></pre>
  <p>This function, for each target that it is invoked for, creates a <code>link_date.c.in</code> template, then uses this template to create <code>link_date.c</code>, just for that target. Then this is added to a target-specific library which is then linked with the target executable. The final <code>add_custom_command</code> is used to ensure that the link_date library is rebuilt every time CMake is about to link the target executable. I got the original code for this from <a href="https://cmake.org/pipermail/cmake/2010-October/040247.html" rel="nofollow noreferrer">here</a>.</p>
  <p>The key thing is that it always injects the build timestamp into the executable no matter who builds it - developer, CI pipeline, etc. It works very well with the Makefiles generator and I've been using it for over 12 months, without any issues.</p>
  <p>Recently I've been looking at updating our build to use Ninja, as it is demonstrably faster in most of my pipelines, however with this project it runs into a problem, specifically with the last <code>COMMAND</code> of the last <code>add_custom_command</code> (PRE_LINK) statement, which runs a sub-build. This has the effect of <code>cd</code>ing into the build sub-directory of the sub-project that invoked <code>add_link_date</code>, but because CMake only generates a Ninja <code>build.ninja</code> file in the top of the build directory, the child <code>cmake --build</code> fails because there is no <code>build.ninja</code> in this sub-project directory.</p>
  <p>Is there a way to modify this process to work with Ninja?</p>
  <p>I understand that not every CMake project can be migrated from Makefiles to Ninja, however this is the only real hurdle I have with this particular project so it would be nice to find a workaround.</p>