On 09/13/2010 05:46 PM, Gerhard Stengel wrote: > Hi, > > I have a strange problem with custom targets and their dependencies. I do as > follows: > > 1) create a file 1 and add it to a custom target 1 > 2) create a file 2 and add it to a custom target 2 > 3) create a 3rd file by packing #1 and #2 together > 4) the 3rd file is added to a custom target which depends on custom targets 1 > and 2 > > This is an example CMakeLists.txt: > > ----snip --- > > add_custom_command(OUTPUT Demo1.out > COMMAND ${CMAKE_COMMAND} -E copy > ${CMAKE_CURRENT_SOURCE_DIR}/Demo1.in Demo1.out > DEPENDS Demo1.in) > add_custom_target(cust1 ALL DEPENDS Demo1.out) > > add_custom_command(OUTPUT Demo2.out > COMMAND ${CMAKE_COMMAND} -E copy > ${CMAKE_CURRENT_SOURCE_DIR}/Demo2.in Demo2.out > DEPENDS Demo2.in) > add_custom_target(cust2 ALL DEPENDS Demo2.out) > > #this would work correctly in all cases > #add_custom_command(OUTPUT Demo.tar > # COMMAND ${CMAKE_COMMAND} -E tar cvf Demo.tar Demo1.out > Demo2.out > # DEPENDS Demo1.out Demo2.out) > > #without file level dependencies it isn't correctly rebuilt > add_custom_command(OUTPUT Demo.tar > COMMAND ${CMAKE_COMMAND} -E tar cvf Demo.tar Demo1.out > Demo2.out) > > add_custom_target(cust3 ALL DEPENDS Demo.tar) > add_dependencies(cust3 cust1 cust2) > > ----snip --- > > If I create Demo.tar from a clean project, everything's fine. However, the > rebuilt isn't performed completely, that is > if I touch Demo1.in, just Demo1.out is rebuilt, but not Demo.tar that depends > on it! [...]
Demo.tar does *not* depend on Demo1.out; it has no dependencies at all. As a proof - if on *nix - issue "find . -exec grep "Demo\.tar" {} \;" in the build directory after cmaking, and you'll see that Demo.tar's dependency line doesn't mention any prerequisites after the colon. > [...] This seems wrong to me because I > expect that if the target cust1 is rebuild, even the target cust3 has to be > rebuilt due to the relation established by > the add_dependencies() command! Rebuilding cust3 doesn't regenerate Demo.tar due to its lack of dependencies if it already exists. So, Demo.tar is generated at the first time and that's it, unless the file is removed later. > The problem seems to be that add_dependencies() doesn't realize that if cust1 > or cust2 becomes out of date cust3 has to > be rebuilt, too. It does, but rebuilding cust3 doesn't do what you expect, see above. > The solution using file level dependencies (see commented out command) would > work, [...] ...and is the correct one... > [...] but in my project it's not really > possible to do so because the "source" custom targets which the "final" > custom target takes as input contain lots of > files. First of all, is it possible to simplify your CMakeLists.txt? Unless you really need cust{1,2} as top-level targets they aren't necessary if Demo{1,2}.out are mentioned as dependencies in Demo.tar's custom command and if these commands all reside in the same CMakeLists.txt. Furthermore, you could even use ADD_CUSTOM_TARGET(Demo.tar ALL COMMAND ${CMAKE_COMMAND} -E tar cvf Demo.tar Demo1.out Demo2.out DEPENDS Demo1.out Demo2.out) instead of Demo.tar's custom command if you don't need Demo.tar as an ingredient for another target and, again, if these commands/targets are defined in the same CMakeLists.txt. > Is there an easy workaround or is this a cmake bug? No bug. ;) Without further knowledge of your project, the best advice one can give is to use lists, loops, functions and properties to cope with large numbers of files in the CMakeLists.txt. 'hope that helps. Regards, Michael _______________________________________________ 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://www.cmake.org/mailman/listinfo/cmake