3 回答
TA贡献2080条经验 获得超4个赞
多次添加同一子目录是毫无疑问的,这并不是CMake的工作方式。可以采用两种主要方法来进行清洁:
在与应用程序相同的项目中构建库。对于正在积极使用(在使用应用程序时)正在使用的库,请首选此选项,以便它们可能经常被编辑和重建。它们还将显示在同一IDE项目中。
在外部项目中构建您的库(我不是说ExternalProject)。对于仅由您的应用使用但未使用它们的库,请首选此选项。大多数第三方库就是这种情况。它们也不会使您的IDE工作区混乱。
方法1
您的应用CMakeLists.txt添加了库的子目录(而库的CMakeLists.txt不添加)
您的应用CMakeLists.txt负责添加所有直接和传递依赖项,并以正确的顺序添加它们
它假定添加的子目录libx将创建一些libx易于使用的目标(例如)target_link_libraries
附带说明:对于库来说,创建一个功能齐全的库目标是一个好习惯,即,其中包含使用该库所需的所有信息:
add_library(LibB Src/b.cc Inc/b.h)
target_include_directories(LibB PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/Inc>)
因此,库的包含目录的位置可以保留为lib的内部事务。您只需要这样做;
target_link_libraries(LibC LibB)
然后LibB还将将的包含目录添加到的汇编中LibC。PRIVATE如果LibB的公共标头未使用,请使用修饰符LibC:
target_link_libraries(LibC PRIVATE LibB)
方法#2
在单独的CMake项目中构建和安装库。您的库将安装一个所谓的config-module,该模块描述头文件和库文件的位置并编译标志。您的应用程序CMakeList.txt假设已经建立并安装了库,并且可以通过find_package命令找到配置模块。这是另一个完整的故事,所以我在这里不再赘述。
一些注意事项:
您可以混合使用#1和#2,因为在大多数情况下,您将拥有不变的第三方库和正在开发的自己的库。
#1和#2之间的折衷方案是使用ExternalProject模块,这是许多人首选的模块。这就像将库的外部项目(在其自己的构建树中构建)包含到应用程序的项目中一样。在某种程度上,它结合了两种方法的缺点:您不能将库用作目标(因为它们位于不同的项目中),也不能调用find_package(因为在CMakeLists配置应用程序时未安装库)。
#2的一种变体是在外部项目中构建库,但不是安装工件,而是从源/构建位置使用它们。有关此的更多信息,请参见export()命令。
TA贡献1982条经验 获得超2个赞
方法1:我喜欢您对target_include_directories()
命令的使用(CMake> = 2.8.12),这肯定使事情变得更容易。但是我正在寻找一种解决方案,其中库的用户不需要知道内部依赖项。方法2:我将研究使用二进制传递和find_package()
命令。您能推荐任何有用的链接吗?
TA贡献1809条经验 获得超8个赞
关于ExternalProject
模块:ExternalProject_Add()
如果我们谈论更大的整体库,我认为该命令是可行的。但是对于我的50多个较小的库,我不认为这是一个选择,并且在某种程度上说,不打算以这种方式使用它的说法在这里也适用。开销是很大的:例如,我担心它-如果我使用该SOURCE_DIR
选项-将启动每个库的编译器检测,并且我必须传递所有特定于构建环境的选项,包括。我的工具链文件。
- 3 回答
- 0 关注
- 1630 浏览
添加回答
举报