<div dir="ltr">Hi all,<div><br></div><div>I&#39;m trying to do some build-time configuration, for things like getting revision information into header files, packaging scripts, etc. So I&#39;m using add_custom_command to run cmake scripts that use configure_file to create new files. However, I&#39;m running into an issue that I&#39;m not sure is a bug, or whether I&#39;m just understanding things wrong. </div>

<div><br></div><div>Here&#39;s what I&#39;m trying to to do: at build time a script &quot;get_revision.cmake&quot; computes the revision number and writes it to &quot;revision.cmake&quot; using configure_file. I use a dummy output that never gets created, so that it runs on every build. A second add_custom_command calls configure_revision.cmake, which includes the revision.cmake and uses configure_file to create revision.h. Because I use configure_file, which uses CopyFileIfDifferent internally, it should also mean that the second custom command shouldn&#39;t run if the revision number is constant (which it always is in this example), and the main.cpp doesn&#39;t get recompiled if revision.h doesn&#39;t change. </div>
<div><br></div><div>Here&#39;s a self-contained minimal example CMakeLists.txt:</div>
<div><br></div><div>--- CMakeLists.txt ---</div><div><br></div><div><div>cmake_minimum_required (VERSION 2.8)</div><div>project (version)</div><div><br></div><div style># define file names</div><div>set(GET_REVISION_CMAKE ${CMAKE_CURRENT_BINARY_DIR}/get_revision.cmake)</div>

<div>set(REVISION_CMAKE ${CMAKE_CURRENT_BINARY_DIR}/revision.cmake)</div><div>set(REVISION_CMAKE_IN ${REVISION_CMAKE}.in)</div><div>set(REVISION_H ${CMAKE_CURRENT_BINARY_DIR}/revision.h)</div><div>set(REVISION_H_IN ${REVISION_H}.in)</div>

<div>set(CONFIGURE_REVISION_H ${CMAKE_CURRENT_BINARY_DIR}/configure_revision.cmake)</div><div>set(SRC ${CMAKE_CURRENT_BINARY_DIR}/main.cpp)</div><div><br></div><div style># create source files</div><div>file(WRITE ${REVISION_CMAKE_IN} </div>
<div>  &quot;set(REVISION @REVISION@)&quot;)</div>
<div>file(WRITE ${GET_REVISION_CMAKE}</div><div>  &quot;set(REVISION 1234)\n&quot;</div><div>  &quot;configure_file(${REVISION_CMAKE_IN} ${REVISION_CMAKE} @ONLY)&quot;)</div><div>file(WRITE ${REVISION_H_IN} </div><div>  &quot;#define REVISION @REVISION@&quot;)</div>

<div>file(WRITE ${CONFIGURE_REVISION_H} </div><div>  &quot;include(\&quot;${REVISION_CMAKE}\&quot;)\n&quot;</div><div>  &quot;configure_file(${REVISION_H_IN} ${REVISION_H} @ONLY)&quot;</div><div>)</div><div>file(WRITE ${SRC} </div>

<div>  &quot;#include &lt;iostream&gt;\n&quot;</div><div>  &quot;#include \&quot;${REVISION_H}\&quot;\n&quot;</div><div>  &quot;int main(int argc, char**argv) { \n&quot;</div><div>  &quot; std::cout &lt;&lt; REVISION &lt;&lt; std::endl;\n&quot;</div>

<div>  &quot;}&quot;)</div><div><br></div><div style># build time configure commands</div><div>add_custom_command(</div><div>  OUTPUT ${REVISION_CMAKE} ${REVISION_CMAKE}.alwaysbuild</div><div>  COMMAND ${CMAKE_COMMAND} -P ${GET_REVISION_CMAKE}</div>
<div>  DEPENDS ${GET_REVISION_CMAKE}</div>
<div>  COMMENT &quot;Updating revision info&quot;</div><div>)</div><div>add_custom_command(</div><div>  OUTPUT ${REVISION_H}</div><div>  COMMAND ${CMAKE_COMMAND} -P ${CONFIGURE_REVISION_H}</div><div>  DEPENDS ${REVISION_H_IN} ${REVISION_CMAKE}</div>

<div>  COMMENT &quot;Generating revision header&quot;</div><div>)</div><div>add_custom_target(version DEPENDS ${REVISION_H})</div><div>add_executable(version_test ${SRC})</div><div>add_dependencies(version_test version)</div>

<div><br></div><div>--- CMakeLists.txt end ---<br></div></div><div><br></div><div>However, when I try this, the &quot;Generating revision header&quot; command always runs, both on linux (cmake 2.8.7 with make) and windows (cmake 2.8.10.1 with Visual Studio 2008). This is not what I want, but more importantly, not what I would expect. Is this a bug or are my expectations wrong?</div>
<div><br></div><div>Troubleshooting I&#39;ve tried already: </div><div><br></div><div>On linux, I see that the revision.cmake modification date is always updated, and therefore the second command always runs. If I change the first add_custom_command to use a fake dependency instead of a fake output, like so:<br>
</div><div>--- snippet ---</div><div><div>add_custom_command(</div><div>  OUTPUT ${REVISION_CMAKE}.alwaysbuild</div>
<div>  COMMAND ${CMAKE_COMMAND} -E echo_append</div><div>  COMMENT &quot;(Run always)&quot;</div><div>)</div><div>add_custom_command(</div><div>  OUTPUT ${REVISION_CMAKE} </div><div>  COMMAND ${CMAKE_COMMAND} -P ${GET_REVISION_CMAKE}</div>

<div>  DEPENDS ${GET_REVISION_CMAKE} ${REVISION_CMAKE}.alwaysbuild</div><div>  COMMENT &quot;Updating revision info&quot;</div><div>)</div></div><div>--- snippet end ---<br></div><div>oddly enough, the revision.cmake file is no longer touched, as expected, and the header rule is no longer invoked unnecessarily. So somehow, the presence of a fake output file causes the real output file to be touched. It seems to me, though, that it should have worked in the original too. </div>
<div><br></div><div>On the other hand, in Visual Studio, in both cases the modification date of revision.cmake stays the same. However, in both cases, I still see &quot;Generating revision header&quot; on each build, and I don&#39;t understand why - if the dependencies of the second command don&#39;t change, why is it rerunning? </div>
<div style><br></div><div style>Note that in all cases (linux and windows) the main.cpp is not rebuilt unnecessarily, so the combination of add_custom_command and configure_file works as expected there.</div>
<div><br></div><div>Can anyone explain what is going on here?</div><div><br></div><div>best regards Mark</div></div>