On 12/02/2010 03:13 PM, Raymond Wan wrote: > Hi Michael, > > > On Thu, Dec 2, 2010 at 19:40, Michael Hertling <mhertl...@online.de> wrote: >> On 12/01/2010 06:03 PM, Raymond Wan wrote: >>> Ah! I see. Then is it recommended that this top-level CMakeLists.txt >>> have just these lines, or should I move the ADD_EXECUTABLE, etc. lines >>> here as well? Or is this really "up to me" and there isn't a >>> suggested paradigm? >> >> Basically, IMO, a CMakeLists.txt with ADD_EXECUTABLE() et al. should be >> placed in the same directory as the related source files unless there's >> a reason not to do so; this makes for modularity and a well organized >> code base. The above-mentioned directory structure with its top-level >> CMakeLists.txt containing just ADD_SUBDIRECTORY() commands keeps the >> modules main, dir-A and dir-B separate with minimal interconnections. >> In the previous structure, e.g., main/CMakeLists.txt had to know that >> dir-A resides in "../dir-A"; now, such information is concentrated in >> the top-level CMakeLists.txt, and the sole reference of main to dir-A >> is the target "subprogA_ar". Due to CMake's capabilities to track the >> dependencies among targets, it doesn't matter where dir-A is placed >> within the project's source tree. So, in short, don't move the >> ADD_EXECUTABLE() etc. to the top-level CMakeLists.txt. > > > I see -- I did not realize this point you made about CMake's > dependency tracking abilities. So, basically the only thing I need to > worry about is the order of the ADD_SUBDIRECTORY ()'s. As long as I > put > > ADD_SUBDIRECTORY (dir-A) > > before > > ADD_SUBDIRECTORY (main) > > then "main" will be built correctly?
Even this is not necessary if the only reference of main to dir-A is TARGET_LINK_LIBRARIES(... subprogA_ar) in main/CMakeLists.txt since TARGET_LINK_LIBARIES(), AFAIK, does a lazy evaluation of the targets' dependencies, i.e. they are evaluated when all CMakeLists.txt files have been processed and, hence, all dependencies are known. If you refer to subprogA_ar in another way, e.g. SET_TARGET_PROPERTIES(), then you will get an error if dir-A hasn't been configured yet. > But, if I am not mistaken and following what you are saying, I can > only build "main" using the top-level CMakeLists.txt. The lower > CMakeLists.txt in main/ does not know the location of "dir-A". The > only way for both to work is to have this in main/CMakeLists.txt: > > ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A) > > yet this kind of duplication should be an error at worse; unnecessary > repetition at best? Each invocation of ADD_SUBDIRECTORY() for a source directory must be associated with an own binary directory, so the above-mentioned line would allow you to use both alternatives. However, when configuring the top-level CMakeLists.txt, you will get an error due to multiple definitions of the subprogA_ar target. In main/CMakeLists.txt, you might protect ADD_SUBDIRECTORY() against multiple invocations like IF(NOT TARGET subprogA_ar) ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A) ENDIF() or IF(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) ADD_SUBDIRECTORY(../dir-A ${CMAKE_CURRENT_BINARY_DIR}/dir-A) ENDIF() but this does not appear really appropriate to me. Nevertheless, I wonder why you want to build "main" by configuring its own source directory and alternatively via the top-level directory. If this is because you'd like to exclude some modules from building, you should handle such things in the top-level CMakeLists.txt, e.g. like: # Define options: OPTION(WITH_MAIN "Build module main" ON) OPTION(WITH_A "Build module A" ON) OPTION(WITH_B "Build module B" ON) # Handle dependencies: IF(WITH_MAIN) SET(WITH_A ON) ENDIF() # Enable modules: IF(WITH_B) ADD_SUBDIRECTORY(dir-B) ENDIF() IF(WITH_A) ADD_SUBDIRECTORY(dir-A) ENDIF() IF(WITH_MAIN) ADD_SUBDIRECTORY(main) ENDIF() So, you can conveniently enable/disable the modules on the command line or in the GUI, e.g. with "cmake -DWITH_B=OFF <path/to/top-level-dir>" if you don't want to build module B. As an alternative, you might consider to move dir-A to main/dir-A if dir-A is essentially a submodule of main, but referring to a sibling dir-A from main indicates that the latter is not sufficiently self- contained to be built on its own with a "cmake <path/to/main>", so the modules' relationships should be handled by other means, IMO. Regards, Michael >> The top-level directory of non-trivial projects should not contain any >> source files, perhaps a config.h header or the like. Usually, there're >> enough things gathering in a project's root, e.g. READMEs, subdirs for >> documentation, resources or CMake stuff, a CMakeLists.txt file ;) etc. >> The sources, however, should be organized in their own subdirectories, >> so the top-level CMakeLists.txt typically contains ADD_SUBDIRECTORY() >> commands along with configurational stuff like setting up compiler >> flags, processing options or investigating the underlying system, >> but no ADD_EXECUTABLE() or the like. >> >> Of course, there're exceptions and probably strong different opinions. > > > I see! Thank you for this! I'll stick with standard practice for now > and leave the exceptions and stronger opposing opinions to people who > know more about CMake than me. :-) > > Thank you very much for the explanation! > > Ray _______________________________________________ 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