Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法为所有项目设置CMake变量?_Cmake - Fatal编程技术网

有没有办法为所有项目设置CMake变量?

有没有办法为所有项目设置CMake变量?,cmake,Cmake,最近我和CMake一起做了很多项目,总的来说,我觉得它很棒。然而,每当我需要构建一个具有依赖性的项目时,它很快就会成为一个难题 系统安装的依赖关系很好,因为CMake的find_软件包系统通常非常适合查找系统安装的软件包。然而,每当我从源代码构建依赖项时,我发现几乎不可能告诉CMake在哪里可以找到包 我一直在搜索FindFoo.cmake模块,找出它所查看的特殊提示变量,然后将该变量设置为我的库所在的位置。真正的问题是,因为这些提示变量始终是CMake变量,我最终不得不在我自己的CmakeLi

最近我和CMake一起做了很多项目,总的来说,我觉得它很棒。然而,每当我需要构建一个具有依赖性的项目时,它很快就会成为一个难题

系统安装的依赖关系很好,因为CMake的find_软件包系统通常非常适合查找系统安装的软件包。然而,每当我从源代码构建依赖项时,我发现几乎不可能告诉CMake在哪里可以找到包

我一直在搜索
FindFoo.cmake
模块,找出它所查看的特殊提示变量,然后将该变量设置为我的库所在的位置。真正的问题是,因为这些提示变量始终是CMake变量,我最终不得不在我自己的
CmakeList.txt
中设置它们,这是非常脏的,或者将CMake包装在脚本文件中,以确保它传递了查找包所需的所有正确提示变量

我只想设置环境变量,但大多数
FindFoo.cmake
模块实际上并不检查任何环境变量

我研究了使用来帮助解决我的问题,但是如果CMake找到了
FindFoo.CMake
模块,它甚至不需要查看注册表,当
FindFoo.CMake
模块失败时,CMake就会放弃

我要寻找的是在CMake中的“用户范围”或“系统范围”设置变量的方法,这样我就可以在一个地方指定提示变量,而不是跨一堆项目和脚本文件。不幸的是,我似乎找不到任何这样的功能


我在Windows上,但我正在寻找一个尽可能通用的解决方案,因为我可能不在未来。

这是通过
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()
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 -C "~/local.cmake" ..
${PROJECT\u SOURCE\u DIR}/my cmake.path
类似于:

set(CMAKE_PREFIX_PATH ) # some comment to explain what is expected here
set(FOO_ROOT )          # some comment...
由您来维护该文件,其中包含您希望填写的所有变量,以及帮助用户使用该文件的适当注释


路径文件在这里被复制到
PROJECT\u BINARY\u DIR
,但您也可以在所有项目的“公共”路径中复制并使用它。

@was帮助者的回答提到创建一个
my paths.cmake
文件,然后将其导入到我的项目中。这几乎是一个完美的解决方案,只是它仍然需要修改项目。然而,在进一步阅读了cmake手册之后,我意识到它有一个选项可以预加载“初始缓存”
.cmake
文件

因此,我在一个易于访问的位置创建了一个
local.cmake
文件,其中包含如下条目:

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()
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 -C "~/local.cmake" ..
然后,为了配置我的项目,我调用
cmake
,如下所示:

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()
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 -C "~/local.cmake" ..
这个解决方案仍然需要指定一个命令行参数,但它是一个单独的参数,应该很容易记住


(我将暂时不回答这个问题,以防有人提出更好的解决方案。)

您可以定义一个包含所有要使用的路径的环境变量FOO,并通过
-DCMAKE_PREFIX_PATH=$FOO
@usr1234567在搜索解决方案时,我不知怎的错过了CMake_PREFIX_PATH变量,将此变量传递给CMake。我不知道它是否正是我想要的,但它似乎非常有用。编辑CMakeCache或在命令行上指定值基本上是我现在正在做的事情,但我发现对每个项目都这样做既乏味又容易出错。剩下的答案需要修改
CMakeLists.txt
,这感觉很脏,所以我尽量避免。不过,您的回答确实给了我一个非常好的主意,我将尝试一下,所以谢谢。:)