add_custom_command with IMPLICIT_DEPENDS fails when implicitly dependent file is deleted
This testcase.tar.gz shows a simple example of using a custom command for creating a source file and using IMPLICIT_DEPENDS for creating its dependencies.
test.h
depends on test2.h
, the "normal" cxx file test.cxx
as well as the custom-made cxx file custom.cxx
depend on test.h
. IMPLICIT_DEPENDS correctly creates the implicit dependency of custom.cxx
on test2.h
.
I can run cmake and compile it correctly (output below):
cmake $SRC_DIR && make
-- The C compiler identification is GNU 9.2.0
[...]
-- Build files have been written to: /home/qon/tmp3/build
[ 25%] Generating custom.cxx
Scanning dependencies of target foo
[ 50%] Building CXX object CMakeFiles/foo.dir/test.cxx.o
[ 75%] Building CXX object CMakeFiles/foo.dir/custom.cxx.o
[100%] Linking CXX executable foo
[100%] Built target foo
Now, when I change test.2 and rerun make, both cxx files are recompiled correctly (so far, the IMPLICIT_DEPENDS works)
touch $SRC_DIR/test2.h && make
[ 25%] Generating custom.cxx
Scanning dependencies of target foo
[ 50%] Building CXX object CMakeFiles/foo.dir/test.cxx.o
[ 75%] Building CXX object CMakeFiles/foo.dir/custom.cxx.o
[100%] Linking CXX executable foo
[100%] Built target foo
The problem is now: when I remove test2.h
, and remove its include in test.h, the dependency resolution would need to see that test.h
no longer depends on test2.h
, and thus remove the dependency on test2.h
from both test.cxx
and custom.cxx
. This works correctly for the normal test.cxx
but fails for the IMPLICIT_DEPENDS:
rm $SRC_DIR/test2.h && echo "#foo" > $SRC_DIR/test.h && make
make[2]: *** No rule to make target '../test2.h', needed by 'custom.cxx'. Stop.
make[1]: *** [CMakeFiles/Makefile2:75: CMakeFiles/foo.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
custom.cxx
has a hard dependency on test2.h
in CMakeFiles/foo.dir/depend.make
:
custom.cxx: ../test2.h
When I modify CMakeFiles/foo.dir/depend.make
manually and remove this line, I can run make again, and it resolves the dependencies correctly:
make
Scanning dependencies of target foo
[ 25%] Building CXX object CMakeFiles/foo.dir/test.cxx.o
[ 50%] Generating custom.cxx
[ 75%] Building CXX object CMakeFiles/foo.dir/custom.cxx.o
[100%] Linking CXX executable foo
[100%] Built target foo
So in summary: if a file which is used as an implicit dependency from IMPLICIT_DEPENDS is deleted, it breaks the compilation also if it is no longer a dependency. (This problem does not appear for "normal" source files like test.cpp
.) Instead, in this case IMPLICIT_DEPENDS should first rescan the dependencies to check if the file is still needed.