我有一个用 Zig 编写的程序,但运行该程序的系统没有 Zig 编译器。
我将程序导出为 C 代码(通过
ofmt = c
功能),然后使用 gcc 或 clang 进行编译。
效果很好,直到我使用了浮子。
我有以下错误:
undefined reference to `__floatundisf'
undefined reference to `__floatundidf'
undefined reference to `__fixdfsi'
undefined reference to `__floatsidf'
undefined reference to `__fixunsdfsi'
undefined reference to `__floatunsidf'
经过调查,这些函数旨在替换汇编指令,以防浮点操作在目标 CPU 上不可用。
有趣的是,当用 Zig 的 C 编译器(
zig cc
)编译时,它可以工作。但是 gcc (13.2.1) 和 clang (16.0.6) 都无法在链接期间提供实现。我尝试链接不同的库,如 libc、libm 和 libgcc,最新的应该提供它们。
这是我的
build.zig
:
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "zigc",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
const c_source = b.addStaticLibrary(.{
.name = "zigc",
.root_source_file = .{ .path = "src/main-c.zig" },
.target = .{ .ofmt = .c },
.optimize = optimize,
});
const c_export = b.addInstallArtifact(c_source, .{});
const export_step = b.step("cc", "Export to C code");
export_step.dependOn(&c_export.step);
通过使用
zig cc
选项运行 --verbose
,它会给出链接器 (ld
) 调用:
ld ... libcompiler_rt.a ...
跳过所有无趣的部分,一个论点很重要。 Zig 在名为
libcompiler_rt
的库中提供了一堆函数。
库的来源位于
zig/lib/compiler_rt.zig
和同名文件夹中。要生成此库的可移植 C 代码导出,请使用以下命令进行编译:
zig build-obj -ofmt=c compiler_rt.zig
现在您可以使用以下命令编译程序:
gcc main.zig.c compiler_rt.c