仅将导入模块的标头添加到 CMake 中的库中

Posted

技术标签:

【中文标题】仅将导入模块的标头添加到 CMake 中的库中【英文标题】:Add only headers of an imported module to a library in CMake 【发布时间】:2018-05-24 15:14:03 【问题描述】:

在 CMake 中,有一些导入的模块用于简单地将外部模块添加到本地目标。例如,如果我们想在我们的项目中使用boost::filesystem 库,我们可以有这样的CMakeLists.txt

project(foo CXX)

find_packge(Boost REQUIRED COMPONENTS filesystem)

add_executable(foo main.cpp)
target_link_libraries(foo Boost::filesystem)

通过上述配置,CMake 将添加适当的编译器选项,并将所需库中的目录包含到foo 的构建过程中。

现在我们必须构建一个库而不是可执行文件,并且我们不想将boost::filesystem 库链接到我们的库。我们只希望将编译器选项和包含目录添加到我们的目标中。我们可以在这里使用导入模块的概念吗?我的意思是,如果我们可以使用Boost::filesystem 语法将这些选项添加到我们的目标?

project(foo CXX)

find_packge(Boost REQUIRED COMPONENTS filesystem)

add_library(foo STATIC foo.cpp)
# what should be wrote here to only add headers and configs to foo not the libs?

【问题讨论】:

target_include_directories(foo PRIVATE $Boost_INCLUDE_DIRS)? 我很确定 add_library(STATIC) 不会将 Boost 库链接到自身(参见例如 here)。 @AmitSingh 我知道,但我喜欢使用像 Boost::filesystem 这样的语法 @Florian 你提到的错误是关于 VC++ 我认为。不是吗? @E.Vakili 是的,但它描述了为什么您不想将依赖库链接到静态库的详细信息。简而言之,如果两个静态库将包括例如Boost::filesystem 然后你将这两个库链接到一个可执行文件中,你会得到duplicate symbol 错误。所以默认情况下,CMake 不会为 VC 添加链接器选项,如 --whole-archive for gccLinkLibraryDependencies。所以target_link_libraries(foo Boost::filesystem) 应该可以工作,它只是描述了依赖关系。 【参考方案1】:

把我的 cmets 变成答案

add_library(STATIC) 不会将 target_link_libraries() 依赖项链接到自身。

简而言之,如果两个静态库将包含例如Boost::filesystem 然后你将这两个库链接到一个可执行文件(外部符号在其中得到实际解析),你会得到重复的符号错误。

因此默认情况下,CMake 不会添加链接器选项,例如 --whole-archive 用于 gccLinkLibraryDependencies 用于 VC

target_link_libraries(foo Boost::filesystem) 应该可以工作,它只是描述了稍后在构建可执行文件或共享库时解决的依赖关系。

参考文献

ld linker question: the --whole-archive option CMake issue #9732: Cmake does not disable Link Libray Dependencies in the project settings

【讨论】:

以上是关于仅将导入模块的标头添加到 CMake 中的库中的主要内容,如果未能解决你的问题,请参考以下文章

Angular CLI 生成的库 - 无法从它的模块导入组件

ResearchKit 标头无法在 Xcode 中导入

如何从项目中导入模块[重复]

VBA从添加到工作簿中导入udf模块

d不同c文件中导入c

接收器类型 '' 例如消息是前向声明(但标头在 .m 中导入)