我一直在尝试使用 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文件,但肯定
- 这不会在多个 CMake 项目中扩展,并且
- 对于每个项目,这将需要我为构建软件的每个平台(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应该被修复。它不是依赖于平台的解决方案。