add_custom_command's IMPLICIT_DEPENDS feature doesn't work as expected
Hi,
I recently discovered a behaviour of the add_custom_command
that I believe is bogus.
In our software we make use of the ROOT "framework". (http://root.cern.ch) One defining feature of ROOT is its ability to handle C++ objects in a generic way, using so-called dictionaries. (It's a long story...) In order to generate a dictionary for a user class, one has to use one of the ROOT executables that generates the source file(s) for the dictionary, which the user then has to compile into his/her source code in an appropriate manner.
As you can guess, we use add_custom_command
to run these dictionary source file generation commands. Since the dictionary generator is a C++ interpreter itself, it's not completely trivial to set up the dependencies for the custom command. But luckily IMPLICIT_DEPENDS
is exactly what we need for it. Since it allows us to only specify the headers holding the classes that we actually want to generate a dictionary for, and not have to care about which other headers these "important" headers pull in.
However, we had to discover that IMPLICIT_DEPENDS
doesn't play nicely with our CI system. Attached is a very simple demonstration of this. implicitDepends.tar.gz2
It runs a custom command to generate a source file, from a header file called header1.h
. This header1.h
file includes another file called header2.h
.
The compilation of this project works just fine out of the box. But try to do the following after building the "project":
- Remove the
header2.h
file; - Comment out the include of
header2.h
inheader1.h
.
When I try an incremental build after these changes, I get the following:
make[2]: *** No rule to make target `/Users/krasznaa/Development/cmake/implicitDepends/header2.h', needed by `output.cxx'. Stop.
make[1]: *** [CMakeFiles/DummyLibrary.dir/all] Error 2
make: *** [all] Error 2
Even though a clean build of the modified source works just fine. Also, if I add one more header to the source, the incremental build still works correctly.
Unfortunately in the current setup Make is exposed to the dependency rules generated previously, before it would have a chance to update those dependency rules for the latest status of the source code. I have to admit I have absolutely no idea how all of this is implemented in CMake itself, so I'd leave it up to you guys to figure out how to best fix it. Unfortunately until it is fixed our CI system is not nearly as reliable as we'd like it to be.
Cheers, Attila