这是一篇关于如何使用 Zig 创建静态链接的 Go 可执行文件并调用 CGO 依赖的短文。完整代码在此仓库中。
- 默认使用 CGO 时生成的可执行文件是动态链接的,常希望静态链接以避免运行时错误。
步骤如下:
- 通过
zig init
创建 zig 库,然后删除src/main.zig
,只保留简单的静态库。 - 修剪
build.zig
为:
const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const lib_mod = b.createModule(.{ .root_source_file = b.path("src/root.zig"), .target = target, .optimize = optimize, }); const lib = b.addLibrary(.{ .linkage =.static, .name = "cgo_static_linking", .root_module = lib_mod, }); b.installArtifact(lib); }
- 在
src/root.zig
中编写使用 C ABI 的简单库函数:
const std = @import("std"); pub export fn my_zig_function() void { std.debug.print("Hello from zig!\n",.{}); }
- 编写对应的 C 头文件
zig_lib.h
:
#pragma once void my_zig_function();
- 构建库:运行
zig build
。 - 编写 Go 程序调用:
package main /* #cgo LDFLAGS: -L./zig-out/lib -lcgo_static_linking -static #include "zig_lib.h" */ import "C" import "fmt" func main() { fmt.Println("starting program") defer fmt.Println("done") C.my_zig_function() }
- 构建 Go 可执行文件并静态链接:使用
CC="zig cc -target x86_64-linux-musl" CGO_ENABLED=1 CGO_LDFLAGS="-static" GOOS=linux GOARCH=amd64 go build -a -ldflags '-extldflags "-static"' main.go
。 - 检查工作:可执行文件不是动态可执行文件,说明静态链接成功。
最后作者表示对当前工具的发展感到感激,Go 和 Zig 都很出色,若觉得有用可向Zig Software Foundation捐赠。
- 通过
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。