2026/9/24 13:20:35

Keil MDK 5.37+ 手动安装 ARM Compiler 5 解决 STM32 编译报错指南

Keil MDK 5.37+ 手动安装 ARM Compiler 5 解决 STM32 编译报错指南 1. 从一次真实的编译报错说起如果你最近把 Keil MDK 升级到了 5.37 或更高的版本然后打开一个用 STM32 CubeMX 生成的老工程点击编译大概率会撞上这么一条报错*** Error: Cannot find ARM Compiler ARMCC version 5或者更直接一点The configured compiler ARMCC is not available.这时候你可能会愣一下——工程昨天还好好的怎么升了个 Keil 就不认了打开Project - Manage - Project Items一看编译器选项里那个熟悉的ARM Compiler 5不见了只剩下ARM Compiler 6也就是 AC6基于 Clang 的那套。这不是你的工程坏了也不是 CubeMX 生成代码有问题而是Keil MDK 从 5.37 版本开始官方安装包里不再默认捆绑 ARM Compiler 5AC5。AC5 就是那个基于 ARMCC 的老编译器也就是我们常说的ARM Compiler 5.06 update 7 (build 960)这个版本。而 STM32 CubeMX 在很长一段时间里默认生成的工程模板、启动文件、以及各种中间件尤其是老版本的 HAL 库和标准外设库都是按 AC5 的语法和链接脚本配置的。一旦编译器缺失整个工程就编不过。这篇文章就是写给正在被这个问题卡住的嵌入式开发者。不管你是刚接触 STM32 的新手还是维护着一堆历史工程的老手只要你的 Keil 版本在 5.37 以上又需要编译 AC5 的工程这篇内容都能帮你把编译器手动装回去并且把背后的逻辑讲清楚。我会从为什么 Keil 要移除 AC5讲到怎么一步步手动安装再到装完之后还有哪些坑要填全程按我实际操作的顺序来写你可以直接照着做。2. Keil 为什么要在 5.37 之后移除 AC52.1 AC5 和 AC6 到底差在哪要理解这个变动得先搞清楚 AC5 和 AC6 的本质区别。AC5 的核心是 ARMCC它是 ARM 公司早期基于 Edison Design Group 前端技术做的编译器语法上对 C90 和部分 C99 支持得很好对 GNU 扩展也比较宽容。很多老工程里那些__align、__packed、#pragma arm之类的写法都是 AC5 时代的产物。AC6 则是基于 LLVM/Clang 架构重新做的前端是 Clang后端是 LLVM。它在 C 标准支持上更现代C11、C17 都没问题优化能力也更强尤其是 LTO链接时优化和 size 优化做得比 AC5 好不少。但代价是——AC6 对 AC5 的私有语法和编译选项兼容性有限。比如 AC5 里的--c99、--gnu、--apcsinterwork这些选项在 AC6 里要么改名了要么直接不支持。链接脚本、scatter file 的写法也有差异。所以对于 STM32 CubeMX 生成的老工程来说直接切到 AC6 往往会引发一连串新的报错汇编启动文件不认、链接脚本语法不对、某些库函数找不到。与其让用户去改工程不如把 AC5 装回来这是最省事的路径。2.2 官方移除 AC5 的时间线和原因ARM 官方对 AC5 的退役其实早有预告。AC5 的最后一个版本就是5.06 update 7 (build 960)发布于 2021 年左右之后就不再更新了。Keil MDK 从 5.37 开始安装包里不再包含 AC5 组件到了 5.38、5.39 以及后来的 MDK 5.41这个趋势一直延续。官方给出的理由主要有几点一是 AC5 已经停止维护继续捆绑会增加安装包体积和维护成本二是鼓励用户迁移到 AC6享受更好的优化和标准支持三是 AC5 的授权模式和新版 MDK 的授权体系需要做区分处理。但对实际开发者来说问题在于——大量存量工程还在用 AC5。尤其是那些基于 STM32F1、F4 系列的老项目CubeMX 生成的模板默认就是 AC5 配置。你不可能为了升级 Keil 就把所有工程重写一遍。所以手动安装 AC5 就成了一个刚需操作。2.3 手动安装 AC5 的合法性说明这里要澄清一个很多人关心的问题手动安装 AC5 需不需要额外的许可证答案是——取决于你的 Keil MDK 授权类型。如果你用的是 MDK-Professional 或者 MDK-Essential 的正版授权AC5 作为 MDK 的一个组件在授权有效期内是可以正常使用的。安装 AC5 本身不额外收费它只是从安装包里被拆出来了需要你单独下载安装。如果你用的是 MDK-Lite 版本也就是免费评估版那 AC5 同样受 32KB 代码限制这个限制和编译器版本无关是 MDK-Lite 本身的限制。提示安装 AC5 之前先确认你的 Keil 授权状态。打开File - License Management看看当前的授权类型和到期时间。如果是正版授权装完 AC5 后不需要重新激活直接就能用。3. 找到正确的 AC5 安装包3.1 版本号必须对得上5.06u7 build 960AC5 有多个版本从 5.06 到 5.06 update 7中间有好几个 build。你必须装5.06 update 7 (build 960)这个版本原因有两个第一这是 AC5 的最后一个版本bug 修复最全对新型号 STM32 的支持也最好。早期版本在编译 STM32F4、F7 的一些新外设驱动时可能会出问题。第二Keil MDK 5.37 之后的工程配置里如果指定了编译器版本通常认的就是 build 960。你装个老版本Keil 可能识别不到或者识别到了但报版本不匹配。怎么确认你需要的版本打开你的工程看Options for Target - Target标签页在ARM Compiler下拉框旁边有个版本号。如果是灰色的或者显示Missing那就说明当前没装。你可以看看工程文件.uvprojx里写的编译器版本用文本编辑器打开搜索ArmCC或者Compiler能看到类似5.06u7的字样。3.2 从哪里获取安装包AC5 的安装包现在不在 Keil 主安装程序里了需要单独下载。获取途径主要有两个途径一Keil 官方下载页面。在 Keil 官网的 MDK 下载区域往下翻能找到 ARM Compiler 5 的独立下载链接。文件名通常类似ARM_Compiler_5.06u7_960.exe或者.zip格式。这个是最正规的来源推荐优先用这个。途径二从旧版 MDK 安装目录里提取。如果你手头有旧版 Keil比如 5.36 或更早的安装包或者电脑上还留着旧版安装目录AC5 的编译器文件其实就在Keil_v5\ARM\ARMCC\这个文件夹里。你可以直接把这个文件夹拷贝出来放到新版 Keil 的对应位置。这个方法适合你已经有旧版环境的情况省去下载步骤。注意不管用哪种途径装之前先确认安装包完整性。AC5 的安装包大概 100MB 左右如果下载下来只有几 MB那肯定是坏的。另外安装包不要放在中文路径下Keil 的安装程序对中文路径支持不好容易中途报错。3.3 安装前的环境检查在动手装之前花两分钟做几个检查能避免后面很多麻烦确认 Keil 安装路径默认是C:\Keil_v5如果你改过记下来。AC5 要装到这个目录下的ARM子文件夹里。关闭 Keil 和所有相关进程包括 Keil uVision、STM32CubeMX、以及可能占用编译器文件的杀毒软件。装的时候如果文件被占用会安装失败。确认磁盘空间AC5 装完大概占 500MB 到 1GB确保目标盘有足够空间。备份当前工程配置虽然安装 AC5 不会动你的工程但保险起见把.uvprojx文件复制一份。万一装完编译器选项乱了还能对照恢复。4. 手动安装 AC5 的完整步骤4.1 运行安装程序并指定路径双击下载好的 AC5 安装包会弹出一个安装向导。前面几步都是常规的下一步关键是安装路径这一步。安装程序默认可能会建议装到C:\Program Files\ARM\之类的路径不要用这个默认路径。你要手动改成 Keil 的安装目录下的ARM文件夹。比如你的 Keil 装在C:\Keil_v5那路径就设成C:\Keil_v5\ARM\ARMCC或者有些安装包会让你选到C:\Keil_v5\ARM然后它自动在里面建ARMCC文件夹。具体看安装程序的提示核心原则是——最终 AC5 的编译器文件要落在Keil安装目录\ARM\ARMCC\bin\下面。装完之后你可以去验证一下打开这个路径C:\Keil_v5\ARM\ARMCC\bin\里面应该能看到armcc.exe、armlink.exe、armasm.exe这几个关键文件。看到它们说明编译器本体装好了。4.2 在 Keil 里注册编译器路径光把文件放进去还不够Keil 需要知道去哪里找这个编译器。这一步很多人会漏掉导致装完了 Keil 还是报找不到编译器。打开 Keil uVision进入Project - Manage - Project Items或者直接点工具栏上的Manage Project Items图标。在弹出的窗口里选Folders/Extensions标签页。在这个页面里找到ARM Compiler相关的设置项。你会看到一个Use ARM Compiler的下拉框以及一个Custom或者Add按钮。点击添加把路径指向你刚才安装的ARMCC文件夹。具体操作是在ARM Compiler区域有一个Add按钮点它然后浏览到C:\Keil_v5\ARM\ARMCC选中这个文件夹确认。这时候 Keil 应该能识别到ARMCC编译器版本号会显示5.06 update 7 (build 960)。提示如果你在Folders/Extensions里找不到添加编译器的入口可能是因为 Keil 版本差异。在 MDK 5.37 里这个入口通常在Project - Manage - Project Items - Folders/Extensions下的ARM Compiler部分。如果实在找不到可以尝试直接编辑 Keil 的配置文件但更推荐用界面操作避免改错。4.3 在工程里切换回 AC5编译器注册好了接下来要让你的工程用上它。打开你的 STM32 CubeMX 工程点Options for Target或者按AltF7进入Target标签页。在ARM Compiler下拉框里现在应该能看到Use default compiler version 5或者直接显示ARM Compiler 5.06 update 7的选项。选中它。然后切到C/C标签页检查一下Misc Controls里的编译选项。AC5 和 AC6 的选项写法不一样如果你之前手动改过要改回 AC5 的写法。比如AC5 用--c99AC6 用-stdc99AC5 用--gnuAC6 用-stdgnu11AC5 的--apcsinterwork在 AC6 里没有直接对应对于 CubeMX 生成的工程通常Misc Controls里不需要额外加什么保持默认就行。如果你看到里面有 AC6 特有的选项删掉。4.4 验证编译是否通过配置改完点Rebuild重新编译全部看看能不能过。如果一切顺利编译输出窗口会显示类似Build started: Project: YourProject *** Using Compiler V5.06 update 7 (build 960), folder: C:\Keil_v5\ARM\ARMCC\Bin Build target YourTarget compiling main.c... ... .\YourProject.axf - 0 Error(s), 0 Warning(s).看到0 Error(s)说明 AC5 已经正常工作工程编译通过了。如果还有报错先别慌往下看第 5 节我把常见的坑都列出来了。5. 装完之后最容易踩的几个坑5.1 编译报错 cannot open source input file 的排查装完 AC5 后有时候会冒出一些新的报错比如error: #5: cannot open source input file stm32f4xx.h: No such file or directory这种报错通常不是编译器本身的问题而是头文件搜索路径没配对。AC5 和 AC6 对 include 路径的处理方式略有不同尤其是相对路径的解析。排查步骤打开Options for Target - C/C看Include Paths里的路径列表。确认每个路径都指向实际存在的文件夹。CubeMX 生成的工程头文件路径通常包括Core/Inc、Drivers/STM32F4xx_HAL_Driver/Inc、Drivers/CMSIS/Device/ST/STM32F4xx/Include、Drivers/CMSIS/Include这几个。如果路径里有中文或者空格尽量改成纯英文无空格路径。AC5 对中文路径的支持比 AC6 差。检查路径分隔符Windows 下用反斜杠\或者正斜杠/都行但不要混用。还有一个常见情况是——CubeMX 重新生成代码后路径变了。比如你换了 CubeMX 版本或者改了工程位置include 路径可能没自动更新。这时候手动把路径补上就行。5.2 汇编启动文件报错的根因AC5 和 AC6 对汇编文件的处理差异很大。CubeMX 生成的启动文件startup_stm32f4xxxx.s通常是按 AC5 的语法写的用的是AREA、EXPORT、IMPORT这些 ARM 汇编伪指令。如果你之前切到 AC6 编译过AC6 可能会报一堆汇编语法错误。切回 AC5 后这些错误通常会自动消失。但如果还有报错检查两点第一启动文件有没有被误改。CubeMX 生成的启动文件不要手动改如果改过从 CubeMX 重新生成一份。第二Options for Target - Asm标签页里的汇编器选项。AC5 用的是armasmAC6 用的是armclang的集成汇编器。确认这里选的是 AC5 对应的汇编器。5.3 链接脚本scatter file的兼容问题链接脚本是另一个容易出问题的地方。AC5 和 AC6 的 scatter file 语法有差异尤其是LR_IROM1、ER_IROM1这些区域的写法。CubeMX 生成的工程scatter file 通常在MDK-ARM文件夹下文件名类似YourProject.sct。这个文件是按 AC5 语法生成的。切回 AC5 后链接脚本应该能正常工作。如果链接报错比如Error: L6218E: Undefined symbol ...或者Error: L6406E: No space in execution regions ...先检查 scatter file 里的内存区域定义是否和你的芯片匹配。比如 STM32F407 的 Flash 是 1MBRAM 是 192KBscatter file 里要对应写对。如果芯片型号选错了链接就会出问题。5.4 优化等级和调试信息的取舍AC5 的优化等级和 AC6 不完全一样。AC5 有-O0、-O1、-O2、-O3、-Os这几档AC6 多了-Oz极致 size 优化和-Ofast。对于调试阶段建议用-O0这样变量不会被优化掉单步调试时能看到所有局部变量。发布版本可以用-Os或者-O2平衡性能和体积。在Options for Target - C/C里Optimization下拉框选对应的等级。注意AC5 的-O0在有些版本里叫Level 0 (-O0)选的时候看清楚。提示如果你在调试时发现某些变量看不见或者值不对八成是优化等级太高编译器把变量优化到寄存器里了。临时切到-O0重新编译问题通常就解决了。6. 关于 AC5 和 AC6 的选型建议6.1 什么情况下必须用 AC5不是所有工程都需要 AC5。以下几种情况建议老老实实用 AC5工程基于标准外设库SPLSPL 是 ST 早期的库很多写法只兼容 AC5。虽然理论上能移植到 AC6但改动量大不值得。工程里有大量 AC5 私有语法比如__align(4)、__packed、#pragma anon_unions这些AC6 要么不支持要么写法不同。工程依赖的第三方库只提供了 AC5 的.lib文件这种情况最麻烦因为.lib是编译好的二进制没法重新编译。只能用 AC5 链接。团队统一用 AC5不想引入额外变量如果团队里其他人都在用 AC5你一个人切 AC6可能会引入不必要的协作成本。6.2 什么时候可以考虑迁移到 AC6反过来以下几种情况可以考虑逐步迁移到 AC6新项目从零开始新项目没有历史包袱直接用 AC6享受更好的优化和标准支持。工程已经用 HAL 库且 CubeMX 版本较新新版 CubeMX 生成的工程对 AC6 的支持已经比较好了迁移成本相对低。对代码体积或性能有极致要求AC6 的 LTO 和 size 优化确实比 AC5 强尤其是-Oz选项能显著减小固件体积。需要用 C11 或更高标准的新特性AC5 对 C11 支持有限AC6 则完整支持。迁移的时候建议先在分支上做不要直接改主工程。迁移步骤大致是切换编译器到 AC6然后逐个解决报错主要是汇编文件、链接脚本、以及私有语法这几块。CubeMX 重新生成代码时可以选择 AC6 模板能省不少事。6.3 两个编译器共存的管理方式最省心的做法其实是——让 AC5 和 AC6 共存。Keil 支持同时安装多个编译器版本你在工程里按需切换就行。共存的管理要点AC5 装在Keil_v5\ARM\ARMCCAC6 通常在Keil_v5\ARM\ARMCLANG两者互不干扰。在Project - Manage - Project Items - Folders/Extensions里两个编译器都能注册进去。每个工程在Options for Target - Target里独立选择编译器版本互不影响。团队协作时在工程文档里注明每个工程用的编译器版本避免有人切错了导致编译失败。这样你维护老工程时用 AC5开新工程时用 AC6两不耽误。7. 我实际踩过的几个坑和应对经验7.1 安装路径带空格导致的诡异报错我第一次装 AC5 的时候图省事装到了C:\Program Files\Keil_v5\ARM\ARMCC结果 Keil 死活识别不到编译器。后来发现是路径里的空格在作怪——Keil 在解析编译器路径时对空格的处理有问题。解决办法很简单Keil 安装路径不要带空格。默认的C:\Keil_v5就很好别改成C:\Program Files\Keil。如果你已经装了带空格的路径要么重装 Keil要么把 AC5 装到一个无空格路径下然后在 Keil 里手动指向那个路径。7.2 杀毒软件拦截编译器文件有一次装完 AC5编译时armcc.exe直接被 Windows Defender 隔离了报错说找不到编译器。查了半天才发现是杀毒软件误判。应对方法装 AC5 之前先把 Keil 安装目录加到杀毒软件的排除列表里。装完之后再检查一下ARMCC\bin下的几个 exe 文件是否还在。如果被隔离了从隔离区恢复并加白名单。7.3 工程从 AC6 切回 AC5 后的选项残留这个坑比较隐蔽。如果你之前把工程切到 AC6 编译过Options for Target - C/C里的Misc Controls可能会残留 AC6 的选项比如-stdgnu11、-Wno-...之类的。切回 AC5 后这些选项 AC5 不认识会报unknown option。解决办法切回 AC5 后把Misc Controls清空只保留必要的选项。CubeMX 生成的工程通常不需要额外加选项清空就行。如果确实需要加用 AC5 的语法写。7.4 多版本 Keil 共存时的路径冲突有些开发者电脑上装了多个版本的 Keil比如 5.36 和 5.41 各装一个。这时候 AC5 装到哪个目录下要特别注意。原则是AC5 装到你当前主要使用的那个 Keil 版本目录下。如果你两个版本都要用 AC5那就在两个目录下各装一份或者装一份然后在另一个 Keil 里手动指向同一个路径。但要注意不同 Keil 版本对 AC5 的注册方式可能略有差异。如果在一个版本里注册好了另一个版本里识别不到就在另一个版本里重新注册一次路径。7.5 CubeMX 重新生成代码后的编译器重置用 CubeMX 重新生成代码时如果 CubeMX 版本和 Keil 版本不匹配可能会把工程的编译器设置重置回默认值。比如你明明配好了 AC5CubeMX 一生成又变回 AC6 了。应对方法CubeMX 生成代码后先检查Options for Target - Target里的编译器选项确认还是 AC5。如果不是手动切回来。另外CubeMX 的Project Manager - Toolchain/IDE里可以选MDK-ARM并指定编译器版本新版 CubeMX 支持这个设置能减少重置的情况。8. 一套可复用的检查清单为了让你下次遇到类似问题时能快速定位我把整个流程整理成一个检查清单。装 AC5 或者排查编译问题时按这个顺序过一遍检查项正常状态异常处理Keil 版本5.37 及以上确认是否需要 AC5AC5 安装路径Keil_v5\ARM\ARMCC\bin\下有 armcc.exe重新安装到正确路径Keil 编译器注册Folders/Extensions 里能看到 AC5手动添加路径工程编译器选择Target 标签页选 AC5下拉框切换Include 路径指向实际存在的文件夹补全或修正路径汇编器选项选 AC5 对应的 armasm切换汇编器Scatter file与芯片型号匹配从 CubeMX 重新生成Misc Controls无 AC6 残留选项清空或改 AC5 语法杀毒软件Keil 目录已加白名单恢复被隔离文件优化等级调试用 -O0发布用 -Os按需调整这张表建议存下来下次再遇到找不到编译器或者编译报错对着过一遍大部分问题都能解决。9. 关于授权和后续升级的几点提醒最后聊几个和授权、升级相关的事这些是我在实际使用中积累的经验官方文档里不一定写。第一AC5 的授权是跟着 MDK 授权走的。你不需要为 AC5 单独买 license。只要你的 MDK 授权有效AC5 就能用。但要注意如果你的 MDK 授权到期了没续AC5 也会跟着失效。所以续授权的时候别忘了确认 AC5 还能不能用。第二Keil 后续版本可能进一步收紧 AC5 的支持。虽然目前 5.37 到 5.41 都还能手动装 AC5但未来版本会不会彻底移除相关接口不好说。如果你有大量 AC5 工程建议保留一个稳定的 Keil 版本比如 5.36 或 5.37作为老工程专用环境不要盲目追新。第三迁移到 AC6 是大趋势但不用急。对于还在维护的老工程继续用 AC5 完全没问题没必要为了技术先进强行迁移。等工程有大的重构需求时再考虑一并迁移到 AC6这样成本更可控。第四团队协作时统一环境很重要。如果团队里有人用 AC5有人用 AC6工程文件传来传去很容易出问题。建议在团队内约定好老工程统一用 AC5新工程统一用 AC6并且在工程根目录放一个说明文件写清楚编译器版本和 Keil 版本要求。我在实际项目里就是这么做的——维护着一个 5.36 的环境专门编译老工程同时用 5.41 开新项目。两套环境互不干扰切换的时候只要打开对应的 Keil 就行。这个方式虽然看起来笨但胜在稳定不会因为环境问题耽误进度。