Keil MDK 5.37+ 手动安装 ARM Compiler 5 解决 STM32 编译报错指南
2026/9/24 13:20:30 网站建设 项目流程

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 5(AC5)。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 之后移除 AC5

2.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--apcs=interwork这些选项,在 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 960

AC5 有多个版本,从 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.exearmlink.exearmasm.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(或者按Alt+F7),进入Target标签页。在ARM Compiler下拉框里,现在应该能看到Use default compiler version 5或者直接显示ARM Compiler 5.06 update 7的选项。选中它。

然后切到C/C++标签页,检查一下Misc Controls里的编译选项。AC5 和 AC6 的选项写法不一样,如果你之前手动改过,要改回 AC5 的写法。比如:

  • AC5 用--c99,AC6 用-std=c99
  • AC5 用--gnu,AC6 用-std=gnu11
  • AC5 的--apcs=interwork在 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 路径的处理方式略有不同,尤其是相对路径的解析。

排查步骤:

  1. 打开Options for Target -> C/C++,看Include Paths里的路径列表。
  2. 确认每个路径都指向实际存在的文件夹。CubeMX 生成的工程,头文件路径通常包括Core/IncDrivers/STM32F4xx_HAL_Driver/IncDrivers/CMSIS/Device/ST/STM32F4xx/IncludeDrivers/CMSIS/Include这几个。
  3. 如果路径里有中文或者空格,尽量改成纯英文无空格路径。AC5 对中文路径的支持比 AC6 差。
  4. 检查路径分隔符,Windows 下用反斜杠\或者正斜杠/都行,但不要混用。

还有一个常见情况是——CubeMX 重新生成代码后,路径变了。比如你换了 CubeMX 版本,或者改了工程位置,include 路径可能没自动更新。这时候手动把路径补上就行。

5.2 汇编启动文件报错的根因

AC5 和 AC6 对汇编文件的处理差异很大。CubeMX 生成的启动文件(startup_stm32f4xxxx.s)通常是按 AC5 的语法写的,用的是AREAEXPORTIMPORT这些 ARM 汇编伪指令。

如果你之前切到 AC6 编译过,AC6 可能会报一堆汇编语法错误。切回 AC5 后,这些错误通常会自动消失。但如果还有报错,检查两点:

第一,启动文件有没有被误改。CubeMX 生成的启动文件不要手动改,如果改过,从 CubeMX 重新生成一份。

第二,Options for Target -> Asm标签页里的汇编器选项。AC5 用的是armasm,AC6 用的是armclang的集成汇编器。确认这里选的是 AC5 对应的汇编器。

5.3 链接脚本(scatter file)的兼容问题

链接脚本是另一个容易出问题的地方。AC5 和 AC6 的 scatter file 语法有差异,尤其是LR_IROM1ER_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 是 1MB,RAM 是 192KB,scatter 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:

  • 工程基于标准外设库(SPL):SPL 是 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\ARMCC,AC6 通常在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 的选项,比如-std=gnu11-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 版本不匹配,可能会把工程的编译器设置重置回默认值。比如你明明配好了 AC5,CubeMX 一生成,又变回 AC6 了。

应对方法:CubeMX 生成代码后,先检查Options for Target -> Target里的编译器选项,确认还是 AC5。如果不是,手动切回来。另外,CubeMX 的Project Manager -> Toolchain/IDE里,可以选MDK-ARM并指定编译器版本,新版 CubeMX 支持这个设置,能减少重置的情况。

8. 一套可复用的检查清单

为了让你下次遇到类似问题时能快速定位,我把整个流程整理成一个检查清单。装 AC5 或者排查编译问题时,按这个顺序过一遍:

检查项正常状态异常处理
Keil 版本5.37 及以上确认是否需要 AC5
AC5 安装路径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 就行。这个方式虽然看起来"笨",但胜在稳定,不会因为环境问题耽误进度。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询