我有一个大型的代码库,可以构建数十个库和几个可执行文件。
代码库按层次结构分解,并且几乎每个级别都构建了库。
我已经完成并在每个目录中放置了一个CMakeLists.txt文件来构建每个库。
在每个CMakeLists.txt中,我使用了“project(xxx)”指令。这为我定义了PROJECT_NAME,PROJECT_SOURCE_DIR和PROJECT_BINARY_DIR变量,我明智地使用了这些变量。
然而,其中一个团队对这种方法不满意,因为他找不到任何其他人做过这个的真实世界的例子。他经常引用KitWare示例不使用这种方法,因此我们也不应该这样做。
他提倡的另一种方法是在每个makefile中设置这些变量,这看起来很像“项目”给你的。
我真的看不出他的观点,并且在说服他方面没有取得什么进展。任何人都可以通过这种方式阐明使用项目指令的缺点。
我把自己放在集体智慧上?
答案 0 :(得分:12)
首先,它允许您使用<projectName>_BINARY_DIR
和<projectName>_SOURCE_DIR
,但这不是主要优势。如果你给CMake一个项目名称,那么它将为他们自己的目录中的每个子项目生成构建目标。这意味着无论您使用的是GNU Make,Eclipse CDT,XCode还是任何其他受支持的生成器,您都可以单独构建子项目。例如,使用GNU Make,每个子项目都有自己的完整构建系统。
您可以通过PROJECT_NAME
访问当前项目名称,通过CMAKE_PROJECT_NAME
访问根项目名称。
编辑:我刚刚意识到以下将是其任何构建目标的标准CMake行为,无论它们是否是项目。我会在这里提供一般信息,但与答案无关:
假设我有一个C ++库,我可以生成三个二进制可执行文件; Main
和tests/test1
以及examples/ex1
。我可以在我使用ALL目标调用CMake的目录中运行make,运行make ex1
,或者我可以将目录更改为examples/
并使用该目录中的make
构建示例。这将构建所有依赖项目和库,即使它们位于目录结构中的其他位置但不会构建Main
或tests/test1
或它们依赖于examples/ex1
的任何库没有。如果我然后从主目录运行make,它将不会重建examples/ex1
所依赖的任何库,除非它们的源已更改。
答案 1 :(得分:0)
如果库是真正独立的项目,那么使用project
命令是有意义的。但是,如果不是,我只需将它们添加为根CmakeLists.txt
中的子目录。如果您需要知道当前正在处理的目录,可以使用变量CMAKE_CURRENT_SOURCE_DIR和CMAKE_CURRENT_BINARY_DIR。
答案 2 :(得分:0)
我今天找到了一个很好的用法示例:添加Doxygen文档。
我使用CMake(和Ninja)来构建我的个人C ++项目。我决定将一些Doxygen文档添加到我的一个非常完整但没有文档的工作中。我还认为只要我弄清楚如何尽可能地将它添加到其他项目中就可以将它添加到其他项目中。
首先,我生成了一个标准的Doxygen模板并将其重命名。
cd my_projects/projectx
doxygen -g Doxyfile
mv Doxyfile Doxyfile.in
请注意.in扩展名。如果我理解正确的话,可能不是必要的,而是传统的。
接下来,我在我的CMakeLists.txt文件中添加了以下代码块,就在定义我的目标之前(不确定这是否重要,但CMake有时对某些命令的顺序很挑剔)。
FIND_PACKAGE(Doxygen)
IF("${DOXYGEN_FOUND}" MATCHES "^YES$")
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
@ONLY)
ADD_CUSTOM_TARGET( doc ALL
COMMAND ${DOXYGEN_EXECUTABLE}
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Doxygenating..."
VERBATIM)
ENDIF()
这会创建一个名为doc的新目标。指定ALL会将其添加到默认的“all”目标,但这是可选的。指定@ONLY可确保任何“$ {variable}”类型变量不会被CONFIGURE_FILE扩展,只有“@ variable @”类型。有点令人困惑(至少对我来说),CMAKE_CURRENT_SOURCE_DIR似乎引用项目目录,CMAKE_CURRENT_BINARY_DIR引用到构建目录。
最后,这就是PROJECT_NAME等人进来的地方,我编辑了Doxyfile.in。
这是我的新Doxyfile.in:
的开头DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "@PROJECT_NAME@"
PROJECT_NUMBER = @PROJECT_VERSION_TWEAK@
PROJECT_BRIEF =
PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/res/doc_logo-200x55.png
OUTPUT_DIRECTORY = @CMAKE_CURRENT_SOURCE_DIR@/doc
我想,你明白了。一旦完全通用化(这是一个单词吗?)我可以将它复制到我的其他项目中,只要我标记我的代码,我就会在各处都有很好的文档。
注意未指定PROJECT_BRIEF。我还没有完成这个,还有一些空白让我思考。例如,PROJECT_VERSION_TWEAK实际上并不包含任何内容。我必须找到一种方法来获取我的内部版本号。