On 22. Mar, 2010, at 15:22 , Verweij, Arjen wrote: > Hi, > >> From: Michael Wild [mailto:them...@gmail.com] > >>>> You have to call ADD_SOURCES for all your sources BEFORE you do the >>>> ADD_LIBRARY call. >>> >>> I am already doing this, but since the files I was adding to the >> library didn't exist, the call failed. I somehow expected cmake to start >> executing the custom command since there was a previously defined >> dependency, but apparently cmake wasn't set up for the way I'm >> mistreating it :) >>> >>> What triggers a custom command to be executed? With your help I have >> arrived at: >> >> >> You should add a "DEPENDS <input_file1> <input_file2> ..." option to >> your ADD_CUSTOM_COMMAND calls, then CMake will know when to invoke it, >> otherwise it can't know anything about the dependency. > > Alright. I have spent a considerable amount of time experimenting, rewriting > and testing. I have reduced my problem to hello world inside a hello.cr file. > add_sources() has been molested and reduced to a mere shadow of its former > glory. With or without DEPENDS doesn't change matters, although I'm sure > without is bad form. Layout: > > CMakeLists.txt (code below) > h -- CMakeLists.txt (it just calls add_sources() -- without any arguments) > | -- hello.cr (your typical hello world) > > So, when I call add_sources() directly from the top level CMakeLists.txt > file, I obtain my executable "test". If I comment out the add_sources() call, > and use add_subdirectory(h) instead, and call add_sources() from there, it > fails. The complaint is that it cannot find source file "hello.c" Apparently > the problem is that add_custom_command() calls are local to the directory > they are called in, and since the executable is assembled from a list on a > higher level, it expects to find the source file on disc already :( > > PROJECT(Test) > enable_language( C ) > cmake_minimum_required(VERSION 2.8) > > function (add_sources) > define_property(GLOBAL PROPERTY list BRIEF_DOCS "brief" FULL_DOCS "full") > > SET ( out_file "/mnt/usr3/people/verweija/cmake2/build/h/hello.c" ) > SET ( in_file "/mnt/usr3/people/verweija/cmake2/h/hello.cr" ) > > ADD_CUSTOM_COMMAND( > OUTPUT ${out_file} > COMMAND ${CMAKE_COMMAND} -E copy ${in_file} ${out_file} > DEPENDS "/mnt/usr3/people/verweija/cmake2/h/hello.cr" > ) > > LIST( APPEND mylist ${out_file} ) > > set_property(GLOBAL APPEND PROPERTY "list" "${mylist}") > endfunction(add_sources) > > add_sources() > #add_subdirectory( h ) > > get_property(list GLOBAL PROPERTY list) > message ( STATUS list=${list} ) > ADD_EXECUTABLE( "test" ${list} ) > > I have found some threads about this, and I will be reading them shortly :) > > Regards, > Arjen
Problem is the following: Dependencies between stuff in different directories only work for top-level targets (add_library, add_executable and add_custom_target). So, you would need to add a ADD_CUSTOM_TARGET call with a unique target name in your ADD_SOURCES function, add that name to a global list (as you do with the sources) and then after your ADD_EXECUTABLE call you have to do an ADD_DEPENDENCIES. Further, you need to tell CMake at the top-level that the sources are generated by setting the source file property GENERATED to TRUE. All very complicated and error prone. So I suggest, you move the whole logic of your preprocessing to your top-level CMakeLists.txt file: cmake_minimum_required(VERSION 2.8 FATAL_ERROR) project(example) # function to collect all the sources from sub-directories # into a single list function(add_sources) get_property(is_defined GLOBAL PROPERTY SRCS_LIST DEFINED) if(NOT is_defined) define_property(GLOBAL PROPERTY SRCS_LIST BRIEF_DOCS "List of source files" FULL_DOCS "List of source files to be compiled in one library") endif() # make absolute paths set(SRCS) foreach(s IN LISTS ARGN) if(NOT IS_ABSOLUTE "${s}") get_filename_component(s "${s}" ABSOLUTE) endif() list(APPEND SRCS "${s}") endforeach() # append to global list set_property(GLOBAL APPEND PROPERTY SRCS_LIST "${SRCS}") endfunction(add_sources) # add subdirectories add_subdirectory(src) # preprocess sources set(PREP_SRCS) get_property(SRCS GLOBAL PROPERTY SRCS_LIST) foreach(s IN LISTS SRCS) file(RELATIVE_PATH rs "${CMAKE_CURRENT_SOURCE_DIR}" "${s}") string(REGEX REPLACE "r$" "" o "${CMAKE_CURRENT_BINARY_DIR}/${rs}") add_custom_command( OUTPUT "${o}" COMMAND ${CMAKE_COMMAND} -E copy "${s}" "${o}" DEPENDS "${s}" COMMENT "Creating ${o}" VERBATIM ) list(APPEND PREP_SRCS "${o}") endforeach() # add executable add_executable(example ${PREP_SRCS}) HTH 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