第二部分 · 7 / 7
跨平台 stub
RDMA 只在 Linux + cgo + 有库的环境才真正可用。但 gordma 用 Go 的构建标签做了优雅处理:
代码在 macOS / Windows / CGO_ENABLED=0 下也能编译、跑单元测试,只是 RDMA 调用返回
ErrNotSupported 而非崩溃。
怎么做到的
同一个 API,按平台编译不同实现文件:
| 文件 | 构建标签 | 内容 |
|---|---|---|
*_linux.go | //go:build linux && cgo | 真实实现,cgo 调 libibverbs/librdmacm |
*_stub.go | //go:build !linux || !cgo | 桩实现,所有入口返回 ErrNotSupported |
关键
两种构建导出完全相同的 API——类型签名、方法名、错误一致。
所以引用 gordma 的代码在任何平台都能编译通过,行为差异只在运行时。
各平台编译
go build ./... # Linux 真实 / macOS 桩
GOOS=darwin GOARCH=arm64 go build ./... # 桩
GOOS=windows GOARCH=amd64 go build ./... # 桩
CGO_ENABLED=0 go build ./... # 即便在 Linux 也走桩
运行时判断
用 gordma.Supported() 判断当前 build 能否真正跑 RDMA(来自 doc.go):
if !gordma.Supported() {
log.Fatal("RDMA not supported on this platform")
}
// 它只在 Linux + cgo 构建里返回 true
examples 就是这么做的:在不支持的平台打印
RDMA not supported on this platform 然后干净退出,而不是 panic。
handshake 包:纯 Go,处处可测
值得单独一提:handshake 包完全没有 cgo,因为它做的只是 TCP 上交换 JSON。
这意味着握手逻辑能在 macOS 上写单元测试、被 CI 在任意平台覆盖,与 RDMA 硬件解耦。
为什么这样设计
价值
- 开发者在 MacBook 上就能写代码、跑单测、用 IDE 跳转,不必随时连着一台带网卡的 Linux。
- CI 能在普通 runner 上做编译检查、跨平台交叉编译、与硬件无关的单元测试。
- 硬件相关的集成测试被单独隔离,只在有 RDMA NIC 的专用机器上跑。
- 整体大幅降低了贡献门槛。
这套约定(*_linux.go / *_stub.go 配对)贯穿根包和 rdmanet 子包,
看代码时遇到成对文件就知道是这个模式。
下一步
库讲完了。进入 第三部分,看能直接跑的 cmd 性能工具与 examples 示例。
gordma 教程