On 10/06/2011 05:40 PM, Martin Kupke wrote: > Hi, > > in my CMake project I have the need for a custom command that should be > processed in case a file is touched...that is the file the custom > command depends on. I already use the add_custom_command and > add_custom_target CMake instructions in my project, but always for > CMakeLists.txt files in subfolders where a static library will be build. > > I think I have a real simple requirement, but I don't get it work up to now. > In my main project I have a subfolder with an own CMakeLists.txt file, > this subfolder is added to the main project by instruction > add_subdirectory( "${CMAKE_CURRENT_SOURCE_DIR}/subfolder" ). > Within the CMakeLists.txt in the subfolder I want to call a custom > command, so I added the following lines: > message( "My Tool started by custom command / target" )
Use the COMMENT clause of ADD_CUSTOM_COMMAND() instead; in this way, you will see when the custom command is actually executed. > add_custom_command( OUTPUT Out.txt > COMMAND tool.exe ${ToolConfig} > DEPENDS ${ToolConfig} ) > add_custom_target( TOOL_CFG_OUT > DEPENDS Out.txt ) > > In my main project I added the custom target as dependency in the way: > add_dependencies( ${PROJECT_NAME} TOOL_CFG_OUT ) > > If I start the CMake process generating the Makefile I see the output of > my message "My Tool started by custom command / target", but the custom > command is never called. > I would like to have a build configuration that every time the dependend > file which is declared in the variable ${ToolConfig} is touched, the > command tool.exe is started. > > What am I doing wrong? Do you have a sample for me how to start a custom > command every time a file is touched. I don't get it work. > > Thanks in advance, > Martin... Indeed, custom commands in subdirectories with results used in higher directories provide some pitfalls. At first, the following exemplary CMakeList.txt files model the situation you outlined and do work: # CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(CUSTOMCOMMAND C) SET(CMAKE_VERBOSE_MAKEFILE ON) ADD_SUBDIRECTORY(subdir) FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n") SET_SOURCE_FILES_PROPERTIES( ${CMAKE_BINARY_DIR}/subdir/f.c PROPERTIES GENERATED TRUE) ADD_EXECUTABLE(main main.c ${CMAKE_BINARY_DIR}/subdir/f.c) ADD_DEPENDENCIES(main f) # subdir/CMakeLists.txt: FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/f.c.in "void f(void){}\n") ADD_CUSTOM_COMMAND( OUTPUT f.c COMMAND ${CMAKE_COMMAND} -E copy f.c.in f.c DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/f.c.in COMMENT "Generating f.c") ADD_CUSTOM_TARGET(f DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/f.c) AFAICS, the crux is the DEPENDS clause of ADD_CUSTOM_COMMAND(): Followed by a relative path, it refers to CMAKE_CURRENT_BINARY_DIR, but the custom command is attached to the custom target "f", and this is built in CMAKE_BINARY_DIR without having its prerequisites adapted. Look into subdir/CMakeFiles/f.dir/build.make; the dependency line of interest is "subdir/f.c: subdir/f.c.in" which is perfect in CMAKE_ BINARY_DIR. Change the DEPENDS clause to "DEPENDS f.c.in", and the dependency line becomes "subdir/f.c: ../subdir/f.c.in", i.e. Make's target (f.c) is relative to CMAKE_BINARY_DIR, but the prerequisite (f.c.in) is relative to CMAKE_CURRENT_BINARY_DIR, or CMAKE_BINARY_ DIR/subdir. Of course, this can't work and might even be considered as a CMake bug, but the interpretation of the DEPENDS clause w.r.t. relative paths isn't documented - as opposed to the OUTPUT clause - so you should always use full paths here when in doubt. There's another somewhat subtle pitfall revealed by the above-noted example: During the inital configuration, ADD_EXECUTABLE() searches ${CMAKE_BINARY_DIR}/subdir/f.c, doesn't find it because it doesn't exist yet, but stumbles over the f.c.in template - and is content since ".in" is a valid suffix. However, an ".in" file is useless for a C project on *nix, and so it's ignored. This results in the quite funny situation that f.c is regenerated each time f.c.in is touched - as you desired - but it's not compiled and, thus, not incorporated in the main target's executable. That's the reason for explicitly setting the GENERATED property on f.c what's not necessary for the OUTPUT files of a custom command in the same CMakeLists.txt. Change f.c.in's suffix to .template, e.g., and you will see that the GENERATED property is actually necessary as the property imposed automatically by ADD_CUSTOM_COMMAND() is valid in the respective CMakeLists.txt file only; see the documentation of SET_SOURCE_FILES_PROPERTIES(). 'hope that helps. If not, please boil down your problem to a minimal but self-contained example which demonstrates the issue and can be posted here for further investigation. 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