英文:
What reasons are there to discourage accessing CMake cache variables using `$CACHE{variable}`?
问题
# 问题
我正在阅读[Professional CMake](https://crascit.com/professional-cmake/),第5.5节“变量的潜在意外行为”不建议使用`$CACHE{variable}`来访问缓存变量,除非用于调试。确切的引用如下:
> 项目通常不应该使用这个,除非用于临时调试,因为它破坏了长期以来的期望,即普通变量将覆盖在缓存中设置的值。
我不理解这个理由,所以我创建了两个示例。第一个示例使用了`$CACHE{variable}`,第二个示例通过取消设置遮盖缓存变量的普通变量来避免使用它。
**方法1:**
```cmake
cmake_minimum_required(VERSION 3.27)
project(example)
set(variable "Hello" CACHE STRING "An example variable" FORCE)
set(variable "Goodbye")
message("The normal variable's value is ${variable}.")
message("The cache variable's value is $CACHE{variable}.")
方法2:
cmake_minimum_required(VERSION 3.27)
project(example)
set(variable "Hello" CACHE STRING "An example variable" FORCE)
set(variable "Goodbye")
message("The normal variable's value is ${variable}.")
unset(variable)
message("The cache variable's value is ${variable}.")
两者都产生了预期的输出:
The normal variable's value is Goodbye.
The cache variable's value is Hello.
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: ...
因此,似乎$CACHE{variable}
更能显示作者的意图,而${variable}
虽然破坏了"长期期望",但我很难看出有人会因此而感到困惑。
我在Google上找不到任何信息,我查看了最新版本(3.27)的CMake文档,但它没有提到是否应该使用它。
问题
目前,我更喜欢使用$CACHE{variable}
的简洁性和简洁性,我想知道除了破坏"长期期望"之外,是否有任何理由不应该在CMakeLists.txt
中使用$CACHE{variable}
来访问所有缓存变量?
Here's the translation of your text. Let me know if you need any further modifications or the complete code:
```markdown
# 问题
我正在阅读[Professional CMake](https://crascit.com/professional-cmake/),第5.5节“变量的潜在意外行为”不建议使用`$CACHE{variable}`来访问缓存变量,除非用于调试。确切的引用如下:
> 项目通常不应该使用这个,除非用于临时调试,因为它破坏了长期以来的期望,即普通变量将覆盖在缓存中设置的值。
我不理解这个理由,所以我创建了两个示例。第一个示例使用了`$CACHE{variable}`,第二个示例通过取消设置遮盖缓存变量的普通变量来避免使用它。
**方法1:**
```cmake
cmake_minimum_required(VERSION 3.27)
project(example)
set(variable "Hello" CACHE STRING "An example variable" FORCE)
set(variable "Goodbye")
message("The normal variable's value is ${variable}.")
message("The cache variable's value is $CACHE{variable}.")
方法2:
cmake_minimum_required(VERSION 3.27)
project(example)
set(variable "Hello" CACHE STRING "An example variable" FORCE)
set(variable "Goodbye")
message("The normal variable's value is ${variable}.")
unset(variable)
message("The cache variable's value is ${variable}.")
两者都产生了预期的输出:
The normal variable's value is Goodbye.
The cache variable's value is Hello.
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: ...
因此,似乎$CACHE{variable}
更能显示作者的意图,而${variable}
虽然破坏了"长期期望",但我很难看出有人会因此而感到困惑。
我在Google上找不到任何信息,我查看了最新版本(3.27)的CMake文档,但它没有提到是否应该使用它。
问题
目前,我更喜欢使用$CACHE{variable}
的简洁性和简洁性,我想知道除了破坏"长期期望"之外,是否有任何理由不应该在CMakeLists.txt
中使用$CACHE{variable}
来访问所有缓存变量?
<details>
<summary>英文:</summary>
# Problem
I am working through [Professional CMake](https://crascit.com/professional-cmake/) and section *5.5 - Potentially Surprising Behaviour of Variables* discourages accessing cache variables using `$CACHE{variable}` except when debugging. The exact quote is:
> Projects should not generally make use of this other than for temporary debugging, since it breaks the long-established expectation that normal variables will override values set in the cache.
I did not understand this reasoning so I created two examples. The first uses `$CACHE{variable}` and the second avoids it by unsetting the normal variable that is shadowing the cache variable.
**Approach 1:**
```cmake
cmake_minimum_required(VERSION 3.27)
project(example)
set(variable "Hello" CACHE STRING "An example variable" FORCE)
set(variable "Goodbye")
message("The normal variable's value is ${variable}.")
message("The cache variable's value is $CACHE{variable}.")
Approach 2:
cmake_minimum_required(VERSION 3.27)
project(example)
set(variable "Hello" CACHE STRING "An example variable" FORCE)
set(variable "Goodbye")
message("The normal variable's value is ${variable}.")
unset(variable)
message("The cache variable's value is ${variable}.")
Both produce the expected output of:
The normal variable's value is Goodbye.
The cache variable's value is Hello.
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: ...
It therefore seems that $CACHE{variable}
is better at showing the author's intention than ${variable}
and while it does break "long-established expectation", I struggle to see how someone could get confused by this.
I could not find anything on Google and I looked at the CMake documentation for the latest version (3.27) but it did not mention whether it should be used or not.
Question
At the moment, I prefer the simplicity and conciseness of $CACHE{variable}
and want to know, beyond breaking "long-established expectation", if there is any reason why I should not use $CACHE{variable}
to access all the cache variables in CMakeLists.txt
?
答案1
得分: 1
Here's the translated code:
我只是要扩展一下273K在评论中所说的,因为虽然我同意遵循手册是“如此容易”的,但我也认为理解手册为什么建议这样做是合理的(也很重要)。
假设您正在构建一个库:
...
add_library(foolib STATIC ...)
target_compile_definitions(foolib PRIVATE "${foolib_special_behavior}")
...
其中 foolib_special_behavior
是通常在缓存中设置的变量。
现在有人试图在另一个项目中将您的库用作依赖项:
...
set(foolib_special_behavior "SPECIAL")
add_subdirectory("dependencies/foolib")
...
这是将某物包含为子目录时的常见模式:在包含子目录之前,您可以设置要使用的任何配置选项。
现在,如果您使用了 target_compile_definitions(foolib PRIVATE "$CACHE{foolib_special_behavior}")
,这将不起作用 - 嵌套您的项目的项目将不得不在缓存中设置变量。
Please let me know if you need any further modifications or assistance with the code.
英文:
I'm just going to expand on what 273K said in the comments, because while I agree it's "so easy" to follow the manual, I also think it's valid (and important) to understand why the manual recommends what it does.
Assume you're building a library:
...
add_library(foolib STATIC ...)
target_compile_definitions(foolib PRIVATE "${foolib_special_behavior}")
...
Where foolib_special_behavior
is a variable that's usually set in the cache.
Now someone is trying to use your library as a dependency in another project:
...
set(foolib_special_behavior "SPECIAL")
add_subdirectory("dependencies/foolib")
...
This is a usual pattern when including something as a subdirectory: you set any configuration options you want to use before including the subdirectory.
Now if you had used target_compile_definitions(foolib PRIVATE "$CACHE{foolib_special_behavior}")
, this would not work - the project embedding you would have to set variables in the cache.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论