3
votes

i like to structure my code in multiple subdirs but i dont want to create a new cmakelist.txt in each new subdir.

my folder structure is something like this:

project
  >cmakelist.txt
  >build
  >src
   >main.cpp
   >multiple_subdirs_or_(c|h)pp_files_with_more_subdirs_or_(c|h)pp_files

my cmakelist.txt looks like this:

...
file(GLOB_RECURSE cpps RELATIVE ${CMAKE_CURRENT_LIST_DIR}  "src/*.cpp")
file(GLOB_RECURSE hpps RELATIVE ${CMAKE_CURRENT_LIST_DIR}  "src/*.hpp")  

#remove files with main
list(REMOVE_ITEM cpps "src/test.cpp")

#bins
add_executable(test src/test.cpp src/test.cpp ${hpps} ${cpps})

#same problem if this is used instead of the other add_executable
add_library(foo OBJECT ${cpps} ${hpps})
add_executable(test src/test.cpp $<TARGET_OBJECTS:foo>)

the problem with my file:

source files created after the execution of cmake are not compiled and the build fails if they are used. as predicted by http://www.cmake.org/cmake/help/v3.0/command/file.html in section GLOB:

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.

the question: is it possible to use a single cmakelist.txt for a project with multiple sub directories? (without the problems of file(GLOB ...) )

2
You can run the target make rebuild_cache to make cmake run globbing expressions again, and it will pick up the new files - but as others recommended in answers, it's best to list all files manually (which means you would have to add new files in your CMakeLists.txt as well, and when the file changes cmake will do rebuild_cache automatically).Akos Bannerth

2 Answers

4
votes

You have two totally unrelated things here.

First, can you use only a single CMakeLists.txt file for your whole project? Yes, of course you can (although I'd personally not go this way after a project has reached a certain size), and you're already doing this.

Second, the problem with GLOB. You already quoted the part of the documentation where it states what problems the use of GLOB has. This cannot really be avoided at the moment if you want to continue using GLOB, as this is part of the cmake design where they distinguish between what is done during configure and build time. The alternative is to list all files manually. Whether you do this in a single CMakeLists.txt file in your projects main directory, or in multiple files across your subdirectories does not matter.

4
votes

To answer your question: yes, it is possible to handle a project with multiple sub-directories and one CMakeLists.txt. I have two considerations for you to take into account:

  1. I strongly recommend you not using file(GLOB ...) for sources.
  2. You have to list the files manually. For example (src/ is the source-subdirectory):

    set(cpps src/file1.cpp src/file2.cpp src/file3.cpp)