为何CMake中unset指令未按预期生效?技术问询
问题重现
调用CMake的Shell脚本
rm -rf build && mkdir build && cd build && cmake .. -DPULISH_VERSION=ON
CMakeLists.txt内容
cmake_minimum_required(VERSION 3.13) option(WITH_FOO "whether FOO is enabled or not" on) option(PULISH_VERSION "whether is the pulished verion or not" on) if(PULISH_VERSION) if(WITH_FOO) message("FOO should not be enabled for the published version.") unset(WITH_FOO) # It seems `WITH_FOO` does not work, what a surprise! endif() endif() if(WITH_FOO) message("Attention! FOO is enabled!") add_compile_definitions(WITH_FOO_ENABLED) endif() add_executable(demo main.c)
main.c内容
int main(){return 0;}
执行输出
cmake .. -DPULISH_VERSION=ON -- The C compiler identification is GNU 4.9.4 -- The CXX compiler identification is GNU 4.9.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 -- Detecting C compile features -- Detecting C compile features - 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 -- Detecting CXX compile features -- Detecting C compile features - done FOO should not be enabled for the published version. Attention! FOO is enabled! -- Configuring done -- Generating done -- Build files have been written to: /home/John/demo/build
问题原因
CMake的option命令会将定义的变量存入**缓存(Cache)**中,普通的unset(WITH_FOO)仅能移除当前作用域内的普通变量,无法清除缓存里的WITH_FOO值。后续的if(WITH_FOO)判断会优先读取缓存中的变量值,因此即使执行了unset,WITH_FOO依然被判定为ON,导致后续逻辑触发。
解决方法
有两种可行的修复方式:
方式一:清除缓存中的变量
将unset(WITH_FOO)替换为:
unset(WITH_FOO CACHE)
这条命令会彻底清除缓存中的WITH_FOO变量,后续的if(WITH_FOO)会因为变量未定义而判定为FALSE。
方式二:直接修改缓存值为OFF
如果需要明确将WITH_FOO设置为禁用状态,也可以直接覆盖缓存值:
set(WITH_FOO OFF CACHE BOOL "whether FOO is enabled or not" FORCE)
FORCE参数确保强制覆盖缓存中已有的值,这样后续的判断会直接使用OFF状态。
修改后的核心代码片段示例:
if(PULISH_VERSION) if(WITH_FOO) message("FOO should not be enabled for the published version.") # 二选一即可 unset(WITH_FOO CACHE) # 或者 set(WITH_FOO OFF CACHE BOOL "whether FOO is enabled or not" FORCE) endif() endif()
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

