做嵌入式开发,用 Keil5 编译时最头疼的报错之一,就是工程里明明写着ARM Compiler Version 5,可本机却找不到这个编译器。我最早是在一台新配的电脑上打开维护了两年的 STM32 老工程时撞上的,屏幕上直接甩出一行红色提示:Target uses ARM-Compiler 'Arm Compiler 5' in '..\Keil_v5\ARM\ARMCC\bin' which is not available。那时候第一反应是工程路径坏了,折腾半天才发现,问题根本不在源码,而是新版 Keil MDK 默认没有把 Arm Compiler 5 安装进去。这篇文章就把我实际踩过的坑整理出来,完整讲讲 ARM Compiler Version 5 缺失的来龙去脉,以及官方安装、离线拷贝、迁移到 AC6 三种靠谱的解决办法。不管是刚入门的小白,还是维护老项目的工程师,照着做基本都能把编译环境拉回正轨。
1. 先把报错拆开看:缺的到底是什么?
1.1 报错现场与常见环境
这种报错描述得非常直白:Keil 读取到工程里写着一个编译选项,要求使用Arm Compiler 5,并且期待在某个路径下找到它的可执行文件,结果发现该路径下根本没有对应的armcc.exe。
常见的完整提示有两类。一类是工程打开或编译时直接提示:
Target uses ARM-Compiler 'Arm Compiler 5' in '..\Keil_v5\ARM\ARMCC\bin' which is not available.另一类是在编译输出窗口里出现:
*** Target 'Target 1' uses ARM-Compiler 'Arm Compiler 5' in '..\Keil_v5\ARM\ARMCC\bin', which is not available.我遇到最多的情况集中在三种场景:
- 刚重装系统,重新安装了最新版 Keil MDK,然后打开以前的老工程。
- 换了一台电脑,直接把整个工程目录从旧电脑拷贝过来,没有一起拷贝老的 Keil 安装目录。
- 同一台电脑上卸载过旧版 MDK,再安装新版时,没有保留
ARMCC编译器目录。
前两种最迷惑人,因为源码、芯片包、分散加载文件都在,看起来一切正常,结果一编译就断在编译器上。这时候不要急着改代码,先确认编译器是否真的存在。
1.2 老工程为什么死磕 AC5
Keil MDK 从很早就开始同时支持两套编译工具链:老牌的 Arm Compiler 5(通常叫 ARMCC)和新一代的 Arm Compiler 6(基于 Clang,通常叫 ARMClang)。两者的编译规则、语法检查、优化策略和代码生成方式都不完全相同。
早期用 MDK 5.xx 创建的工程,默认选择的是 Arm Compiler 5。工程文件.uvprojx里会有一个标志位记录这个选择,常见的体现就是uAC6这个标签。老工程默认把这个值设成0,意思就是“请用 AC5 给我编译”。如果你新装的 Keil 只有 AC6,Keil 拿着工程配置去对编译器清单,当然找不到 AC5,于是直接报错。
还有一个更现实的原因:很多旧项目的启动文件、底层库、CMSIS 版本都是按 AC5 的规则写的。AC5 对于某些语法非常宽容,比如老的__asm内联汇编、旧的#pragma用法,在 AC5 下可以编译,到了 AC6 可能会变成硬错误。对只负责维护业务代码的工程师来说,把编译器版本换掉往往意味着大量兼容性修复,远不如装回 AC5 省事。
1.3 装了 AC6 为什么还缺 AC5
有一个很常见的误区:我在同一台电脑上装了 MDK,里面明明有 AC6,为什么还提示缺 AC5?
因为 AC5 和 AC6 是两套独立安装的编译器,不是同一个工具的两个开关。在 Keil 的安装目录里,通常是这样区分的:
C:\Keil_v5\ARM\ARMCC\ // Arm Compiler 5,主程序是 armcc.exe C:\Keil_v5\ARM\ARMCLANG\ // Arm Compiler 6,主程序是 armclang.exe默认安装新版 MDK 时,官方安装包很可能只带ARMCLANG,不会自动带上ARMCC。有 AC6 不代表有 AC5,这个前提不解决,编译报错会一直存在。尤其从 MDK v5.36/v5.37 这个阶段开始,官方对安装策略做了调整,AC5 变成需要单独安装的组件,不再默认集成。这也解释了为什么这一两年突然冒出大量同样的求助。
2. 首选方案:从官方渠道补齐 ARM Compiler Version 5
2.1 安装前先确认现有版本和安装路径
不管用哪种方法补装,第一步都是先搞清楚本机 Keil 的安装位置和版本。因为新版 MDK 的安装路径不一定还是老默认的C:\Keil_v5,有人装在 D 盘,有人装在自定义目录,还有人用的是别人拷贝过来的绿色版。
打开 Keil uVision,点菜单栏Help -> About uVision,能看到 MDK 版本号,比如5.37.0.0、5.36.0.0。然后到安装目录下确认一下当前有什么:
C:\Keil_v5\ ARM\ ARMCC\ ARMCLANG\ PACK\如果ARMCC文件夹不存在,或者存在但里面没有bin\armcc.exe,那基本可以判断为编译器缺失或安装不完整。这里顺手检查一下路径里有没有中文、空格、特殊字符,尤其是从旧电脑拷贝过来的工程,路径不对也会引发诡异的编译错误。
2.2 下载并安装 Arm Compiler 5,一步步操作
官方渠道补装 AC5 最稳妥,步骤也不复杂。到 Arm 官网或者 Keil 官网搜索“Arm Compiler 5”,找到下载页面,选择Arm Compiler 5.06 update 7的安装包。这是 AC5 系列中非常常用的一个版本,很多工程在 Target 配置里直接指定的就是V5.06 update 7。
下载的时候要注意,有些页面会同时提供 AC5 和 AC6,别下错。名字里通常带ARM Compiler 5或者armcc字样。安装时需要注意的关键点是:安装路径必须和现有 Keil MDK 的根目录对齐。
比如你的 Keil MDK 装在:
C:\Keil_v5那么安装 AC5 时,要把安装路径选成:
C:\Keil_v5不要选C:\Keil_v5\ARM,更不要选C:\Program Files\Arm。因为这个安装包会自动在指定根目录下创建ARM\ARMCC这样的目录结构,选错路径,Keil 照样找不到。
安装完成后,回到目录检查:
C:\Keil_v5\ARM\ARMCC\bin\armcc.exe能看到这个 exe,说明编译器本体已经就位。剩下的就是让 Keil 重新认识它。
2.3 安装完成后如何让 Keil 认出来
编译器文件放好后,重启 Keil uVision,再打开老工程。右键工程名,选择Options for Target,切到Target选项卡,底部有一个ARM Compiler下拉框,里面通常会出现若干选项:
Use default compiler version 5Use latest installed version- 具体的
V5.06 update 7 - 也可能同时列出
V6.x
把编译器选成 V5 相关的选项,点 OK,重新编译。大多数情况下,原来那个“缺失”的报错就会消失。
如果下拉框里还是看不到任何 V5 选项,可以用文本编辑器直接打开.uvprojx工程文件,搜索uAC6这个标签:
<TargetOption> <uAC6>0</uAC6> </TargetOption>把<uAC6>的值改成0,再保存关闭,重新用 Keil 打开工程。这个标签在老工程里如果记录的是1,意味着 Keil 按 AC6 的方式去加载工程;改成0后,会强制走 AC5 的兼容路径。配合上一步安装好的 ARMCC 目录,通常能解决识别不到的问题。
3. 没有外网或者着急复用:离线拷贝 ARMCC 的实用技巧
3.1 拷贝前要做好的几个准备
并不是所有环境都有条件去官网下载安装包。内网开发、客户现场、临时借来的电脑,这些场景下更快的办法是找一台已经装好 AC5 的电脑,把整个ARMCC目录离线拷贝过来。
但千万别只拷贝bin文件夹,那样大概率会失败。完整的 AC5 目录不仅包含可执行文件,还有 include 头文件、lib 库文件、模板文件、许可相关文件等。正确做法是把整个ARMCC目录完整复制,而不是挑其中一部分。
拷贝前最好在两台电脑上确认一下 Keil 版本差异。如果源机器是 MDK 5.36,目标机器是 MDK 5.37,AC5 版本相同的情况下,问题通常不大。但如果源机器本身就是残缺的绿色版,拷贝出来的目录也未必完整,所以尽量找一台用官方安装包装好的电脑。
3.2 拷贝目录与路径对齐
源机器上 AC5 的位置一般在:
D:\Keil_v5\ARM\ARMCC先把整个文件夹拷贝到 U 盘或者内网共享目录。到目标机器上之后,找到目标 Keil 安装目录下对应的 ARM 文件夹。假设目标 Keil 装在:
C:\Keil_v5那就把ARMCC放到:
C:\Keil_v5\ARM\ARMCC注意最终保证路径是:
C:\Keil_v5\ARM\ARMCC\bin\armcc.exe而不是:
C:\Keil_v5\ARM\ARMCC\ARMCC\bin\armcc.exe目录层级如果多套了一层,Keil 一样找不到。拷贝过程如果被杀毒软件拦截,可以把 Keil 安装目录加入白名单以后重新拷贝。很多用户在外面拷贝大目录时经常“丢文件”,最后编译报错信息变得奇奇怪怪,其实都是杀毒软件后台清理了一部分 dll。
3.3 验证绿色编译器能否被识别
拷贝完成后,先别急着打开 Keil。打开 Windows 命令行,切到 ARMCC 的 bin 目录,执行一下:
C:\Keil_v5\ARM\ARMCC\bin\armcc.exe --version正常情况下会输出版本号,比如Product: ARM Compiler 5.06 update 7 (build 960)。如果提示找不到入口或者报缺 dll,说明目录不完整,要继续补文件。
命令行验证通过后,再打开 Keil,进Options for Target -> Target,看下拉框里有没有出现 V5。有时候 Keil 不会自动刷新编译器列表,可以先关闭工程,再重新打开;如果还不行,就把 Keil 完全退出再启动。需要说明的是,离线拷贝这个方法本身是“绿色化”思路,干净程度不如官方安装包,但应急和批量部署时非常实用。我遇到过不少次客户现场不让连外网,这个方法几乎是唯一能在十几分钟内把编译环境救起来的方案。
4. 更彻底的做法:把旧工程迁移到 ARM Compiler 6
4.1 切换编译器版本的入口
如果手上没有 AC5 安装包,也找不到第二台电脑拷贝,那还有一条路:让工程改用 AC6 编译。这条路前期有点痛,但长期来看更有价值,因为 AC6 是当前 Keil 主推的工具链,新开发的工程基本都在用 AC6。
操作入口依然是工程右侧的Options for Target -> Target -> ARM Compiler,在这里把编译器切换成V6.x或者Use latest installed version。点击 OK 后,直接编译。
第一次用 AC6 编译老工程,大概率会刷出一屏错误和警告。不用慌,这些错误可以按类型分批处理,常见的有语法差异、头文件兼容性、内联汇编写法等。处理方式可以参考下面几个方向。
4.2 迁移到 AC6 常见的兼容性改动
AC6 基于 Clang,对 C 语言标准的遵循更严格,这意味着以前 AC5 里“蒙混过关”的写法,在 AC6 下会被拎出来。最常见的一类是老的__asm内联汇编,写法可能是:
__asm { MOV R0, #0 }这在 AC5 里能编译,但 AC6 可能会把它视为错误。解决办法是改成 AC6 支持的语法,或者把汇编逻辑提取到独立的.s文件里,用函数接口调用。具体语法细节最好对照 Keil 的 AC6 迁移文档,因为不同版本、不同芯片内核,写法会有细微差异。
另一类常见问题是 CMSIS 和芯片头文件的版本。老工程里可能还在用很老的 CMSIS,AC6 对头文件的依赖顺序和宏定义方式更敏感。最简单的处理方法是打开 Pack Installer,把当前芯片对应的 Device Family Pack 更新到较新版本,CMSIS 相关的头文件也会同步升级。
实际迁移时,我习惯先把编译器切到 AC6,把错误列表按文件排序,先修启动文件相关的错误,再修外设库、业务代码。一边修一边编译,效率比一次性大改要高很多。
4.3 迁移后如何验证行为一致性
编译器换了,表面编译通过只是第一步,更要紧的是行为保持一致。我通常会在迁移后做三件事:
首先对比 MAP 文件和编译输出里的 Code、RO Data、RW Data、ZI Data 大小。AC6 的优化策略和 AC5 不完全相同,体积有变化很正常,但如果相差特别大,比如代码直接缩小 30% 以上,就要警惕是不是有函数被误裁剪了。
然后在目标板上跑一遍核心功能自测,重点关注中断、定时器、ADC、通信接口这些时序敏感的模块。AC5 和 AC6 对 volatile、内存对齐的处理规则有差异,偶尔会出现“编译过了但运行不正常”的情况。
最后把编译器警告级别开高一点,AC6 会给出很多 AC5 不提示的 warning,比如隐式函数声明、类型转换不一致。把这些 warning 当 error 清理干净,能提前排查掉很多现场才暴露的问题。
| 对比维度 | AC5 | AC6 |
|---|---|---|
| 编译标准 | 偏老,宽容度高 | 严格,遵循 C99/C11 更彻底 |
| 代码体积 | 基准 | 多数场景更小 |
| 编译速度 | 较慢 | 通常更快 |
| 新工程支持 | 官方已弱化 | 当前主推 |
| 老代码兼容性 | 很好 | 需要少量改动 |
如果你只是为了临时编译老工程,装回 AC5 更省事;如果这个项目还要长期维护,多花半天迁移到 AC6 是值得的。
5. 常见问题速查和排坑心得
5.1 报错信息对照表
| 报错信息 | 可能原因 | 解决办法 |
|---|---|---|
Target uses ARM-Compiler 'Arm Compiler 5' ... not available | 工程指定 AC5,但 Keil 没安装 AC5 | 按第 2 节安装 AC5,或离线拷贝 ARMCC |
fatal error: C3908U: Compiler 5 is not installed | Keil 找不到 ARMCC 可执行程序 | 检查ARMCC\bin\armcc.exe是否存在,确认安装路径与 Keil 根目录一致 |
L6002U: Could not open file ...\ARMCC\lib\armlib\... | ARMCC 目录不完整,lib 文件缺失 | 从其他电脑完整拷贝 ARMCC,不要只拷贝 bin |
#error "Compiler version not supported" | 头文件针对编译器做了版本判断,但检测不到预期版本 | 更新 CMSIS,或切换到 AC6 后再编译 |
| 编译能通过,但烧录后运行不正常 | 编译器版本切换后,优化和内存对齐行为变化 | 对比 MAP 文件,重点验证中断、外设和时序相关代码 |
对照表只能帮你快速定位大方向,真正排查时还要结合自己的工程目录特征。比如报错信息里的路径是相对路径还是绝对路径,如果工程文件里写死了某个旧电脑的盘符,那即使本地装了 AC5 也可能识别不到。这时候可以把工程路径和 Keil 安装路径都改成同一盘符下的简单目录,再重新打开验证。
5.2 几个容易被忽略的细节
第一个细节是权限问题。AC5 安装到C:\Keil_v5时,如果系统账号没有管理员权限,安装包可能只释放了部分文件。建议安装时右键选择“以管理员身份运行”,装完以后也尽量用管理员身份打开 Keil。尤其公司电脑开了 UAC 的话,这一步省不了。
第二个细节是杀毒软件。ARMCC 目录下有很多 exe、dll 文件,杀毒软件在后台扫描时有可能误报或者隔离部分文件。遇到“昨天还能编译今天突然报缺失”的情况,先去隔离区看看有没有被删的 ARMCC 文件。把 Keil 安装目录加入杀毒软件白名单,是减少这类问题很有效的习惯。
第三个细节和 Target 选项卡有关。有人装了 AC5 之后,发现Options for Target -> Target里的Xtal(MHz)是灰色的,改不了。这其实和编译器缺失不是同一个问题,通常是因为工程没有正确选择器件,或者对应的 Device Family Pack 没有被安装。去 Pack Installer 里搜芯片型号,装好相应 Pack,再回来设置晶振频率,灰色状态就会解除。
还有一个小问题经常被混淆:AC5 缺失和“编译很慢”不是一回事。如果你已经成功编译,但速度特别慢,先检查电脑是否开启了杀毒软件实时监控,再看工程输出目录是不是在机械硬盘,最后看是不是开了过大的优化等级。不要因为编译慢就反复卸载重装 Keil,那样只会把环境搞得更乱。
最后再说一点自己的体会
这几类问题我前前后后处理过很多次,最大的感受是:遇到编译器缺失的报错,先冷静判断“缺的到底是工具还是配置”,不要一上来就重装整个 Keil。确认ARMCC目录是否存在、路径是否对齐、工程里的编译器选项是否是 V5,这三步能解决八成问题。官方安装包最省心,离线拷贝是应急利器,迁移 AC6 则是长期主义,三条路线没有绝对好坏,看你的时间和场景选。关键在于理解 Keil 的编译器机制,搞清楚 AC5 和 AC6 是两套独立工具,而不是靠换工程文件硬凑。下次再看到“ARM Compiler Version 5 缺失”,翻出这篇文章,按顺序操作一遍,基本都能顺利编译通过。