news 2026/4/16 9:57:49

CMake基础:foreach详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CMake基础:foreach详解

目录

1.简介

2.使用场景

2.1.批量添加源文件到目标

2.2.遍历目录下的所有指定文件

2.3.批量链接第三方库

3.循环控制(CMake 3.20+ 支持)

4.同时循环多个列表

5.注意事项


1.简介

CMake 的foreach是遍历列表 / 集合的核心指令,支持传统遍历现代关键字遍历两种语法,常用于批量处理源文件、库依赖、编译选项等场景。

语法:

foreach(<循环变量> IN [LISTS <列表名>] [ITEMS <元素>] [RANGE <起始> <结束>]) # 循环体 endforeach()
  • LISTS:遍历已定义的 CMake 列表变量
  • ITEMS:遍历直接给出的元素
  • RANGE:遍历数值范围(如RANGE 1 5对应 1-5)

2.使用场景

2.1.批量添加源文件到目标

适用于项目源文件较多的情况,避免重复写add_executable的参数。

cmake_minimum_required(VERSION 3.15) project(ForeachDemo LANGUAGES CXX) # 定义源文件列表 set(SOURCE_FILES main.cpp utils.cpp network.cpp ) # 遍历源文件列表,打印并收集(这里直接用列表也能加,遍历主要用于额外操作) foreach(src IN LISTS SOURCE_FILES) message(STATUS "添加源文件: ${src}") endforeach() # 添加可执行文件 add_executable(${PROJECT_NAME} ${SOURCE_FILES}) # Windows + VS2019 环境配置 if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX) endif()

2.2.遍历目录下的所有指定文件

结合file(GLOB)收集目录中的.cpp文件,适合动态管理源文件。

cmake_minimum_required(VERSION 3.15) project(ForeachFileDemo LANGUAGES CXX) # 收集 src 目录下的所有 .cpp 文件(GLOB 会自动生成列表) file(GLOB_RECURSE SRC_FILES ${CMAKE_SOURCE_DIR}/src/*.cpp) # 遍历文件列表,过滤掉不需要的文件(比如 test_xxx.cpp) foreach(file IN LISTS SRC_FILES) # 检查文件名是否包含 test_ if(file MATCHES "test_.*\\.cpp$") message(STATUS "过滤测试文件: ${file}") list(REMOVE_ITEM SRC_FILES ${file}) # 从列表中移除 endif() endforeach() add_executable(${PROJECT_NAME} ${SRC_FILES})

注意:file(GLOB)不推荐用于频繁增减文件的场景,若文件变动需手动执行cmake --build . --clean-first重新生成。

2.3.批量链接第三方库

适用于项目依赖多个库的情况,简化target_link_libraries的写法。

cmake_minimum_required(VERSION 3.15) project(ForeachLibDemo LANGUAGES CXX) add_executable(${PROJECT_NAME} main.cpp) # 定义依赖库列表(假设已通过 find_package 找到这些库) set(DEPEND_LIBS Qt5::Core Qt5::Sql Boost::asio ) # 遍历库列表,批量链接 foreach(lib IN LISTS DEPEND_LIBS) target_link_libraries(${PROJECT_NAME} PRIVATE ${lib}) message(STATUS "链接库: ${lib}") endforeach()

3.循环控制(CMake 3.20+ 支持)

CMake 3.20 及以上版本支持continue()(跳过当前循环)和break()(终止循环),示例如下:

foreach(num RANGE 1 10) if(num LESS 3) continue() # 跳过 1、2 endif() if(num GREATER 7) break() # 终止于 8 endif() message(STATUS "当前数值: ${num}") endforeach()

4.同时循环多个列表

CMake 的foreach本身不支持直接并行遍历多个列表,需借助索引循环 + 列表取值实现,核心思路是通过列表长度确定循环次数,再用list(GET)获取对应索引的元素。

示例:同时遍历源文件列表对应的编译选项列表,为不同源文件设置专属编译参数

cmake_minimum_required(VERSION 3.15) project(MultiListForeach LANGUAGES CXX) # 定义两个长度相同的列表 set(SOURCE_FILES main.cpp utils.cpp network.cpp) set(COMPILE_FLAGS "-O2" "-g -Wall" "-O3 -march=native") # 获取列表长度(需确保所有列表长度一致) list(LENGTH SOURCE_FILES FILE_COUNT) if(NOT FILE_COUNT EQUAL ${CMAKE_ARGV2}) message(FATAL_ERROR "列表长度不一致,无法并行遍历!") endif() # 索引循环,遍历多个列表 math(EXPR MAX_INDEX "${FILE_COUNT} - 1") foreach(IDX RANGE 0 ${MAX_INDEX}) # 获取对应索引的元素 list(GET SOURCE_FILES ${IDX} CURRENT_FILE) list(GET COMPILE_FLAGS ${IDX} CURRENT_FLAG) # 打印信息 + 应用编译选项 message(STATUS "为 ${CURRENT_FILE} 设置编译选项: ${CURRENT_FLAG}") set_source_files_properties(${CURRENT_FILE} PROPERTIES COMPILE_FLAGS ${CURRENT_FLAG}) endforeach() add_executable(${PROJECT_NAME} ${SOURCE_FILES}) # Windows VS2019 环境适配 if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4) endif()

5.注意事项

1.循环变量的作用域:foreach内定义的变量默认是全局的,若需局部作用域,可在循环内用set(<var> <value> PARENT_SCOPE)控制。

2.跨平台路径处理:遍历文件路径时,建议用CMAKE_SOURCE_DIR/CMAKE_CURRENT_SOURCE_DIR等变量,避免硬编码 Windows 路径分隔符。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 18:07:40

TouchGAL:构建Galgame爱好者的专属交流空间

TouchGAL&#xff1a;构建Galgame爱好者的专属交流空间 【免费下载链接】kun-touchgal-next TouchGAL是立足于分享快乐的一站式Galgame文化社区, 为Gal爱好者提供一片净土! 项目地址: https://gitcode.com/gh_mirrors/ku/kun-touchgal-next 在数字娱乐多元发展的今天&am…

作者头像 李华
网站建设 2026/4/12 16:41:43

智能文档扫描仪保姆级教程:基于OpenCV的透视变换算法详解

智能文档扫描仪保姆级教程&#xff1a;基于OpenCV的透视变换算法详解 1. 引言 1.1 学习目标 本文将带你从零开始&#xff0c;完整实现一个基于 OpenCV 的智能文档扫描系统&#xff0c;具备自动边缘检测、透视矫正和图像增强功能。通过本教程&#xff0c;你将掌握&#xff1a…

作者头像 李华
网站建设 2026/4/16 21:22:16

APK安装器:Windows平台安卓应用运行的全新体验

APK安装器&#xff1a;Windows平台安卓应用运行的全新体验 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 还在为安卓应用在电脑上运行困难而烦恼吗&#xff1f;APK安装…

作者头像 李华
网站建设 2026/4/13 17:27:24

终极指南:libdxfrw让你的CAD文件处理飞起来

终极指南&#xff1a;libdxfrw让你的CAD文件处理飞起来 【免费下载链接】libdxfrw C library to read and write DXF/DWG files 项目地址: https://gitcode.com/gh_mirrors/li/libdxfrw libdxfrw是一个强大的C库&#xff0c;专门用于读取和写入DXF/DWG文件格式&#xff…

作者头像 李华
网站建设 2026/4/14 20:17:46

手机如何成为多平台兼容的移动系统容器?

手机如何成为多平台兼容的移动系统容器&#xff1f; 【免费下载链接】Vectras-VM-Android Its a Virtual Machine App for Android Which is Based on QEMU 项目地址: https://gitcode.com/gh_mirrors/ve/Vectras-VM-Android 在移动办公成为主流的今天&#xff0c;你是否…

作者头像 李华
网站建设 2026/4/17 2:39:48

如何通过Bili.Uwp在Windows 11上实现高效追番体验

如何通过Bili.Uwp在Windows 11上实现高效追番体验 【免费下载链接】Bili.Uwp 适用于新系统UI的哔哩 项目地址: https://gitcode.com/GitHub_Trending/bi/Bili.Uwp 还在为网页版B站卡顿、广告多而烦恼吗&#xff1f;作为Windows 11用户&#xff0c;你是否期待一款能够完美…

作者头像 李华