解耦应用程序和库在CMake项目

decoupling app and libraries in CMake project

本文关键字:CMake 项目 应用程序 解耦      更新时间:2023-10-16

我有一个项目配置为:

CMake项目

  • 静态Lib A src(依赖于B)
      静态Lib B src(依赖于Qt)
  • App src(静态链接LibA)
  • 每个文件夹都有自己的CMakeLists.txt,但都是同一个CMake项目的一部分。一切正常。

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

    应用程序类似地成为自己的CMake包,我认为我只需要find_package(LibA)。事实证明,我还需要在LibB上使用find_package,因为应用程序需要一个头文件。但意想不到的是,应用程序需要在Qt5Widgets、Qt5Core和Qt5Gui上进行find_package,就像LibB所做的那样。这就是我不太明白的地方。当一切都是一个巨大的项目时,应用程序的CMakeLists.txt只需要链接到LibA。其他的事我都不知道就搞定了吗?我天真地认为在LibA和LibB上执行find_package会以某种方式导致Qt库被链接到应用程序中吗?

    这可能是一个糟糕的问题,因为我的东西又工作了。我只是想确保我理解了原因。

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

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

    共享(动态)库是一个更复杂(和通用)的东西,允许加载和链接代码运行时。这是由一个动态链接器完成的,它还会递归地给它加载的库的任何依赖项。

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