2015-07-21 194 views
8

您有一个CMake启用的库项目。您需要在另一个库或可执行文件中使用它。如何使用CMake查找并链接到图书馆?你可以具有以下优选:如何使用CMake查找并使用install-export和find_package链接到库?

  • 写的锅炉板代码尽可能少
  • 解耦链接库的内部细节从消费目标

理想情况下,该使用图书馆应该是这样的:

add_executable(myexe ...) 
target_link_libraries(myexe mylib) 
+0

[CMake的链接到外部库(可能的重复http://stackoverflow.com/questions/8774593/cmake-link-to-external-图书馆) – usr1234567

回答

18

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

myapp项目

我们有一个可执行的目标myapp。我们将它与mylib链接起来,它是在它自己的构建树中构建的。在myappCMakeLists.txt我们发现并指定mylib作为myexe依赖:

find_package(mylib REQUIRED) 
... 
add_executable(myexe ...) 
target_link_libraries(myexe mylib) 

让我们来看看如何设置mylibmyexe构建,使这项工作。

mylib项目

mylib的目录布局:

mylib 
- CMakeLists.txt 
- mylib.c 
+ include 
    - mylib.h # single public header 

mylibCMakeLists.txt我们需要创建目标,并指定其源文件:

add_library(mylib mylib.c include/mylib.h) 

公众标题mylib.h将包含为#include "mylib.h"既通过mylibmylib客户:

  • mylib本身建于mylib的CMake的项目(如测试)等目标需要找到include/mylib.hmylib源代码树的mylib
  • 客户建立他们的自己的项目(如myexe)需要在的安装位置找到include/mylib.h

CMake的允许我们指定既包括mylib路径:

target_include_directories(mylib PUBLIC 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> 
    $<INSTALL_INTERFACE:include>) 

我们在这里使用PUBLIC选择,因为需要的mylib公共接口上这个头。使用PRIVATE作为mylib内部的包含路径。

INSTALL_INTERFACE指定相对于安装根目录的路径,即CMAKE_INSTALL_PREFIX。要实际安装公用标头:

install(FILES include/mylib.h DESTINATION include) 

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

我们需要两个相关的install命令。第一招:覆盖所有标准安装静态库,dll的和so的位置所需要的目的地

install(TARGETS mylib 
    EXPORT mylib-targets 
    ARCHIVE DESTINATION lib 
    LIBRARY DESTINATION lib 
    RUNTIME DESTINATION bin) 

列表。如果你确定你的库只能作为一个静态库被构建,那么一个DESTINATION lib就可以做到。

有趣的部分是EXPORT选项。它将目标列表(目前只有mylib)分配给标识mylib-targets。该标识将在未来命令用来生成和消费项目中安装一些特殊的文件,这使find_package(mylib)工作:

install(EXPORT mylib-targets 
    FILE mylib-config.cmake 
    DESTINATION lib/cmake/mylib) 

此命令生成多个文件:

  • 一个文件,每个构建配置(Debug,Release等),它描述了库文件和依赖于配置的参数
  • 一个描述配置无关参数的文件,也包括所有依赖于配置的文件。由于这个文件也可以被用来作为自己的一个配置模块,我们只需将其重命名为mylib-config.cmake

文件将被安装到${CMAKE_INSTALL_PREFIX}/lib/cmake/mylib这是许多标准位置find_package(mylib)命令将为mylib-config.cmake搜索之一。

建设mylib

我们需要指定一个可变CMAKE_INSTALL_PREFIX安装位置:

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

,并建立和安装库:

cmake --build . --target install 

大厦myexe

myexe需要知道在哪里寻找mylib。变量CMAKE_PREFIX_PATH可以是路径列表。我们需要指定前面的安装位置:构建多种配置

通常我们需要建立多种配置(DebugRelease

mkdir build 
cd build 
cmake -DCMAKE_PREFIX_PATH=$PWD/../out ../mylib 
cmake --build . 

的注意事项。一个关键问题是指定配置相关的文件名或安装位置。例如,您可以为库项目设置DEBUG_POSTFIX属性的默认值:

set(CMAKE_DEBUG_POSTFIX d) 

mylib库文件的调试版本将被命名为(在Windows或mylibd.liblibmylibd.lib。生成的EXPORT文件将包含修改后的文件名。

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib 
cmake --build . --target install 

您可能需要单独的编译目录的每个配置,也可以重复使用相同的:

如果你使用的makefile风格CMake的发电机,你可以通过设置变量CMAKE_BUILD_TYPE控制构建配置建立目录。在这种情况下,为了安全起见,最好明确地干净的构建之前:

cmake --build . --target install --clean-first 

如果您使用的是multiconfig IDE发电机,像XcodeVisual Studio,你需要指定编译时间配置:

cmake -DCMAKE_INSTALL_PREFIX=$PWD/../out ../mylib 
cmake --build . --target install --config Release 

参考

您可以克隆和构建this repository其中包含mylibmyexe项目(在Windows和Linux测试)。

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

和两个DETA ILED的文章: