I have a program written in Zig, but the system where it will run don't have a Zig compiler.
I export the program to C code (via the ofmt = c
feature) then compile it with either gcc or clang.
Which worked well, until I used floats.
I have the following error:
undefined reference to `__floatundisf'
undefined reference to `__floatundidf'
undefined reference to `__fixdfsi'
undefined reference to `__floatsidf'
undefined reference to `__fixunsdfsi'
undefined reference to `__floatunsidf'
After investigation, those functions are meant to replace assemble instructions in case floats operations are not available on the targeted CPU.
Interestingly, when compiling with Zig's C compiler (zig cc
), it works. But both gcc (13.2.1) and clang (16.0.6) fail to provide implementation during linking. I tried to link against different libraries like libc, libm and libgcc, which the latest, is supposed to provide them.
Here is my 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);
By running
zig cc
with the--verbose
option, it gives the linker (ld
) invocation:Skipping all the uninteresting parts, one argument is important. Zig ships a bunch of functions in a library called
libcompiler_rt
.The sources of the library are in
zig/lib/compiler_rt.zig
and the folder of the same name. To produce a portable C code export of this library, compile it with:Now you can compile the program with: