【发布时间】:2019-12-06 15:03:43
【问题描述】:
场景:
我正在将应用程序构建系统移植到 CMake。依赖项已经安装在系统上或将通过 conan 处理。
假设项目的结构如下:
- include/
- BigFoo/
- *.hpp
- src/
- BigFoo/
- *.cpp
- main.cpp
- *.qml
- test/
- BigFoo/
- *Test.cpp
我的目标是在主应用程序和单元测试中重用 BigFoo 的编译输出 (*.o)。我不想要 BigFoo 的内部库(*.a 或 *.so)。
BigFoo 正在使用来自目标系统的 Qt5 和 Boost 组件。它还使用作为柯南包提供的组件。
目前的做法:
- 将 BigFoo 构建为静态库 => 通过 target_link_library() 处理依赖项
- 构建 main.cpp 和 *.qml => 与 BigFoo 的链接
- 构建 BigFoo/*Test.cpp => 与 BigFoo 的链接
所需的方法:
- 将 BigFoo 构建为对象库 => 包含依赖项头
- 使用 BigFoo_Object 构建 main.cpp、*.qml => 链接依赖项
- 使用 BigFoo_Object 构建 BigFoo/*Test.cpp => 链接依赖项
所需方法的问题:
在构建 OBJECT 库时,我无法通过 target_include_directories() 包含多个组件的依赖项(Boost::XYZ Qt5::XYZ CONAN_PKG::XYZ 等)。
add_library(Core OBJECT)
# I want to do something like this:
target_include_directories(Core PUBLIC
Qt5::Core
Qt5::Qml
Qt5::Quick
Qt5::Scxml
CONAN_PKG::XYZ
CONAN_PKG::XYZ
)
结果是 CMake(当然)添加了头文件包含路径,如下所示...
-I../../../Application/Qt5::Qml
后来又失败了,因为它不能拆解 Qt 的包含语句。
在构建静态库时,标头包含由 target_link_libraries() 处理,我现在有点困惑如何在不链接任何内容的 OBJECT 库上执行此操作。
我的问题:
- 如何在 OBJECT 库目标中包含 find_package() 和 CONAN_PKG 提供的 CMake 目标的标头?
- 是否有更好/更好的方法来重用 BigFoo,这样我就不会重复编译?
PS:我使用的是 cmake 3.13
【问题讨论】:
-
您想要的方法似乎合理,但您需要更具体地使用“我无法包含”。为什么?有没有错误?在编译或 CMake 配置期间?此外,您使用哪个 CMake 版本,
OBJECT库在较新的版本中有更好的支持。 -
您是否在 CMakeLists.txt 中包含了 conan_basic_setup(TARGETS)? CONAN_PKG 仅在您选择 TARGETS 时才会导出
-
感谢您的提示,我已经更新了问题。
-
是的,我在 conan_basic_setup 上使用了 TARGETS 标志。我还检查了生成的柯南 *.cmake 文件。所有需要的依赖项都导出为 INTERFACE + IMPORTED lib。