如何使用CMake查找和链接到库使用install-export和find_package? [英] How to use CMake to find and link to a library using install-export and find_package?

查看:586
本文介绍了如何使用CMake查找和链接到库使用install-export和find_package?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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




  • 写尽可能少的样板代码

  • 将链接库的内部细节从使用目标中解耦



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

  add_executable(myexe ...)
target_link_libraries(myexe mylib)
让我来演示一个具体例子的可能的解决方案:



h1> myapp 项目

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

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

让我们来看看如何设置 mylib myexe p>

mylib 项目



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 将作为 #includemylib.h两个都由 mylib mylib 的客户:




  • mylib 本身和其他目标内置于 mylib 的CMake项目例如测试)需要从 mylib 源代码树
  • 中找到 include / mylib.h b
  • 在其自己的项目(如 myexe )中创建 mylib 的客户需要查找 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)

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



需要两个,相关的 install 命令。第一个:

 安装(TARGETS mylib 
导出mylib目标
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)

覆盖所有标准安装静态库的位置, dll 所以的。如果您确定您的库将仅作为静态库构建,则单个 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 code> 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 h1>

myexe 需要知道在哪里查找 mylib 。变量 CMAKE_PREFIX_PATH 可以是路径列表。我们需要指定先前的安装位置:

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



有关构建多个配置的注意事项



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

  set(CMAKE_DEBUG_POSTFIX d)

mylib 库文件将命名为 libmylibd.lib (或在Windows上命名为 mylibd.lib EXPORT 文件将包含修改的文件名。



如果您使用makefile风格的CMake生成器,通过设置 CMAKE_BUILD_TYPE 变量来控制构建配置:

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

您可能需要为每个配置分别构建目录,或者可以重复使用构建目录。在这种情况下,为了安全起见,最好在build之前显式清除:

  cmake --build。 --target install --clean-first 

如果您使用多配置IDE生成器, code> Xcode 或 Visual Studio ,您需要在构建时指定配置:

  cmake -DCMAKE_INSTALL_PREFIX = $ PWD /../ out ../mylib 
cmake --build。 --target install --config发布



参考



您可以克隆并构建此存储库,其中包含 mylib



c> a href =http://www.cmake.org/cmake/help/v3.3> CMake文档。最重要的相关命令是:





和两个详细文章:




You have a CMake-enabled library project. You need to use it in another library or executable. How to use CMake to find and link to the library? You may have the following preferences:

  • write the least possible amount of boiler-plate code
  • decouple the internal details of the linked library from the consuming target

Ideally, the usage of the library should look like this:

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

解决方案

Let me demonstrate a possible solution on a concrete example:

The myapp project

We have an executable target myapp. We're linking it with mylib, which is built in its own build tree. In the CMakeLists.txt of myapp we find and specify mylib as a dependency of myexe:

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

Let's see how to set up mylib and the build of myexe to make this work.

The mylib project

The directory layout of mylib:

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

In the CMakeLists.txt of mylib we need to create the target and specify its source files:

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

The public header mylib.h will be included as #include "mylib.h" both by mylib and the clients of mylib:

  • mylib itself and other targets built in mylib's CMake project (for example tests) need to find include/mylib.h from the mylib source tree
  • clients of mylib built in their own projects (like myexe) need to find include/mylib.h at its installed location

CMake allows us to specify both include paths for mylib:

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

We're using the PUBLIC option here since this header is needed on the public interface of mylib. Use PRIVATE for include paths internal to mylib.

The INSTALL_INTERFACE specifies a path relative to the install root, that is, CMAKE_INSTALL_PREFIX. To actually install the public header:

    install(FILES include/mylib.h DESTINATION include)

We also need to install the library itself and the so-called config-module and related files. The config-module is the file which will be used by consuming projects, like myapp to find mylib and get all the parameters needed to link with it. It is similar to the pkg-config's .pc files.

We need two, related install commands. The first one:

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

The list of destinations needed to cover all the standard install locations of static libraries, dll's and so's. If you're sure your library will be built exclusively as a static lib, a single DESTINATION lib would make it.

The interesting part is the EXPORT option. It assigns the list of targets (currently, it's only mylib) to the identifier mylib-targets. This identifier will be used in the next command to generate and install some special files which make find_package(mylib) work in the consuming projects:

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

This command generates multiple files:

  • one file for each build configuration (Debug, Release, etc..) which describes the library file and configuration-dependent parameters
  • a file which describes the configuration-agnostic parameters and also includes all the config-dependent files. Since this file can also be used as a config-module on its own we simply rename it as mylib-config.cmake

The files will be installed into ${CMAKE_INSTALL_PREFIX}/lib/cmake/mylib which is one of the many standard locations the find_package(mylib) command will search for mylib-config.cmake.

Building mylib

We need to specify an install location in the variable CMAKE_INSTALL_PREFIX:

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

and build and install the library:

cmake --build . --target install

Building myexe

myexe needs to know where to look for mylib. The variable CMAKE_PREFIX_PATH can be a list of paths. We need to specify the previous install location:

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

A note on building multiple configurations

Usually we need to build multiple configurations (Debug, Release). A critical issue is to specify configuration-dependent filenames or install locations. For example, you can set the default value of the DEBUG_POSTFIX property for the library project:

set(CMAKE_DEBUG_POSTFIX d)

The debug version of the mylib library file will be named libmylibd.lib (or mylibd.lib on Windows). The generated EXPORT files will contain the modified filenames.

If you're using makefile-style CMake generators you can control the build configuration by setting the CMAKE_BUILD_TYPE variable:

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

You may need seperate build directories for each configuration or you can re-use the same build dir. In that case, to play it safe it's best to explicitly clean before build:

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

If you're using a multiconfig IDE generator, like Xcode or Visual Studio, you need to specify the configuration in build time:

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

References

You can clone and build this repository which contains the mylib and myexe projects (tested on Windows and Linux).

Check out the CMake documentation. The most important related commands are:

and two detailed articles:

这篇关于如何使用CMake查找和链接到库使用install-export和find_package?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆