使用非标准包含和库目录的 CMake 的最佳做法

  • 本文关键字:CMake 最佳 非标准 包含 cmake
  • 更新时间 :
  • 英文 :


我一直在尝试使用 CMake 在 Linux 机器上构建 Mozilla RR。我们有一个稍微古怪的安排,其中共享库存储在网络驱动器上,例如/sw/external/product-name/linux64_g63.dll/.此外,我已经在$HOME/sw/中为该项目构建了一些依赖项。(我不是这个盒子上的苏多尔。

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

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/

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

如果我省略-DCMAKE_FIND_ROOT_PATH=$HOME/sw/libseccomp-2.2.3/,CMake 会失败,抱怨缺少 libseccomp-2.2.3 依赖项。但是如果我确实有这个定义,它就会起作用,告诉我 CMake 了解 libseccomp-2.2.3 文件的位置,因此将正确添加必要的编译器调用的路径。

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


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

  1. 这不会在多个 CMake 项目中扩展,并且
  2. 对于每个项目,这将需要我为构建软件的每个平台(Solaris/Linux/Darwin/Cygwin)维护一个单独的CMakeLists.txt文件。

有没有解决这个问题的规范解决方案?也许是一个每个站点的配置文件,它将告诉 CMake 如何为我在该站点上构建的所有项目查找库和标头?

你的方法是正确的,但cmake从未被告知要包含SECCOMP - 请参阅本文末尾。

cmake 了解自定义依赖项目录的方式取决于搜索依赖项的方式(即 CMakeLists.txt 中写入的内容)。

find_package/find_library/find_path/find_program

如果使用上述命令之一找到依赖项,则可以使用 CMAKE_PREFIX_PATH 轻松添加自定义搜索目录。无需添加完整路径来包含,lib 或 bin - 当添加包根目录时find_命令将检查相应的子目录。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_PACKAGE
  • CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
  • CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
  • CMAKE_FIND_ROOT_PATH_MODE_PROGRAM

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

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

仅find_package

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

find_package可以在模块配置两种模式下运行。

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

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

find_package(Qt5)

FindQt5.cmake不可用,但 ~/Qt5/Qt5.8/lib/cmake/Qt5Config.cmake 文件存在,因此请添加

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

到cmake call。

pkg-config

CMake 可以使用外部 pkg 配置工具提供的信息。它通常通过pkg_check_modules命令完成。pkg-config 使用的目录可以使用PKG_CONFIG_PATH环境变量进行自定义。根据 cmake 文档而不是设置PKG_CONFIG_PATH,可以通过CMAKE_PREFIX_PATH添加自定义 .pc-files 目录。如果 CMake 版本低于 3.1,则必须将PKG_CONFIG_USE_CMAKE_PREFIX_PATH设置为TRUE(ON)才能启用此功能。

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

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

在 CMakeList 中.txt seccomp 标头使用

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

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

target_include_directories(<target_name> ${SECCOMP})

或全球:

include_directories(${SECCOMP})

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

最新更新