如何使用CMake使用install-export和find_package查找并链接到库?

时间:2015-07-21 11:19:28

标签: cmake

您有一个启用CMake的库项目。您需要在另一个库或可执行文件中使用它。如何使用CMake查找并链接到库?您可能有以下偏好:

  • 写尽可能少量的样板代码
  • 将链接库的内部详细信息与使用目标
  • 分离

理想情况下,库的用法应如下所示:

add_executable(myexe ...)
target_link_libraries(myexe mylib::mylib)

1 个答案:

答案 0 :(得分:34)

让我演示一个具体例子的可能解决方案:

myapp项目

我们有一个可执行目标myapp。我们将它与mylib链接,CMakeLists.txt是在自己的构建树中构建的。在myapp mylib中,我们找到并指定myexe作为find_package(mylib REQUIRED) ... add_executable(myexe ...) target_link_libraries(myexe mylib::mylib) 的依赖关系:

mylib

让我们看看如何设置myexemylib的构建以使其发挥作用。

mylib项目

mylib - CMakeLists.txt - mylib.c + include - mylib.h # single public header 的目录布局:

CMakeLists.txt

mylib add_library(mylib mylib.c include/mylib.h) 中,我们需要创建目标并指定其源文件:

mylib.h

公共标题#include "mylib.h"mylibmylib的客户{}包含在mylib中:

  • mylib本身以及include/mylib.h的CMake项目中构建的其他目标(例如测试)需要从mylib源代码树中找到mylib
  • myexe内置自己项目的客户(如include/mylib.h)需要在其安装位置找到mylib

CMake允许我们为target_include_directories(mylib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) 指定两个包含路径:

PUBLIC

我们在这里使用mylib选项,因为PRIVATE的公共接口需要此标头。使用mylib包含INSTALL_INTERFACE内部的包含路径。

CMAKE_INSTALL_PREFIX指定相对于安装根目录的路径,即 set_target_properties(mylib PROPERTIES PUBLIC_HEADER include/mylib.h") 。要实际安装公共标头:

myapp

我们还需要安装库本身以及所谓的配置模块和相关文件。配置模块是消费项目(例如mylib)用于查找.pc并获取与其链接所需的所有参数的文件。它类似于 pkg-config install文件。

我们需要两个相关的install(TARGETS mylib EXPORT mylib-targets PUBLIC_HEADER DESTINATION include ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin) 命令。第一个:

dll

覆盖静态库soDESTINATION lib的所有标准安装位置所需的目标列表。如果您确定您的库将仅作为静态库构建,则可以使用单个EXPORT

有趣的部分是mylib选项。它将目标列表(目前只有mylib-targets)分配给标识符find_package(mylib)。此标识符将在下一个命令中用于生成和安装一些使install(EXPORT mylib-targets NAMESPACE mylib:: FILE mylib-config.cmake DESTINATION lib/cmake/mylib) 在消费项目中工作的特殊文件:

mylib-config.cmake

此命令生成多个文件:

  • 每个构建配置(Debug,Release等)的一个文件,用于描述库文件和与配置相关的参数
  • 描述配置不可知参数的文件,还包括所有与配置相关的文件。由于此文件也可以单独用作配置模块,我们只需将其重命名为${CMAKE_INSTALL_PREFIX}/lib/cmake/mylib

这些文件将安装到find_package(mylib)中,mylib-config.cmakemylib命令搜索CMAKE_INSTALL_PREFIX的众多标准位置之一。

构建mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib

我们需要在变量cmake --build . --target install 中指定安装位置:

myexe

并构建并安装库:

myexe

构建mylib

CMAKE_PREFIX_PATH需要知道在哪里查找mkdir build cd build cmake -DCMAKE_PREFIX_PATH=$PWD/../out ../myexe cmake --build . 。变量Debug可以是路径列表。我们需要指定以前的安装位置:

Release

关于构建多个配置的说明

通常我们需要构建多个配置(DEBUG_POSTFIXset(CMAKE_DEBUG_POSTFIX d) )。关键问题是指定依赖于配置的文件名或安装位置。例如,您可以为库项目设置mylib属性的默认值:

libmylibd.lib

mylibd.lib库文件的调试版本将命名为EXPORT(或Windows上为CMAKE_BUILD_TYPE)。生成的cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib cmake --build . --target install 文件将包含已修改的文件名。

如果你正在使用makefile风格的CMake生成器,你可以通过设置cmake --build . --target install --clean-first 变量来控制构建配置:

Xcode

您可能需要为每个配置分别构建目录,或者您可以重复使用相同的构建目录。在这种情况下,为了安全起见,最好在构建前明确清理:

Visual Studio

如果您正在使用multiconfig IDE生成器,例如cmake -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib cmake --build . --target install --config Release mylib,则需要在构建时指定配置:

myexe

参考

您可以克隆并构建包含{{1}}和{{1}}项目的this repository(在Windows和Linux上测试过)。

查看CMake documentation。最重要的相关命令是:

和两篇详细文章: