CMake与非标准包含和库目录的最佳实践

时间:2018-02-04 16:36:25

标签: cmake

我一直在尝试使用CMake在Linux机器上构建Mozilla RR。我们有一个稍微偏心的安排,共享库存储在$HOME/sw/等位置的网络驱动器上。此外,我在PKG_CONFIG_PATH=$HOME/sw/capnproto-0.6.1/lib/pkconfig \ CC=gcc-6.3 CXX=g++-6.3 \ cmake \ -DCMAKE_INSTALL_PREFIX=$HOME/sw/rr-5.1.0 \ -DPYTHON_EXECUTABLE=$HOME/bin/python2 \ -DCMAKE_FIND_ROOT_PATH=$HOME/sw/libseccomp-2.2.3/ \ ../src/ 中为项目构建了一些依赖项。 (我不是这个盒子上的sudoer。)

我感到很困惑,因为我应该如何与CMake通信以查看非标准目录。到目前为止,我已经捏造了:

-DCMAKE_FIND_ROOT_PATH=$HOME/sw/libseccomp-2.2.3/

这显然不是一个可扩展的解决方案,但它至少可以成功完成配置并发出一些Makefile。

如果我省略make,则CMake失败,抱怨缺少libseccomp-2.2.3依赖。但是,如果我确实有这个定义,它会工作,告诉我CMake了解libseccomp-2.2.3文件的位置,因此将正确地添加到必要的编译器调用的路径。

但是,gcc未成功,因为make VERBOSE=1无法从libseccomp probject中找到所需的头文件。检查-I$HOME/sw/libseccomp-2.2.3/include,我发现CMake尚未将gcc添加到{{1}}调用中。

我觉得这不是正确的做法。我看过的其他答案告诉我修改CMakeLists.txt文件,但肯定是

  1. 不会在多个CMake项目中进行扩展,而且
  2. 对于每个项目,需要我为每个平台(Solaris / Linux / Darwin / Cygwin)维护一个单独的CMakeLists.txt文件。我构建了该软件。
  3. 是否有解决此问题的规范解决方案?对于我在该网站上构建的所有项目,可能是一个每站点配置文件,它将告诉CMake如何查找库和头文件?

1 个答案:

答案 0 :(得分:2)

您的方法是正确的,但cmake从未被告知要包含SECCOMP - 请参阅此帖的结尾。

cmake可以通知自定义依赖项目录的方式取决于如何搜索依赖项(即在CMakeLists.txt中写入的内容)。

find_package / find_library / find_path / find_program

如果发现上述命令之一存在依赖关系,则可以使用CMAKE_PREFIX_PATH轻松添加自定义搜索目录。无需添加include,lib或bin的完整路径 - 添加软件包根目录时 find _ -command将检查相应的子目录。 CMAKE_PREFIX_PATH也可以使用环境变量设置。

第二个选项是CMAKE_FIND_ROOT_PATH。添加到 CMAKE_FIND_ROOT_PATH 列表的每个路径都被视为单独的根目录,并在系统根目录之前进行搜索。 请注意,带有 NO_CMAKE_FIND_ROOT_PATH 参数的 find _ 命令将忽略 CMAKE_FIND_ROOT_PATH

以下四个变量可用于调整 CMAKE_FIND_ROOT_PATH 的使用情况:

如果不希望使用主机系统默认库,则将 CMAKE_FIND_ROOT_PATH_MODE_INCLUDE CMAKE_FIND_ROOT_PATH_MODE_LIBRARY 设置为 ONLY 是一种很好的做法。如果在 CMAKE_FIND_ROOT_PATH 中找不到依赖项库或标头,则配置将失败。如果允许cmake搜索系统路径,则很可能在链接步骤甚至运行时期间发生错误。

有关详细信息,请参阅find_package文档。

仅限find_package

以上所有内容也适用于 find_package 命令。

find_package 可以在两种模式下运行 MODULE CONFIG

MODULE 模式下,cmake使用Find [PackageName] .cmake脚本(模块)来查找依赖包。 CMake附带了大量模块,可以使用 CMAKE_MODULE_PATH 变量添加自定义模块。通常可以通过环境或cmake变量向find模块通知自定义搜索路径。 例如。 FindGTest.cmake 搜索存储在 GTEST_ROOT 变量中的路径。

如果没有可用的查找模块, find_package 进入 CONFIG 模式。如果依赖包提供了[PackageName] Config.cmake或[LowercasePackageName] -config.cmake,则可以使用[PackageName] _DIR变量轻松通知cmake该包。 例: CMakeLists.txt包含:

find_package(Qt5)

FindQt5.cmake不可用,但〜/ Qt5 / Qt5.8 / lib / cmake / Qt5Config.cmake文件存在,所以添加

-DQt5_DIR="${HOME}/Qt5/Qt5.8/lib/cmake"

给cmake打电话。

pkg配置

CMake可以使用外部pkg-config工具提供的信息。通常使用 pkg_check_modules 命令完成。 pkg-config使用的目录可以使用 PKG_CONFIG_PATH 环境变量进行自定义。根据{{​​3}}而不是设置 PKG_CONFIG_PATH ,可以通过 CMAKE_PREFIX_PATH 添加自定义.pc文件目录。如果CMake版本在3.1之前, PKG_CONFIG_USE_CMAKE_PREFIX_PATH 必须设置为 TRUE ON )才能启用此功能。

自定义依赖关系的方法搜索路径由CMakeLists.txt内容定义。这里没有通用的解决方案。

现在回到缺少的SECCOMP标题......

在CMakeLists.txt中找到SECCOMP标头

find_path(SECCOMP NAMES "linux/seccomp.h")

但我找不到告诉CMake使用找到的标头的命令。例如:

target_include_directories(<target_name> ${SECCOMP})

或全球:

include_directories(${SECCOMP})

我相信应该修复CMakeLists.txt。它不是依赖于平台的解决方案。