我最近一直在和CMake一起建立很多项目,总的来说,我觉得这很棒。但是,无论何时我需要构建一个具有依赖关系的项目,它很快就会变得很痛苦。
系统安装的依赖项很好,因为CMake的find_package系统通常非常适合查找系统安装的软件包。但是,每当我从源代码构建依赖项时,我发现几乎不可能告诉CMake在哪里找到软件包。
我一直在搜索FindFoo.cmake
模块,找出它正在查看的特殊提示变量,然后将该变量设置为我的库所在的位置。真正的问题是,因为这些提示变量总是CMake变量,所以我最终必须在我自己的CMakeLists.txt
中设置它们,这非常脏,或者在脚本文件中包装cmake以确保它传递给所有需要找到适当的提示变量。
我只想设置环境变量,但大多数FindFoo.cmake
模块实际上并没有检查任何环境变量。
我研究过使用Package Registry来帮助解决我的问题,但如果CMake找到了FindFoo.cmake
模块,它甚至不会在注册表中查找,而CMake只是放弃{ {1}}模块失败。
我正在寻找的是在CMake中在“用户范围”或“系统范围”设置变量的一些方法,所以我可以在一个地方而不是在一堆项目和脚本文件中指定我的提示变量。不幸的是,我似乎无法找到任何此类功能。
我在Windows上,但我正在寻找尽可能多的解决方案,因为我可能不会在将来。
答案 0 :(得分:2)
这是通过cmake-gui
实现的:您设置了路径,它将保留在项目的缓存中,除非删除缓存。
如果您在命令行中使用CMake,则可以将路径作为参数提供:
cmake -DCMAKE_PREFIX_PATH=/some/path -DFOO_ROOT=/some/path/to/foo
另一个选项是将路径设置在单独的文件中,以包含在CMakeLists.txt
中。您可以检查该文件是否存在,并生成一些带有警告消息的模板文件(如果该文件不可用)。像这样:
set(MY_CMAKE_PATHS "${PROJECT_BINARY_DIR}/my-cmake.paths")
if(EXISTS "${MY_CMAKE_PATHS}")
include("${MY_CMAKE_PATHS}")
else()
file(COPY "${PROJECT_SOURCE_DIR}/my-cmake.paths" DESTINATION "${PROJECT_SOURCE_DIR}"
message(FATAL_ERROR
"CMake paths are not available. "
"Please edit the file \"${MY_CMAKE_PATHS}\" with the appropriate values."
)
endif()
${PROJECT_SOURCE_DIR}/my-cmake.paths
就是这样:
set(CMAKE_PREFIX_PATH ) # some comment to explain what is expected here
set(FOO_ROOT ) # some comment...
由您来维护包含您要填充的所有变量的文件,并使用相应的注释来帮助用户使用它。
此处路径文件已复制到PROJECT_BINARY_DIR
,但您也可以在所有项目的“公共”路径中复制并使用它。
答案 1 :(得分:0)
@wasthehelpful的回答提到创建一个my-paths.cmake
文件,然后将其导入我的项目。这几乎是一个完美的解决方案,除了它仍然需要修改项目。但是,在阅读了cmake手册之后,我意识到它可以选择预加载“初始缓存”.cmake
文件。
所以我在一个易于访问的位置创建了一个local.cmake
文件,其中填充了以下条目:
set(ZLIB_ROOT "`~/builds/zlib-1.2.8" CACHE PATH "")
set(PNG_ROOT "~/builds/libpng-1.6.27" CACHE PATH "")
set(OSG_DIR "~/builds/OpenSceneGraph_3.4.0" CACHE PATH "")
然后,为了配置我的项目,我像这样调用cmake
:
cmake -C "~/local.cmake" ..
这个解决方案仍然需要指定一个命令行参数,但它只是一个参数,应该很容易记住。
(如果有人想出更好的解决方案,我会暂时不回答这个问题。)