在我的 cmake 配置中,几个变量依赖于环境变量才能正确设置。该环境变量可以更改,这意味着应该重建 cmake 的缓存。
我的配置可以检测到重新配置的需要,并在调用另一个“cmake”调用或调用“makerebuild_cache”时更新适当的缓存条目。
但是,我希望每当我运行时都会自动检查更改,并在必要时运行rebuild_cache目标。
这可能吗?
In my cmake configuration several variables depend on an environment variable in order to be set correctly. This environment variable can change and it means that the cache for cmake should be rebuilt.
My configuration can detect the need for this reconfigure and update the appropriate cache entries when either another call to "cmake " is called or "make rebuild_cache" is called.
However, I would like whenever I run make it to be checked automatically for changes and have the rebuild_cache target run if necessary.
Is this possible?
发布评论
评论(2)
Make没有记忆。 make 无法“记住”上次运行 make 时给定环境变量的设置。
除非您将环境变量写入文件。
我从未使用过 CMake,所以我不知道如何最好地实现它。但在“原始”make 级别上,总体思路是:
1)编写一条规则(例如,
envir_cache
),将环境变量写入文件(命名为,并非巧合,envir_cache
),如果该文件尚不存在,或该文件存在但其内容与环境变量的值不同。 (类似于if [ -f envir_cache ]
和read cached_var 和
if [ "${myvar}" != "${cached_var }" ]
。)2)使目标
rebuild_cache
依赖于envir_cache
。这样,
rebuild_cache
规则将在第一次运行时以及每次运行之间变量发生更改时执行。Make does not have a memory. There is no way for make to "remember" what a given environment variable was set to the last time make was run.
Unless you write the environment variable to a file.
I've never used CMake, so I don't know how to best implement it. But on the "raw" make level, the general idea would be to:
1) write a rule (say,
envir_cache
) which writes the environment variable to file (named, not so coincidentially,envir_cache
), if that file does not yet exist, or the file exists but its contents are different from the value of the environment variable. (Something along the lines ofif [ -f envir_cache ]
andread cached_var < envir_cache
andif [ "${myvar}" != "${cached_var}" ]
.)2) make the target
rebuild_cache
depend onenvir_cache
.That way, the
rebuild_cache
rule will be executed on the first run, and whenever the variable changed between runs.使用 CMake 不容易完成此操作,但下面显示了如何以 CMake 包含模块的形式执行此操作的示例。该解决方案取决于使用自定义目标,该目标将有问题的变量输出到文件,并调用 cmake Compare_files 选项将前一个文件与验证文件进行比较,并在它们不匹配时调用 cmake 重建缓存。
该解决方案涉及一个精心设计的 CMake include 模块,该模块将递归调用自身以验证缓存的值没有被环境变量更改。如果有,它将通过使用适当的参数调用 cmake 来执行重建缓存步骤,如下所示。预计您将为您希望能够使用环境变量覆盖的每个变量调用 add_option 宏(请参见下面的示例):
如果上述 CMake 模块名为 add_option.cmake 您可以按如下方式使用它
: CMakeLists.txt 文件执行以下操作(使用 Unix Makefile):
以下示例演示了 Unix Makefile 的初始创建。请注意,在这种情况下,变量使用其默认值。
以下示例显示 make 如何调用上面的 add_option.cmake 模块创建的 check-variables 目标及其依赖目标。请注意如何不发生重建缓存。
以下示例显示环境变量如何导致检查变量步骤之一失败并触发重建缓存事件。请注意缓存重建过程中 MYVAR 值的变化。
以下示例显示了上面临时更改的变量如何恢复为默认值,以及如何触发不同的变量来更改其值。请注意,当 MYSTR 变量获取提供的新值时,MYVAR 变量将恢复为其默认值。
This is not easily done with CMake, but an example of how to do this as a CMake include modules is shown below. The solution depends on using a custom target that outputs the variables in question to a file and calls the cmake compare_files option to compare the previous file to the verify file and calls cmake to rebuild the cache in the event they don't match.
The solution involves a carefully crafted CMake include module that will recursively call itself to verify the cached values haven't been changed by an Environment variable. If it has, it will perform the rebuild cache step by calling cmake with appropriate arguments as shown below. It is expected that you will call the add_option macro for every variable you want to be able to override using an Environment variable (see examples below):
If the above CMake module was named add_option.cmake you could use it as follows:
With the above CMakeLists.txt file do the following (using Unix Makefiles):
The following example demonstrates the initial creation of the Unix Makefiles. Note the variables use their default values in this case.
The following example shows how make can invoke the check-variables target and its dependent targets created by the add_option.cmake module above. Notice how no rebuild cache occurs.
The following example shows how an environment variable causes one of the check-variables step to fail and triggers a rebuild cache event. Note the change in the MYVAR value during the cache rebuild process.
The following example shows how the variable changed temporarily above is reverted back to the defaults and a different variable is triggered to change its value. Note the MYVAR variable revert back to its default value while the MYSTR variable obtains a new value provided.