为 GCC 编译器添加 OpenHarmony (OHOS) 目标支持:深度解析与实现思路
do;;;;;while0// OpenHarmony 特定代码#endif。
为 GCC 编译器添加 OpenHarmony (OHOS) 目标支持:深度解析与实现思路
作者:sanchuanhehe
日期:2025年12月5日
地址:https://gitcode.com/sanchuanhehe/ohos-gcc
状态:施工中
引言
OpenHarmony 是一款面向全场景的开源分布式操作系统,由华为贡献给开放原子开源基金会。虽然 OpenHarmony 官方主要使用 LLVM/Clang 作为编译工具链,但为 GCC 添加 OHOS 目标支持具有重要意义:
- 生态兼容性:许多开源项目仍然依赖 GCC 特有的扩展和特性
- 工具链多样性:提供更多编译选择,便于性能对比和问题排查
- 移植便利性:简化现有 GCC 项目向 OpenHarmony 的移植工作
本文将深入分析为 GCC 15.2.0 添加 OpenHarmony 目标支持的补丁实现,讲解关键技术点和设计思路。
一、GCC 目标支持的整体架构
在深入补丁细节之前,我们需要理解 GCC 如何支持新的操作系统目标。GCC 的目标配置系统主要由以下几部分组成:
┌─────────────────┐
│ config.sub │ 目标三元组识别
└────────┬────────┘
│
┌────────▼────────┐
│ config.gcc │ 目标配置主文件
└────────┬────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
┌───────▼───────┐ ┌────────▼────────┐ ┌──────▼──────┐
│ ohos.h │ │ arch-ohos.h │ │ t-ohos │
│ (通用配置) │ │ (架构特定配置) │ │ (Makefile) │
└───────────────┘ └─────────────────┘ └─────────────┘
1.1 目标三元组 (Target Triplet)
GCC 使用"目标三元组"来标识编译目标,格式为:架构-厂商-操作系统
对于 OpenHarmony,我们定义了以下主要目标:
| 架构 | 目标三元组 | 说明 |
|---|---|---|
| AArch64 | aarch64-linux-ohos |
ARM 64位 |
| ARM | arm-linux-ohos |
ARM 32位 |
| x86_64 | x86_64-linux-ohos |
Intel/AMD 64位 |
| RISC-V | riscv64-linux-ohos |
RISC-V 64位 |
| MIPS | mips64el-linux-ohos |
MIPS 64位小端 |
二、补丁核心修改分析
2.1 config.sub 修改:识别 OHOS 目标
- | fiwix* )
+ | fiwix* | ohos* )
;;
以及:
linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
- | linux-musl* | linux-relibc* | linux-uclibc* )
+ | linux-musl* | linux-relibc* | linux-uclibc* | linux-ohos* )
;;
设计思路:
- 将
ohos添加到操作系统识别列表 - 支持
linux-ohos内核-操作系统组合 - 这使得
aarch64-linux-ohos等三元组能被正确解析
2.2 config.gcc 修改:配置构建参数
这是最核心的配置文件,需要处理多个方面:
2.2.1 C 库选择
*-*-*ohos*)
tm_defines="$tm_defines DEFAULT_LIBC=LIBC_MUSL"
;;
OpenHarmony 使用 musl libc,这一选择至关重要:
- musl 是轻量级、符合标准的 C 库
- 相比 glibc 更适合嵌入式场景
- Alpine Linux 也使用 musl,提供了良好的参考
2.2.2 架构特定配置
以 AArch64 为例:
aarch64*-*-linux-ohos*)
tm_file="${tm_file} elfos.h gnu-user.h linux.h ohos.h glibc-stdint.h"
tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-linux.h aarch64/aarch64-ohos.h"
tmake_file="${tmake_file} aarch64/t-aarch64 aarch64/t-aarch64-ohos"
tm_defines="${tm_defines} TARGET_DEFAULT_ASYNC_UNWIND_TABLES=1"
gas=yes gnu_ld=yes
;;
关键点:
- 头文件链:按顺序加载配置头文件,后面的可以覆盖前面的定义
- 异步展开表:启用
.eh_frame以支持 C++ 异常处理 - 工具链:指定使用 GNU as 和 GNU ld
2.3 通用 OHOS 配置头文件 (ohos.h)
这个文件定义了所有架构共享的 OHOS 配置:
2.3.1 C 库选择宏
#undef OPTION_GLIBC
#define OPTION_GLIBC 0
#undef OPTION_MUSL
#define OPTION_MUSL 1
2.3.2 预定义宏
#define OHOS_BASE_OS_CPP_BUILTINS() \
do { \
builtin_define ("__ohos__"); \
builtin_define ("__OpenHarmony__"); \
builtin_define ("__MUSL__"); \
builtin_assert ("target=ohos"); \
builtin_assert ("target=openharmony"); \
} while (0)
这些宏让用户代码可以检测编译目标:
#ifdef __ohos__
// OpenHarmony 特定代码
#endif
2.3.3 动态链接器配置
#define OHOS_DYNAMIC_LINKER OHOS_ARCH_DYNAMIC_LINKER
动态链接器路径遵循 musl 约定,由架构特定头文件定义:
| 架构 | 动态链接器路径 |
|---|---|
| AArch64 | /lib/ld-musl-aarch64.so.1 |
| ARM (hard float) | /lib/ld-musl-armhf.so.1 |
| x86_64 | /lib/ld-musl-x86_64.so.1 |
| RISC-V 64 | /lib/ld-musl-riscv64.so.1 |
2.3.4 安全特性
#define CC1_SPEC \
"%{!fno-stack-protector:%{!fstack-protector-all:%{!fstack-protector-strong:%{!fstack-protector:-fstack-protector}}}}"
默认启用栈保护(Stack Protector),这是 OpenHarmony 的安全要求。
2.4 架构特定配置
以 AArch64 为例 (aarch64-ohos.h):
2.4.1 Cortex-A53 勘误修复
#undef TARGET_FIX_ERR_A53_835769_DEFAULT
#define TARGET_FIX_ERR_A53_835769_DEFAULT 1
#undef TARGET_FIX_ERR_A53_843419_DEFAULT
#define TARGET_FIX_ERR_A53_843419_DEFAULT 1
这修复了 Cortex-A53 处理器的已知硬件 bug。
2.4.2 库搜索路径
#define OHOS_ARCH_LIB_DIR "aarch64-linux-ohos"
#define STARTFILE_SPEC \
"%{!shared: \
%{pg|p|profile:%R/usr/lib/" OHOS_ARCH_LIB_DIR "/gcrt1.o%s; \
pie:%R/usr/lib/" OHOS_ARCH_LIB_DIR "/Scrt1.o%s; \
:%R/usr/lib/" OHOS_ARCH_LIB_DIR "/crt1.o%s}} \
%R/usr/lib/" OHOS_ARCH_LIB_DIR "/crti.o%s \
%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
定义了 CRT(C Runtime)文件的搜索路径,这些文件在程序启动时执行。
2.4.3 链接规范 (LINK_SPEC)
#define LINK_SPEC \
"%{mbig-endian:-EB} %{mlittle-endian:-EL} " \
"%{shared:-shared} " \
"%{!shared: " \
"%{!static: " \
"%{rdynamic:-export-dynamic} " \
"-dynamic-linker " OHOS_DYNAMIC_LINKER "} " \
"%{static:-static}} " \
"-L%R/usr/lib/" OHOS_ARCH_LIB_DIR " " \
"-L%R/usr/lib "
这定义了传递给链接器的参数。
2.5 libgcc 配置
aarch64*-*-linux-ohos*)
extra_parts="$extra_parts crtfastmath.o"
md_unwind_def_header=aarch64/aarch64-unwind-def.h
md_unwind_header=aarch64/linux-unwind.h
tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc"
tmake_file="${tmake_file} t-softfp ${cpu_type}/t-softfp"
;;
配置了:
- LSE (Large System Extension) 原子操作支持
- 软浮点支持
- 异常展开支持
2.6 线程支持修改
-#ifndef __BIONIC__
+#if !defined(__BIONIC__) && !defined(__OHOS__)
__gthrw(pthread_cancel)
#endif
原因:musl libc 的 pthread_cancel 实现有限制,类似 Android 的 Bionic libc。通过这个修改,避免在 OHOS 上使用 pthread_cancel。
2.7 兼容性修复
// gcc/system.h
#ifndef __GLIBC_PREREQ
#define __GLIBC_PREREQ(x, y) 0
#endif
当交叉编译到 musl 目标时,host 系统可能使用 glibc,而某些代码会检查 __GLIBC_PREREQ。这个宏确保在非 glibc 环境下编译不会出错。
三、与 LLVM/Clang OHOS 支持的对比
| 特性 | GCC (本补丁) | LLVM/Clang |
|---|---|---|
| C 库 | musl | musl |
| 运行时库 | libgcc | compiler-rt |
| C++ 标准库 | libstdc++ (可选 libc++) | libc++ |
| 动态链接器路径 | 相同 | 相同 |
| 默认安全特性 | SSP | SSP |
本补丁的设计参考了 LLVM 的 OHOS 支持实现,确保两者生成的代码具有 ABI 兼容性。
四、架构支持矩阵
┌─────────────┬──────────┬──────────┬──────────┬──────────┐
│ 架构 │ 动态 │ 软浮点 │ LSE │ MIPS │
│ │ 链接器 │ │ 原子 │ N32 │
├─────────────┼──────────┼──────────┼──────────┼──────────┤
│ AArch64 │ ✓ │ ✓ │ ✓ │ - │
│ ARM │ ✓ │ ✓ │ - │ - │
│ x86/x86_64 │ ✓ │ - │ - │ - │
│ RISC-V │ ✓ │ ✓ │ - │ - │
│ MIPS │ ✓ │ - │ - │ ✓ │
└─────────────┴──────────┴──────────┴──────────┴──────────┘
五、构建和使用
5.1 构建交叉编译器
# 应用补丁
cd gcc-15.2.0
patch -p1 < ../patches/0001-Add-OpenHarmony-OHOS-target-support-to-GCC.patch
# 配置
mkdir build && cd build
../configure \
--target=aarch64-linux-ohos \
--prefix=/opt/ohos-gcc \
--enable-languages=c,c++ \
--with-sysroot=/path/to/ohos-sysroot \
--disable-multilib
# 构建
make -j$(nproc)
make install
5.2 使用编译器
# 编译 C 程序
aarch64-linux-ohos-gcc -o hello hello.c
# 编译 C++ 程序
aarch64-linux-ohos-g++ -o hello hello.cpp
# 静态链接(不需要 sysroot)
aarch64-linux-ohos-gcc -static -o hello hello.c
参考资料
附录:补丁文件清单
| 文件 | 作用 |
|---|---|
config.sub |
目标识别 |
gcc/config.gcc |
主配置文件 |
gcc/config/ohos.h |
通用 OHOS 配置 |
gcc/config/ohos-paths.h |
路径定义 |
gcc/config/t-ohos |
Makefile 片段 |
gcc/config/aarch64/aarch64-ohos.h |
AArch64 配置 |
gcc/config/aarch64/t-aarch64-ohos |
AArch64 Makefile |
gcc/config/arm/arm-ohos.h |
ARM 配置 |
gcc/config/arm/t-arm-ohos |
ARM Makefile |
gcc/config/i386/i386-ohos.h |
x86 配置 |
gcc/config/mips/mips-ohos.h |
MIPS 配置 |
gcc/config/riscv/riscv-ohos.h |
RISC-V 配置 |
gcc/system.h |
兼容性修复 |
libcpp/system.h |
兼容性修复 |
libgcc/config.host |
libgcc 配置 |
libgcc/gthr-posix.h |
线程支持修复 |
libstdc++-v3/configure.host |
C++ 库配置 |
更多推荐


所有评论(0)