我正在尝试将旧的CMake移植到现代CMake(CMake 3.0.2或更高版本)。在旧的设计中,我有多个CMakelists.txt,每个目录都包含一个CMakeLists.txt文件。
我当前项目的目录结构如下:
.
├── 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
我打算做的只是使用一个CMakelists.txt,并将所有cpp文件放在SOURCE中,并将所有标头放在HEADER中,并使用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})
这样做,我担心使用单个CMakeLists.txt是否是一个好习惯。那么单个CMakeLists.txt是否足够?每个文件夹都需要CMakeLists.txt吗?
我只能想到一个很好的理由在我的项目中拥有多个CMakeLists.txt,那就是模块化。
考虑到我的项目最终会发展起来。
答案 0 :(得分:2)
我总是建议每个目录都有一个CMakeList.txt文件。我的原因:
test
之下,lib
之下的库,bin
之下的二进制文件,doc
之下的文档以及{{ 1}}。这可能因项目而异。当我不得不更改文档时,为什么要遍历数十个不相关的CMake代码?只需查看正确的CMakeLists.txt。utils
之类的东西。这导致可维护的构建代码,并减少了错误路径产生的错误。尤其是对于资源外构建,无论如何都应使用。答案 1 :(得分:1)
对于评论,这有点长-所以我将其作为答案:
在我的一个项目(一个库)中,我拥有许多源,因此我开始将其中一些移到子目录util
中。
为此,我制作了单独的变量:
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)
为了在Visual Studio中看起来更好/更方便,我插入了source_group
,它们在VS项目中生成适当的子文件夹。我相信它们被称为“过滤器”。
source_group("Header Files\\Utilities" FILES ${utilHeaders})
source_group("Source Files\\Utilities" FILES ${utilSources})
当然,我必须考虑变量utilHeaders
和utilSources
以及必须提供源的位置:
add_library(libName
${sources} ${headers}
${utilSources} ${utilHeaders})
就是这样。
Fred在他的评论中提醒我,我不应忘记提及file(GLOB
有一定的弱点(尽管我发现它在我们的日常工作中非常有价值)。 CMake doc.中甚至提到了这一点:
注意:我们不建议您使用GLOB从源代码树中收集源文件列表。如果在添加或删除源时没有CMakeLists.txt文件更改,则生成的生成系统无法知道何时要求CMake重新生成。
CONFIGURE_DEPENDS
标志可能无法在所有生成器上可靠地工作,或者如果将来添加了不支持它的新生成器,则使用该生成器的项目将被卡住。即使CONFIGURE_DEPENDS
可以可靠地工作,在每次重新构建时都要进行检查。
因此,使用file(GLOB
,一旦添加,移动或删除文件,您就永远不会忘记重新运行CMake。也可以选择直接在生成的内置脚本中添加,移动,删除文件(例如VS项目文件),并依赖于下一次重新运行CMake也会覆盖这些文件这一事实。最后但并非最不重要的一点是,git pull
是另外一回事,值得考虑重新运行CMake。