C code generated by Zig fails link stage due to missing functions (soft-float)

194 Views Asked by At

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);
1

There are 1 best solutions below

0
On

By running zig cc with the --verbose option, it gives the linker (ld) invocation:

ld ... libcompiler_rt.a ...

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:

zig build-obj -ofmt=c compiler_rt.zig

Now you can compile the program with:

gcc main.zig.c compiler_rt.c