The following issue has been SUBMITTED. ====================================================================== http://public.kitware.com/Bug/view.php?id=13592 ====================================================================== Reported By: Frank Miller Assigned To: ====================================================================== Project: CMake Issue ID: 13592 Category: CMake Reproducibility: always Severity: minor Priority: normal Status: new ====================================================================== Date Submitted: 2012-10-16 10:00 EDT Last Modified: 2012-10-16 10:00 EDT ====================================================================== Summary: Inefficient Ninja DAG with add_custom_command Description: The ninja generator is not handling dependencies of custom commands efficiently. As far as I can tell, it is producing correct builds but with an only overly conservative DAG.
Here is a toy project: cmake_minimum_required( VERSION 2.8.0 ) project( ndep ) file( WRITE ${CMAKE_BINARY_DIR}/main.cpp " #include <iostream> #include \"foo.h\" int bar(); int main() { std::cout << foo() << bar() << std::endl; } ") file( WRITE ${CMAKE_BINARY_DIR}/foo.in " int foo() { return VALUE; } ") file( WRITE ${CMAKE_BINARY_DIR}/bar.in " int bar() { return VALUE; } ") add_custom_command( OUTPUT foo.h COMMAND cat ${CMAKE_BINARY_DIR}/foo.in | sed 's/VALUE/4/' > ${CMAKE_BINARY_DIR}/foo.h DEPENDS ${CMAKE_BINARY_DIR}/foo.in ) add_custom_command( OUTPUT bar.cpp COMMAND cat ${CMAKE_BINARY_DIR}/bar.in | sed 's/VALUE/2/' > ${CMAKE_BINARY_DIR}/bar.cpp DEPENDS ${CMAKE_BINARY_DIR}/bar.in ) add_executable( ndep main.cpp foo.h bar.cpp ) For this case, using git master, the generated object dependencies are (in Ninja syntax): build main.cpp.o: main.cpp | foo.h bar.cpp build bar.cpp.o: bar.cpp | foo.h bar.cpp If foo.h changes (because of foo.in) then bar.cpp.o will be recompiled when it need not be. Similarly, main.cpp need not be recompiled if bar.cpp changes. Also, bar.cpp is stated to be both an explicit and an implicit dependency of bar.cpp.o. What we want here is: build main.cpp.o: main.cpp || foo.h build bar.cpp.o: bar.cpp Additional Information: I have studied the Ninja generator code a bit and found the logic responsible for writing the object build statements in cmNinjaTargetGenerator::WriteObjectBuildStatement(.) on line 554 in cmNinjaTargetGenerator.cxx. I see that this logic recently changed. Previously the generated files would have showed up as order-only dependencies. This is closer to the desired result but still not perfect. There must be a better way but I am not familiar enough with cmake internals to know what that is. ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 2012-10-16 10:00 Frank Miller New Issue ====================================================================== -- Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers