CMake如何配置选项实现条件判断包含指定源文件
CMake条件包含源文件开关实现
问题背景
需要在CMake中实现一个可通过注释/取消注释单行配置控制的开关,根据开关状态决定是否将额外文件加入源文件集合。
参考Stack Overflow上条件包含源文件、CMake布尔变量取反的两篇相关资料后,编写了如下示例代码(注意:代码里文件名误写为CMakeFiles.txt,CMake默认识别的配置文件名为CMakeLists.txt):
project(MyApp) option(ADD_EXTRA_FILE TRUE) set(MyApp_sources main.c file1.c file2.c ) if(NOT ADD_EXTRA_FILE) set(MyApp_sources ${MyApp_sources} "extra_file.c") endif(NOT ADD_EXTRA_FILE) message(STATUS "ADD_EXTRA_FILE: ${ADD_EXTRA_FILE}") message(STATUS "MyApp_sources: ${MyApp_sources}")
预期行为
运行cmake .时预期ADD_EXTRA_FILE取值为TRUE,此时if(NOT ADD_EXTRA_FILE)判断结果为FALSE,extra_file.c不会被加入源文件集合。
实际运行结果
$ cmake . -- ADD_EXTRA_FILE: OFF -- MyApp_sources: main.c;file1.c;file2.c;extra_file.c -- Configuring done -- Generating done -- Build files have been written to: /tmp
实际运行时ADD_EXTRA_FILE被识别为OFF,if(NOT ADD_EXTRA_FILE)判断为真,extra_file.c被错误加入源文件集合。
问题原因
代码存在两个核心错误:
option()命令的默认值不符合CMake规范:CMake的option命令默认值仅认可ON/OFF两个标准布尔值,传入TRUE时无法被正确识别,会被隐式设置为OFF,这就是变量值不符合预期变成OFF的根本原因。- 判断逻辑写反:按照变量命名
ADD_EXTRA_FILE的语义,应该是变量为真时追加额外文件,但代码里加了NOT取反,导致逻辑完全颠倒。
正确实现方式
CMake完全支持条件包含源文件的需求,按以下规则修正即可:
option或set设置布尔开关时,统一使用ON/OFF作为取值,不要用TRUE/FALSE避免隐式转换问题- 修正判断逻辑,去掉多余的
NOT - 追加列表元素推荐使用CMake原生的
list(APPEND)命令,比重新set整个列表更规范 - 如果需要纯靠修改文件单行控制开关、不被命令行-D参数覆盖缓存,可以直接用普通
set定义变量,改取值或者注释/取消注释对应行即可快速切换
修正后的完整可用代码:
project(MyApp) # 开关配置:要关闭就把ON改成OFF,不需要额外改其他代码 # 想要单行注释切换的话,也可以写成 set(ADD_EXTRA_FILE ON),注释掉这行就默认不开启 option(ADD_EXTRA_FILE ON "Whether to include extra_file.c in build sources") set(MyApp_sources main.c file1.c file2.c ) # 开关开启时才追加额外源文件 if(ADD_EXTRA_FILE) list(APPEND MyApp_sources extra_file.c) endif() message(STATUS "ADD_EXTRA_FILE: ${ADD_EXTRA_FILE}") message(STATUS "MyApp_sources: ${MyApp_sources}") # 后面正常添加编译目标即可 # add_executable(MyApp ${MyApp_sources})
修正后运行效果符合预期:ADD_EXTRA_FILE为ON时源文件列表包含extra_file.c,为OFF时不包含,修改开关行的取值或者注释状态即可一键切换。
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

