C++ 使基于makefile的cmake项目在环境变量更改时自动运行make rebuild_缓存

C++ 使基于makefile的cmake项目在环境变量更改时自动运行make rebuild_缓存,c++,c,cmake,C++,C,Cmake,在我的cmake配置中,几个变量取决于环境变量,以便正确设置。此环境变量可以更改,这意味着应重新生成cmake的缓存 我的配置可以在调用另一个对“cmake”的调用或调用“make rebuild_cache”时检测是否需要重新配置并更新相应的缓存项 但是,我希望无论何时运行,都能自动检查是否有更改,并在必要时运行rebuild_缓存目标 这可能吗?Make没有内存。make无法“记住”上次运行make时给定环境变量的设置 除非将环境变量写入文件 我从未使用过CMake,所以我不知道如何最好地实

在我的cmake配置中,几个变量取决于环境变量,以便正确设置。此环境变量可以更改,这意味着应重新生成cmake的缓存

我的配置可以在调用另一个对“cmake”的调用或调用“make rebuild_cache”时检测是否需要重新配置并更新相应的缓存项

但是,我希望无论何时运行,都能自动检查是否有更改,并在必要时运行rebuild_缓存目标


这可能吗?

Make没有内存。make无法“记住”上次运行make时给定环境变量的设置

除非将环境变量写入文件

我从未使用过CMake,所以我不知道如何最好地实现它。但在“原始”制造水平上,总体思路是:

1) 编写一条规则(例如,
envir\u cache
),将环境变量写入文件(命名为
envir\u cache
),前提是该文件尚不存在,或者该文件存在,但其内容与环境变量的值不同。(类似于
if[-f envir_cache]
read cached_var
if[“${myvar}”!=“${cached_var}”]

2) 使目标
重建缓存
依赖于
环境缓存


这样,在第一次运行时,以及在两次运行之间变量发生变化时,将执行
重建缓存
规则。

使用CMake不容易做到这一点,但下面显示了如何作为CMake包含模块来实现这一点的示例。解决方案取决于使用一个自定义目标,该目标将相关变量输出到一个文件,并调用cmake compare_files选项将上一个文件与验证文件进行比较,如果不匹配,则调用cmake重建缓存

该解决方案涉及一个精心编制的CMake include模块,该模块将递归调用自身,以验证缓存的值没有被环境变量更改。如果有,它将通过使用如下所示的适当参数调用cmake来执行重建缓存步骤。对于希望能够使用环境变量覆盖的每个变量,您都将调用add_option宏(请参见下面的示例):

如果上面的CMake模块名为add_option.CMake,您可以按如下方式使用它:

cmake_minimum_required(VERSION 2.8)
project(Example)
include(${PROJECT_SOURCE_DIR}/add_option.cmake)
add_option(MYVAR
  BOOL
  "A boolean cached value that can be overridden by Environment variable"
  ON)
add_option(MYSTR
  STRING
  "A string cached value that can be overridden by Environment variable"
  "some string")
message(STATUS "MYVAR=${MYVAR}")
message(STATUS "MYSTR=${MYSTR}")
使用上述CMakeLists.txt文件执行以下操作(使用Unix Makefiles):

下面的示例演示了Unix Makefiles的初始创建。注意:在这种情况下,变量使用它们的默认值

cmake .. -G "Unix Makefiles"
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- MYVAR=ON
-- MYSTR=some string
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/example/build
下面的示例显示make如何调用由上面的add_option.cmake模块创建的检查变量目标及其从属目标。请注意,没有重建缓存是如何发生的

make
Scanning dependencies of target check-MYVAR
[ 50%] Checking variable 'MYVAR' for changes
[ 50%] Built target check-MYVAR
Scanning dependencies of target check-MYSTR
[100%] Checking variable 'MYSTR' for changes
[100%] Built target check-MYSTR
Scanning dependencies of target check-variables
[100%] Built target check-variables
以下示例显示环境变量如何导致某个检查变量步骤失败并触发重建缓存事件。请注意在缓存重建过程中MYVAR值的变化

make MYVAR=off
[ 50%] Checking variable 'MYVAR' for changes
-- MYVAR=off
-- MYSTR=some string
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/example/build
[ 50%] Built target check-MYVAR
[100%] Checking variable 'MYSTR' for changes
[100%] Built target check-MYSTR
[100%] Built target check-variables
下面的示例显示如何将上面临时更改的变量恢复为默认值,并触发另一个变量以更改其值。请注意,MYVAR变量将恢复为其默认值,而MYSTR变量将获得提供的新值

make MYSTR="hi mom"
[ 50%] Checking variable 'MYSTR' for changes
-- MYVAR=ON
-- MYSTR=hi mom
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/example/build
[ 50%] Built target check-MYSTR
[100%] Checking variable 'MYVAR' for changes
[100%] Built target check-MYVAR
[100%] Built target check-variables

谢谢你的回复;这似乎是可行的,我只是还没有时间去尝试。一旦我这样做了,我将把答案标记为已接受。
make MYVAR=off
[ 50%] Checking variable 'MYVAR' for changes
-- MYVAR=off
-- MYSTR=some string
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/example/build
[ 50%] Built target check-MYVAR
[100%] Checking variable 'MYSTR' for changes
[100%] Built target check-MYSTR
[100%] Built target check-variables
make MYSTR="hi mom"
[ 50%] Checking variable 'MYSTR' for changes
-- MYVAR=ON
-- MYSTR=hi mom
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/example/build
[ 50%] Built target check-MYSTR
[100%] Checking variable 'MYVAR' for changes
[100%] Built target check-MYVAR
[100%] Built target check-variables