Skip to content

Commit 48bf6d4

Browse files
committed
docs: add linux build methodology writeup
1 parent df17197 commit 48bf6d4

2 files changed

Lines changed: 147 additions & 1 deletion

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
[oO]bj
33
__pycache__
44
[Tt]est[Rr]esults
5-
TestResults
5+
.idea/
6+
.vs/
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# HostForge Linux 交叉编译方案形成记录
2+
3+
## 结论
4+
5+
HostForge 当前的 Linux 构建采用交叉编译方案。
6+
7+
构建时使用现代宿主机上的 `clang`,目标环境使用与 `.NET` 官方 Linux host 基线一致的 `Ubuntu 18.04 bionic` sysroot。`.NET host``SkiaSharp``HarfBuzz` 使用同一套 ABI 基线,目标 `GLIBC` 版本为 `2.27`
8+
9+
## 背景
10+
11+
HostForge 当前的 Linux 产物包含两部分原生代码来源:
12+
13+
- `.NET host` 侧的 `apphost` / `singlefilehost`
14+
- `SkiaSharp` / `HarfBuzz` 侧的附加静态库
15+
16+
早期工作先在现代 Linux 发行版上完成了 `apphost``singlefilehost` 的本机编译。引入 `SkiaSharp 3.119` 后,工具链基线、链接方式和运行时兼容性问题开始集中暴露。
17+
18+
## 为什么这样做
19+
20+
### 1. 产物检查显示 ABI 基线需要统一
21+
22+
`Arch Linux + clang 21 + gcc 15` 环境下,`apphost``singlefilehost` 已经可以编译通过。继续处理 `SkiaSharp 3.119` 时,出现了高版本 `llvm``gcc` 相关问题,对应参考包括:
23+
24+
- `https://github.com/llvm/llvm-project/issues/95133`
25+
- `https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/issues/312`
26+
- `https://gcc.gnu.org/gcc-13/porting_to.html#header-dep-changes`
27+
28+
随后在 `Ubuntu 22.04 + gcc 11.4.0` 环境中完成了一版 host 与 skia 的组合构建,并执行:
29+
30+
```bash
31+
readelf -p .comment singlefilehost
32+
```
33+
34+
结果如下:
35+
36+
```text
37+
String dump of section '.comment':
38+
[ 0] Ubuntu clang version 14.0.0-1ubuntu1.1
39+
[ 28] Linker: LLD 21.1.8
40+
[ 3b] GCC: (GNU) 15.2.1 20260209
41+
[ 56] GCC: (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0
42+
```
43+
44+
这说明产物中已经混入多个来源的工具链信息。接下来需要确认整条构建链路最终使用的是哪条 ABI 基线。
45+
46+
### 2. `.NET` 官方 host 产物给出了基线线索
47+
48+
继续检查原版 `.NET singlefilehost``.comment` 信息后,得到:
49+
50+
```text
51+
String dump of section '.comment':
52+
[ 0] GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
53+
[ 2a] Linker: LLD 20.1.8
54+
[ 3d] clang version 20.1.8
55+
```
56+
57+
这个结果体现出目标环境 GCC 注记与现代 `clang` / `lld` 注记同时存在。HostForge 因此采用“宿主工具链 + 目标 sysroot”的交叉编译路径,并以 `.NET` 官方 Linux host 的基线作为对齐目标。
58+
59+
### 3. `.NET runtime` 文档和脚本提供了直接方法依据
60+
61+
交叉编译方案的主要依据来自以下文件:
62+
63+
- `https://github.com/dotnet/runtime/blob/v10.0.3/docs/workflow/building/coreclr/cross-building.md`
64+
- `https://github.com/dotnet/runtime/blob/v10.0.3/eng/common/cross/build-rootfs.sh`
65+
66+
其中:
67+
68+
- `cross-building.md` 给出了交叉编译入口:先生成 `ROOTFS`,再通过 `ROOTFS_DIR` 配合 `build.sh --cross` 进入交叉编译流程
69+
- `build-rootfs.sh` 给出了 sysroot 的构造方式:基于 `debootstrap --variant=minbase` 初始化 rootfs,重写源配置,在 `chroot` 内安装开发包和运行时依赖,最后执行 `symlinks -cr /usr`
70+
71+
这些内容确定了 HostForge 的 sysroot 构造方法和交叉编译入口。
72+
73+
### 4. `SkiaSharp` 提供了参数传递方式
74+
75+
`SkiaSharp` 的 Linux 构建参考主要来自:
76+
77+
- `https://github.com/mono/SkiaSharp/blob/v3.119.2/native/linux-clang-cross/build.cake`
78+
79+
这里保留下来的方法依据主要是 cross clang 的参数组织方式,包括:
80+
81+
- 通过 `--target` 指定目标三元组
82+
- 通过 `-B``-I``-L` 指向工具链根目录
83+
- 在需要时显式传递 `--sysroot`
84+
85+
HostForge 在此基础上统一为:
86+
87+
- 使用宿主 `clang`
88+
- 显式传递 `--sysroot`
89+
- 统一 `CC=clang`
90+
- 统一 `CXX=clang++`
91+
92+
此外,`libfontconfig1-dev` 被视为 Linux 侧构建 `SkiaSharp` 的前置依赖。
93+
94+
## 实际要求
95+
96+
### 1. sysroot 基线
97+
98+
最终选定的目标 sysroot 为:
99+
100+
- `Ubuntu 18.04 bionic`
101+
102+
这套基线用于对齐 `.NET` 当前 Linux host 的兼容范围,并将最终产物控制在 `GLIBC 2.27`
103+
104+
### 2. sysroot 构造要求
105+
106+
构建过程依赖一个可用的 sysroot。用于交叉编译的 sysroot 和一般的 rootfs 的关键区别在于执行 `symlinks` 修复库路径。缺少这一步时,`clang` 在解析库时会沿绝对符号链接回到宿主机,实际问题表现为找不到 `libdl.so.6` 的符号。
107+
108+
### 3. 统一构建链路
109+
110+
最终落地后的 Linux 原生构建链路如下:
111+
112+
- `.NET host` 使用宿主 `clang + sysroot`
113+
- `SkiaSharp` / `HarfBuzz` 使用宿主 `clang + 同一 sysroot`
114+
115+
这保证了最终链接结果使用同一套 ABI 基线。
116+
117+
## 验证方法
118+
119+
方案验证主要依赖以下命令:
120+
121+
```bash
122+
readelf -p .comment singlefilehost
123+
```
124+
125+
```bash
126+
readelf -V singlefilehost | grep -oP 'GLIBC_\d\.\d+' | sort -V | tail -n1
127+
```
128+
129+
验证目标包括:
130+
131+
- `.comment` 中同时出现宿主 `clang` 与目标环境 `gcc` 的信息
132+
- 最高 `GLIBC` 版本保持在 `2.27`
133+
- 构建过程和最终链接过程能够稳定通过
134+
135+
## 总结
136+
137+
HostForge 当前 Linux 交叉编译方案的核心内容如下:
138+
139+
1. 使用现代宿主机上的 `clang` 作为构建工具链。
140+
2. 使用 `Ubuntu 18.04 bionic` sysroot 作为目标环境基线。
141+
3. 依据 `.NET runtime``build-rootfs.sh` 构造 sysroot。
142+
4. 依据 `SkiaSharp` 的 cross clang 参数方式,将 `SkiaSharp` / `HarfBuzz` 并入同一套构建链路。
143+
5. 通过 `.comment``GLIBC_2.27` 检查确认产物 ABI 基线。
144+
145+
这就是 HostForge 当前 Linux 构建方法的形成结果。

0 commit comments

Comments
 (0)