嵌入库及其's包括通过CMake

Embedding library and it's includes via CMake

本文关键字:包括通 CMake      更新时间:2023-10-16

我正在创建一个非常小的项目,它依赖于以下库:https://github.com/CopernicaMarketingSoftware/AMQP-CPP

我一直在做我对第三方库所做的事情:我将它们的git-reo添加为子模块,并将它们与我的代码一起构建:

option(COOL_LIBRARY_OPTION ON)
add_subdirectory(deps/cool-library)
include_directories(deps/cool-library/include)
target_link_libraries(${PROJECT_NAME} coollib)

这对于Bullet、GLFW和其他库来说非常有效。然而,这个AMQP库做了一个相当丑陋的破解。他们的include目录称为include,但在CMake install()命令中,他们将其重命名为amqpcpp。它们的主标头deps/cool-library/amqpcpp.h引用了使用该"伪"目录的所有其他标头。

结果是:当CMake试图编译依赖于deps/cool-library/amqpcpp.h的源代码时,它失败了,因为它找不到deps/cool-library/amqpcpp/*.h,只找到了deps/cool-library/include

有人知道我如何在不必将库绑定到我的代码库中的情况下解决这个问题吗?

这不是CMake的工作方式。

CMake通常构建一个库的整个分布式包一次,然后将其安装到某个前缀路径。然后,系统上的每个其他构建进程都可以通过说"find_package()"来访问它。此命令自动查找已安装的distribution以及所有的libs、includes等。无论库实现者做了什么奇怪的事情,最终的发行版或多或少都是相似的。

因此,在这种情况下,您通过手动添加include来完成许多不必要的工作。正如你所看到的,它也可能是不可靠的。

你能做的是:

  • 仍然在子模块中拥有所有依赖性源发行版(不过通常人们不会这么做)
  • 使用它们自己的CMakeLists.txt将每个依赖包构建并安装到项目内或项目外的另一个(.gitignored)文件夹中。假设在CMakeLists.txt中使用自定义构建步骤
  • 构建应用程序时,请在CMakeLists.txt中使用"find_package()"

Drop的答案还有两个小补充:如果库正确设置了安装例程,您可以直接在库的二进制树上使用find_package,跳过安装步骤。当您对库和依赖项目都进行更改时,这一点非常有用,因为您不必每次都运行INSTALL目标来使库更改在下游可用。

此外,请查看CMake的ExternalProject模块,它非常方便将外部依赖项作为项目的一部分自动构建。一般的想法是,您仍然将库的源代码作为子模块引入,但不是使用add_subdirectory将源代码引入您的项目,而是使用ExternalProject_Add自行构建它,然后从您的项目中链接它。