cmake中批量处理源文件需用foreach配合列表操作,包括:①用in lists遍历预定义变量;②用file(glob_recurse)动态收集并过滤文件;③用in_list判断为特定文件设编译属性;④用range生成编号目标。

要在CMake中批量处理源文件,比如自动添加所有.cpp文件、为不同模块设置编译选项或过滤掉测试代码,必须用foreach配合列表操作,硬编码每个文件名会迅速让CMakeLists.txt失控。
基础遍历:用IN LISTS处理已定义的源文件列表
第一步:用set定义一个带分号或空格分隔的源文件列表,例如set(SOURCES main.cpp utils.cpp network.cpp)。CMake内部把空格和分号都视为分隔符,所以两种写法等效。
第二步:用foreach(src IN LISTS SOURCES)开始循环,【SOURCES必须是已定义的变量名,不能写成${SOURCES}】。CMake会自动展开该变量内容,逐个赋值给循环变量src。
第三步:在循环体内执行命令,比如打印每个文件:message(STATUS "Processing: ${src}")。注意src只在本次迭代中有效,循环结束后就不可访问。
这一步操作起来很简单,直接把文件拖进去就行。
动态收集:结合file(GLOB_RECURSE)自动扫描目录
方法一:用file(GLOB_RECURSE SRC_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp")递归抓取所有.cpp文件。它生成的是一个真实列表,不是字符串,可直接用于IN LISTS。
方法二:若需排除某些文件(如test_开头的),在foreach内加判断:if(src MATCHES "test_.*\.cpp$") list(REMOVE_ITEM SRC_FILES ${src}) endif()。注意list(REMOVE_ITEM)会原地修改列表,后续遍历将跳过被删项。
CMake 4.3.2 Windows x86_64 历史版本安装包,适合旧项目兼容、构建环境回退、CMakeLists.txt 迁移验证、Visual Studio/Ninja/Makefile 生成器测试和 C/C++ 项目维护。
【file(GLOB)结果不会自动响应文件增删——改了源码目录后必须手动触发cmake --build . --clean-first,否则缓存旧列表】
按条件设置编译属性:为特定源文件启用优化或警告
第一步:先定义要特殊处理的文件子集,例如set(OPTIMIZED_SOURCES "renderer.cpp;physics.cpp")。
第二步:遍历全部源文件列表,对命中子集的文件调用set_source_files_properties:foreach(src IN LISTS ALL_SOURCES)<br>
if(src IN_LIST OPTIMIZED_SOURCES)<br>
set_source_files_properties(${src} PROPERTIES COMPILE_OPTIONS "-O3;-Wall")<br>
endif()<br>endforeach()
这一步的关键在于IN_LIST是CMake 3.12+才支持的条件判断语法,低于该版本需改用list(FIND ...)配合NOT EQUAL -1判断。
数值范围循环:生成多个同构目标或配置编号
① 从0到4生成5个测试可执行文件:foreach(i RANGE 4) add_executable(test_${i} test_${i}.cpp) endforeach()。
② 指定步长跳着生成,比如只做偶数编号:foreach(i RANGE 0 8 2) add_executable(module_${i} mod_${i}.cpp) endforeach()。注意RANGE是闭区间,RANGE 0 8 2产生0、2、4、6、8共5个值。
③ 倒序生成(CMake 3.20+):foreach(i RANGE 5 0 -1) message("${i}") endforeach()。低于3.20版本无法用负步长,得改用while循环。










