c++ - 在 CMake 项目中解耦应用程序和库

标签 c++ cmake

我有一个项目,配置为:

CMake 项目

  • 静态库 A src(取决于 B)
    • 静态Lib B src(取决于Qt)
  • 应用 src(与 LibA 静态链接)

每个文件夹都有自己的 CMakeLists.txt,但都是同一个 CMake 项目的一部分。事情进展顺利。

然后为了更容易地将库源和应用程序源分离到不同的源代码存储库中,我开始学习CMake包的创建以及在LibA上执行find_package。我重新安排了一些事情,现在这些库是它们自己的 CMake 项目,这需要我运行“cmake --build . --target install”将包放在公共(public)区域中(而不是放在构建文件夹中)。

该应用程序同样成为了自己的 CMake 包,我认为我只需要 find_package(LibA)。事实证明,我还需要在 LibB 上 find_package,因为应用程序需要一个 header 。但意想不到的是,App 需要像 LibB 一样在 Qt5Widgets、Qt5Core 和 Qt5Gui 上 find_package。这是我不太明白的部分。当一切都是一个巨大的项目时,应用程序的 CMakeLists.txt 只需要链接到 LibA。难道其他的事情都在我不知情的情况下被处理了吗?我是否天真地认为在 LibA 和 LibB 上执行 find_package 会以某种方式导致 Qt 库也链接到应用程序?

这可能是一个糟糕的问题,因为我的事情又恢复正常了。我只是想确保我理解原因。

最佳答案

在 C++ 中使用静态库不会引入它们的依赖项,因此必须在链接可执行文件时显式指定它们(与动态库相比)。

一个static library本质上是一个预编译的函数存档(目标文件),它通过 C++ 链接器以与任何其他目标文件类似的方式链接到您的应用程序。因此,它不包含有关其依赖项的信息。

一个shared (dynamic) library是一个更复杂(和通用)的东西,允许加载和链接代码运行时。这是由 dynamic linker 完成的,这也会递归地带来加载库的任何依赖项。

因此,如果您想避免显式指定依赖项,动态库可能是更好的选择(出于各种其他原因,它也可能是更好的选择:))。

关于c++ - 在 CMake 项目中解耦应用程序和库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40096665/

相关文章:

c++ - BOOST 程序选项命令行的格式是什么?

c++ - 通过 Eclipse CDT 访问 GDB

C++ Type Wrapper printf 打印错误的浮点值

c++ - 编译命令成功,链接错误 undefined reference 符号 '_ZNSt3__15mutex4lockEv'

windows - PATH 环境如何影响我正在运行的可执行文件,从使用 msvcr90 到 msvcr80?

c++ - 如何修复 'Vcpkg/CMake Is Unable to determine target architecture'(Windows10、vcpkg、clion、cmake)

c++ - 我可以从多个目标创建一个库吗?

c++ - 编译时纯虚函数

c++ - 防止 QSettings 将组织名称添加到 QSettings::setPath() 设置的路径中

qt - CMake : detect "Q_OBJECT" in a file and add it to a list of file to treat by MOC