Reputation: 1149
I am trying to port my old CMake to modern CMake (CMake 3.0.2 or above). In the old design I had multiple CMakelists.txt, each directory contained a CMakeLists.txt file.
My current project's directory structure looks like :
.
├── VizSim.cpp
├── algo
├── contacts
│ ├── BoundingVolumeHierarchies
│ │ └── AABBTree.h
│ └── SpatialPartitoning
├── geom
│ └── Geometry.h
├── math
│ ├── Tolerance.h
│ ├── Vector3.cpp
│ └── Vector3.h
├── mesh
│ ├── Edge.h
│ ├── Face.h
│ ├── Mesh.cpp
│ ├── Mesh.h
│ └── Node.h
├── util
| |__ Defines.h
| |__ Math.h
|
└── viz
└── Renderer.h
What I was planning to do was just use a single CMakelists.txt and place all the cpp files in SOURCE and all the headers in HEADER and use add_executable.
set (SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/src/mesh/Mesh.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/VizSim.cpp
....
)
set (HEADER
${HEADER}
${CMAKE_CURRENT_SOURCE_DIR}/src/mesh/Mesh.h
${CMAKE_CURRENT_SOURCE_DIR}/src/math/Vector3.h
....
)
add_library(${PROJECT_NAME} SHARED ${SOURCE})
Doing this I am worried if using a single CMakeLists.txt is good practice. So does single CMakeLists.txt suffice or do I need a CMakeLists.txt for each folder?
I can only think of one good reason to have multiple CMakeLists.txt in my project and that is modularity.
Considering my project will grow eventually.
Upvotes: 8
Views: 3262
Reputation: 20141
This is a bit long for a comment – so I make it an answer:
In one of my projects (a library), I have that many sources that I started to move some of them in a sub-directory util
.
For this, I made separate variables:
file(GLOB headers *.h)
file(GLOB sources *.cc)
file(GLOB utilHeaders
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/util/*.h)
file(GLOB utilSources
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/util/*.cc)
To make it nice looking / more convenient in VisualStudio, I inserted source_group
s which generates appropriate sub-folders in the VS project. I believe they are called "Filters".
source_group("Header Files\\Utilities" FILES ${utilHeaders})
source_group("Source Files\\Utilities" FILES ${utilSources})
Of course, I have to consider the variables utilHeaders
and utilSources
as well where the sources have to be provided:
add_library(libName
${sources} ${headers}
${utilSources} ${utilHeaders})
That's it.
Fred reminded in his comment that I shouldn't forget to mention that file(GLOB
has a certain weakness (although I find it very valuable in our daily work). This is even mentioned in the CMake doc.:
Note: 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
CONFIGURE_DEPENDS
flag may not work reliably on all generators, or if a new generator is added in the future that cannot support it, projects using it will be stuck. Even ifCONFIGURE_DEPENDS
works reliably, there is still a cost to perform the check on every rebuild.
So, using file(GLOB
, you shouldn't never forget to re-run CMake once files have been added, moved, or removed. An alternative could be as well, to add, move, remove the files directly in the generated built-scripts (e.g. VS project files) and rely on the fact that the next re-run of CMake will those files cover as well. Last but not least, a git pull
is something else that it's worth to consider a re-run of CMake.
Upvotes: 2
Reputation: 23394
I would always recommend a CMakeList.txt file per directory. My reasons:
test
, libraries below lib
, binaries below bin
, documentation below doc
, and utilities below utils
. This may vary from project to project. When I have to make a change to the documentation, why should I wade through dozens of unrelated CMake code? Just have a look into the right CMakeLists.txt.${CMAKE_CURRENT_SOURCE_DIR}
can be avoided. That leads to maintainable build code and reduces errors from wrong paths. Especially with out-of-source build, which should be used anyway.Upvotes: 3