Harmonybrew 仓库中的 gcc(GCC 16)和 llvm(LLVM 23)已经可用
1 前言
鸿蒙生态中缺乏高版本编译器,这是一个困扰开发者们已久的问题。ohos-sdk 中的 LLVM 至今仍停留在 LLVM 15 版本。
由于缺乏高版本编译器,很多依赖高版本 C 标准和高版本 C++ 标准的开源软件都无法移植到鸿蒙平台上。
为了解决这个问题,Harmonybrew 社区的开发者(包括我自己)自发完成了 GCC 和 LLVM 的鸿蒙移植,并且已经将它们录入到 Harmonybrew 核心仓库中。
2 使用方法
2.1 gcc
2.1.1 卸载冲突软件包
如果安装过 llvm-gcc-compat,需要将其卸载:
brew uninstall llvm-gcc-compat
llvm-gcc-compat 里面实现了 gcc 和 ld 这两个软链接,会跟 gcc 和 binutils 冲突。formula 中已经做了冲突声明,如果同时安装这些包,Homebrew 会报错。
2.1.2 安装 gcc
只需要安装 gcc 这一个 formula:
brew install gcc
gcc 级联依赖了 binutils,并默认使用 binutils 里面的 ld 作为链接器。使用过程中不依赖 ohos-sdk 提供的任何命令。
gcc 编译出来的程序可以直接在鸿蒙 PC 上运行,不需要专门用 ohos-sdk 的 binary-sign-tool 签名。因为我已经给 binutils 里面的 ld 打上了自动签名补丁,由它生成的 ELF 文件会默认带有代码签名。
2.1.3 使用 gcc
正常调用 gcc 命令即可:
gcc my_program.c -o my_program
如果你的程序依赖了运行时库(libgcc、libstdc++ 等),它会默认从 gcc 的安装目录里面读取。编译器会自动设置 rpath 来完成这件事。这个行为并不是 Harmonybrew 定制改造的,而是遵循了上游 Homebrew 的配置方式。
这意味着:默认情况下,如果你要将一个依赖了运行时库的程序分发给其他设备使用,目标设备也需要装一个 Harmonybrew,并通过 Harmonybrew 安装一个 gcc,让它提供运行时库。
如果你不想受这个限制,想要让自己的程序能够分发到任意鸿蒙设备上使用,那你需要使用 -static-libgcc、-static-libstdc++ 等编译参数,将运行时库静态链接到自己的程序中。这一点在 gcc 的安装提示里面也有说明。
2.2 llvm
2.2.1 卸载冲突软件包
如果安装过 ohos-sdk,需要将其卸载:
brew uninstall ohos-sdk
ohos-sdk 里面也有 LLVM 编译器,也会提供 clang 命令,会跟独立安装的 llvm 冲突。formula 中已经做了冲突声明,如果同时安装这些包,Homebrew 会报错。
2.2.2 安装 llvm
需要同时安装 llvm 和 lld:
brew install llvm lld
在 Homebrew 中,llvm 和 lld 是两个各自独立的 formula(虽然它们来自同一个开源项目)。在没有系统链接器的情况下,我们需要把 lld 也装上,让它来提供 ld.lld 命令。
llvm 编译出来的程序可以直接在鸿蒙 PC 上运行,不需要专门用 ohos-sdk 的 binary-sign-tool 签名。因为我已经给 lld 打上了自动签名补丁,由它生成的 ELF 文件会默认带有代码签名。
当前 llvm 系列还提供了 llvm@22、llvm@21 这两个版本化的 formula,整个系列都是可以正常使用的。
例如:
brew install llvm@22 lld@22
brew install llvm@21 lld@21
2.1.3 使用 llvm
正常调用 clang 命令即可:
clang my_program.c -o my_program
虽然独立安装的 llvm 和 ohos-sdk 里面的 LLVM 都是 LLVM,但由于版本差距太大,它们的运行时库并不互相兼容,我们并不能让 llvm 编出来的程序链接到系统的运行时库。
出于上述原因,这版 llvm 被配置成了默认静态链接所有运行时库,且只支持静态的运行时库,完全不提供动态的运行时库。这一点在 llvm 的安装提示里面也有说明。
3 移植情况
3.1 gcc
这个 formula 由我本人完成移植,使用的工具是 Codex + DeepSeek-V4.1-Flash。
PR 链接:https://atomgit.com/Harmonybrew/homebrew-core/pull/20443
官方测试套件执行结果(可作为适配完成度的参考):
| 套件 | PASS | FAIL | ERROR | UNRESOLVED |
|---|---|---|---|---|
| gcc | 387,883 | 201 | 0 | 137 |
| g++ | 448,886 | 97 | 0 | 52 |
| gfortran | 73,452 | 12 | 0 | 0 |
| gm2 | 15,099 | 156 | 0 | 156 |
| objc | 2,849 | 0 | 0 | 0 |
| obj-c++ | 1,506 | 0 | 0 | 0 |
| libstdc++ | 17,800 | 20 | 0 | 2 |
| libgomp | 166 | 0 | 434 | 133 |
| libatomic | 54 | 0 | 0 | 0 |
| libitm | 43 | 1 | 0 | 0 |
3.2 llvm
Harmonybrew 里面的 LLVM 最早是由社区开发者 @social4hyq 完成移植,最早移植的版本是 llvm@21。
PR 链接:https://atomgit.com/Harmonybrew/homebrew-core/pull/18194
在 @social4hyq 提交了 llvm@21 的 formula 之后,我用 AI 将 llvm@21 上面的适配补丁移植到了 llvm 和 llvm@22 这两个 formula 上,并补充做了人工测试。
官方测试套件执行结果(可作为适配完成度的参考):
| 套件 | 总数 | 通过 | 失败 | 跳过/不支持 |
|---|---|---|---|---|
| LLVM | 64,397 | 22,985 | 1 | 41,411 |
| Clang | 24,936 | 19,794 | 27 | 5,115 |
| Clang-Unit | 29,041 | 29,020 | 0 | 21 |
| LLVM-Unit | 11,384 | 11,146 | 0 | 238 |
| MLIR | 3,311 | 2,686 | 0 | 625 |
| MLIR-Unit | 1,069 | 1,068 | 0 | 1 |
| Clangd Unit Tests | 1,403 | 1,403 | 0 | 0 |
| Clang Tools | 1,202 | 1,199 | 2 | 1 |
| Polly | 1,104 | 1,064 | 0 | 40 |
| Extra Tools Unit Tests | 515 | 515 | 0 | 0 |
| Clangd | 99 | 90 | 0 | 9 |
| clangIncludeCleaner Unit Tests | 97 | 97 | 0 | 0 |
| lit | 92 | 87 | 1 | 4 |
| Polly-Unit | 26 | 26 | 0 | 0 |
| mlgo-utils | 7 | 6 | 0 | 1 |
| ClangIncludeCleaner | 6 | 6 | 0 | 0 |
| Polly - isl unit tests | 1 | 1 | 0 | 0 |
提示:
- “不支持”占比高是正常现象:Harmonybrew 里面的
llvm只构建了 aarch64 后端,因此 x86/mips 等后端相关用例被标记为 UNSUPPORTED;另有大量依赖 Windows/macOS、特定外部工具链或 gc-sections 的用例被跳过。 - LLVM 和 GCC 两个项目的测试框架不同,不能直接用这个表格上的数字来比较测试用例的完善程度。LLVM 的 9 万个用例的背后,实际执行了约 32 万条 RUN、匹配了近 600 万条 CHECK。按 GCC 的记法(check 级别)衡量,两者在同一个量级上,只是计数单位不同。
更多推荐



所有评论(0)