Cross compiling zig for Kobo Ereaders

Long story short

When ( cross compiling zig code to kobo ereader and if I use .link_libc = true or exe.linkLibC();, then when I run it (the program) I get a Segmentation fault error message.

Short story long

I was trying to write a program in zig for Kobo Ereader.

When cross compiled and dependent only on zig’'s std library everything worked fine, but each time I tried to include a lib written in c called FBInk, and run the successfully compiled program I got an Segmentation fault message.

Because I don’t have access to gdb or ldd on the target platform I tried cutting down this program to the point where I know that even if I were to not call any external c function (i.e. using printf from stdio lib), but I were to use exe.linkLibC(); I would get an Segmentation fault error while running.

I had tried multiple thing eg. dynamic vs static including that library mentioned before but nothing had worked.

I was even able by using the same target to cross compile a simple c program and run it without any issue.

Platform Info

Surprisingly Kobo Ereaders are using Linux under the hood, which is quite open for any hacking opportunities - not like Kindle.

$ uname -a
Linux kobo 4.9.77 #1 SMP PREEMPT d226bc7bf-20250103T160218-B0103160930 armv7l GNU/Linux

$ ls /lib/libc-*.so 
/lib/libc-2.11.1.so

Source Code

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.resolveTargetQuery(.{
        .os_tag = .linux,
        .cpu_arch = .arm,
        .cpu_model = .{ 
            .explicit = &std.Target.arm.cpu.cortex_a55,
        },
        .abi = .gnueabihf,
        .glibc_version = .{ 
            //.major = 2,
            //.minor = 11,
            //.patch = 1,
            .major = 2,
            .minor = 16,
            .patch = 0
        }
    });

    const optimize = b.standardOptimizeOption(.{});

    const rebend = b.addExecutable(.{
        .name = "rebend",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    rebend.linkLibC(); // Results in Segfault 
   

    b.installArtifact(rebend);

    const rebend_c = b.addExecutable(.{
        .name = "rebend-c",
        .target = target,
        .optimize = optimize,
    });

    rebend_c.addCSourceFiles(.{
        .root = b.path("src"),
        .files = &.{
            "main.c"
        },
    });

    rebend_c.linkLibC();

    b.installArtifact(rebend_c);
}

src/main.zig

const std = @import("std");

pub fn main() !void {
    std.debug.print("Help World\n", .{});
}

src/main.c

#include <stdio.h>

int main() {
  printf("Hello World\n");

  return 0;
} 

Run

[root@kobo reband]# ./rebend 
Segmentation fault
[root@kobo reband]# ./rebend-c
Hello World

Is it possible these libc versions are just too old? 2.11.1 was released in late 2009. My apologies if this question is a red herring.

zig has a minimum Linux kernel/libc it supports (which I don’t know offhand}.

That’s what I was thinking…

Have you tried creating a static executable using musl as your libc? I see that you mention static vs dynamic, but it’s unclear to me if you’re talking about the libc or the other C library you’re using.

1 Like

Not to hijack the thread but I was also experimenting yesterday with compiling my game (written in Zig with just the zig stdlib, no external libs) for Windows 7 (and I would like Windows XP support as well) and I was getting an Entry point not found issue. I did find a PR somewhere mentioning minimum supported version is Windows 8. But given this e-reader issue may be falling into the same category of problems, I’m gonna see if your musl/static binary recommendation might work for my use case as well.

Yes the oldest supported version of glibc is 2.16.0 where I target 2.11.1, but
it doesn’t explain why my c code worked while compiled with the same target and that if not used newer features of glibc everything should had worked (i.e. glibc is backward compatible in most regards)

No, but I will try it out - I have forgotten that I can static link musl libc, thought I’m not sure if it would work on a platform that uses primarily glibc.

Originally I was trying to use external c library via zig, but I was always getting Segfault error no matter I that library was linked static or dynamic.

Thx, but I never had got this entry point not found issue, but like written before I will try out this musl static linking stuff.