开始使用
构建管线
跟踪 C 源码如何经过 Clang、C2Go LTO、绑定生成器和 Go 工具链。维护者C2Go contributorsC2Go 把编译和 package 生成拆成两个阶段。理解这个边界,会让构建失败更容易定位。
阶段一:C 前端与 LLVM bitcode
c2go-clang 在启用 C2Go 语言扩展后解析 C。target triple 同时控制机器代码和 C data model,例如 long 在 Linux 与 Darwin 上为 8 字节,而在 64 位 Windows 上为 4 字节。
普通 -fc2go -c 会停在 pre-link LLVM bitcode,并为兼容构建系统把文件命名为 .o。直接请求 Plan 9 汇编或 manifest 时,driver 会把相同的逐源码 bitcode 立即交给同一 bin/ 目录中的 c2go-lto。
阶段二:C2Go LTO
c2go-lto 链接一个或多个 bitcode module,并运行 C2Go lowering 管线。跨 translation unit 内联、逃逸审计、Go 栈处理、GC statepoint、写屏障、ABI lowering 和最终 Plan 9 输出,都在这里统一协调。
即使只输入一个源文件,只要指定 emit flag,driver 内部也会经过这条路径:
cc1 → LLVM bitcode → c2go-lto → output.s + output.json
-O0 和 -O2 都受支持。-O0 保留以 GoABI0 栈传参数为主的简单路径,并跳过 -O2 才启用的跨单元内联、statepoint GC 与叶子 internal-ABI 优化;返回值 ABI 仍会跨优化级别保持一致。
在当前版本里,普通 driver 会以 nonfatal 模式运行内部逃逸审计,并抑制报告;这不是发布安全门禁。必须为所有 translation unit 生成审计 bitcode,并按栈指针逃逸安全中的流程单独运行 c2go-lto。
阶段三:由 manifest 指导绑定
只有汇编还不够。JSON manifest 保存了 Go 源码生成器无法可靠地从文本汇编恢复的信息,包括:
- Go import path 与导出符号名称;
- 目标
GOOS和GOARCH; - 最低 Go 版本、验证快照、C2Go ABI epoch 与 Go toolchain contract epoch;
- record 布局、字段与 GC pointer mask;
- Go linkname 与多返回值;
- 原生导入、动态库、回调和 callout。
c2go-bind 会先验证所有输入彼此一致,再写入文件。target、contract epoch、符号、类型或回调元数据发生冲突时会直接拒绝生成。各版本字段的含义见版本与兼容性。
阶段四:普通 Go 构建
生成目录就是普通 Go package,其中包含 Go 声明、带目标选择的汇编、runtime anchor,以及需要的动态导入胶水。Go 工具链将这些文件与固定版本的 c2go-libc module 一起汇编、链接。
应用启动时不会再调用 C 编译器。
必须保持一致的值
| 值 | 为什么必须匹配 |
|---|---|
-fc2go-package |
最终 Go import path 的唯一来源;也用于识别同包 linkname,并随 manifest 传给 binder |
| 汇编与 manifest | 它们描述同一个编译单元 |
| target triple 与 Go build target | Plan 9 汇编与 OS/架构绑定 |
| compiler、binder 与 libc 版本 | manifest 和 runtime ABI 会协同版本化 |
| Go 工具链版本 | 生成阶段会检查栈帧和 ABI 契约 |
有用的检查点
构建失败时,先保留 .s 与 .json 文件对。调试生成 Go 代码前,检查 manifest 中的 package path、target 与 ABI 版本。可以用 c2go-bind --dry-run 在不修改输出目录的情况下检查 Go 输出;直接诊断编译管线时使用 c2go-lto --c2go-print-stats。
c2go-bind 默认从 manifest pkgpath 的末段推导 Go package 名。只有两者确实不同时才传 --pkgname,例如 import path 为 github.com/c2gohq/c2go_libc、源码声明为 package libc。
下一章先把一个 C API 导出给 Go。从手工命令迁移到项目构建时,使用 Makefile 与 CMake 接入指南。