[CMake] Why is this custom command run twice?

Brad King brad.king at kitware.com
Fri Apr 30 12:03:12 EDT 2010


On 4/30/2010 10:52 AM, elizabeta petreska wrote:
> Thank you for looking this
> I am sending you  two projects in the attachment, one manually generated
> and one with cmake.

Okay, I think I found the problem.  It is an interesting
interaction between old and new features.  The file names
"generated.txt.in" and "generated.txt" are the same except for
the extension.  When CMake sees "DEPENDS generated.txt.in" it
goes through some legacy logic needed to support auto-magic
matching of source file names with and without extension.
This logic is there because we once supported specifying source
files without extension and automatically finding them on disk.
This is still supported for compatibility with ancient projects.
Your case is hitting that logic, and CMake ties the ".txt.in"
and ".txt" sources together thinking they are one source.  This
leads to the project file having

<AdditionalInputs>...
C:/Users/elizabetap/Desktop/custombuild/MaillingListExample/build_cmake_vs10/generated.txt.rule;
C:\Users\elizabetap\Desktop\custombuild\MaillingListExample\build_cmake_vs10\generated.txt.in
...</AdditionalInputs>

Note that the full path to the ".in" file is actually in the
*build* tree which is wrong.  This came because the custom
command's "OUTPUT generated.txt" option told CMake that the
output file is in the build tree.  Since it matched the output
and input files as one source with the auto-magic extension
finding it got confused and wrote the wrong value for the input.
This is why changing the name changes the behavior.

It looks like this was actually wrong in all generators, but
VS 10 did not deal with it as well as the others.  The fix for
the above problem, rather than renaming, is to use a full path
for the DEPENDS option:

ADD_CUSTOM_COMMAND(
   OUTPUT generated.txt
   COMMAND ${CMAKE_COMMAND} -E copy
     "${PROJECT_SOURCE_DIR}/generated.txt.in"
     "${PROJECT_BINARY_DIR}/generated.txt"
   DEPENDS ${PROJECT_SOURCE_DIR}/generated.txt.in
   )

This avoids the legacy code path in CMake that ties the input
and output paths together.

Unfortunately this can't be fixed upstream without breaking the
legacy extension-finding feature.

-Brad


More information about the CMake mailing list