I'm trying to use add_custom_command to generate a file during the build. The command never seemed to be run, so I made this test file.
cmake_minimum_required( VERSION 2.6 )
add_custom_command(
OUTPUT hello.txt
COMMAND touch hello.txt
DEPENDS hello.txt
)
I tried running:
cmake .
make
And hello.txt was not generated. What have I done wrong?
The problem with two existing answers is that they either make the dependency global (
add_custom_target(name ALL ...)
), or they assign it to a specific, single file (set_property(...)
) which gets obnoxious if you have many files that need it as a dependency. Instead what we want is a target that we can make a dependency of another target.The way to do this is to use
add_custom_command
to define the rule, and thenadd_custom_target
to define a new target based on that rule. Then you can add that target as a dependency of another target viaadd_dependencies
.The advantages of this approach:
some_target
is not a dependency forALL
, which means you only build it when it's required by a specific target. (Whereasadd_custom_target(name ALL ...)
would build it unconditionally for all targets.)some_target
is a dependency for the library as a whole, it will get built before all of the files in that library. That means that if there are many files in the library, we don't have to doset_property
on every single one of them.DEPENDS
toadd_custom_command
then it will only get rebuilt when its inputs change. (Compare this to the approach that usesadd_custom_target(name ALL ...)
where the command gets run on every build regardless of whether it needs to or not.)For more information on why things work this way, see this blog post: https://samthursfield.wordpress.com/2015/11/21/cmake-dependencies-between-targets-and-files-and-custom-commands/
The
add_custom_target(run ALL ...
solution will work for simple cases when you only have one target you're building, but breaks down when you have multiple top level targets, e.g. app and tests.I ran into this same problem when I was trying to package up some test data files into an object file so my unit tests wouldn't depend on anything external. I solved it using
add_custom_command
and some additional dependency magic withset_property
.So now testData.cpp will generated before unit-tests.cpp is compiled, and any time testData.src changes. If the command you're calling is really slow you get the added bonus that when you build just the app target you won't have to wait around for that command (which only the tests executable needs) to finish.
It's not shown above, but careful application of
${PROJECT_BINARY_DIR}, ${PROJECT_SOURCE_DIR} and include_directories()
will keep your source tree clean of generated files.Add the following:
If you're familiar with makefiles, this means: