Invalid ELF header when targeting Linux specifically

Today I noticed that I would get an “invalid ELF header” error if I compile a library with -Dtarget=x86_64-linux. Using the flag -Dtarget=x86_64-native creates the correct result.

The “native” ELF file has an extra section .gnu.version. I guess that’s required on certain Linux distros. In a cross-compiling scenario, how does one ensure that a library would work on popular distros like Debian?

x86_64-linux is x86_64-linux-musl.

> zig build-exe --show-builtin -target x86_64-linux > 1.txt
> zig build-exe --show-builtin -target x86_64-linux-gnu > 2.txt
> diff -u 1.txt 2.txt
 pub const link_mode = std.builtin.LinkMode.Static;
 pub const is_test = false;
 pub const single_threaded = false;
-pub const abi = std.Target.Abi.musl;
+pub const abi = std.Target.Abi.gnu;
 pub const cpu: std.Target.Cpu = .{
     .arch = .x86_64,
     .model = &std.Target.x86.cpu.x86_64,

     .os = os,
     .abi = abi,
     .ofmt = object_format,
-    .dynamic_linker = std.Target.DynamicLinker.init("/lib/ld-musl-x86_64.so.1"),
+    .dynamic_linker = std.Target.DynamicLinker.init("/lib64/ld-linux-x86-64.so.2"),
 };
 pub const object_format = std.Target.ObjectFormat.elf;
 pub const mode = std.builtin.OptimizeMode.Debug;

If you have a dynamic library and you want to target debian use x86_64-linux-gnu.

3 Likes

Thanks for the explanation!

1 Like

I wasn’t aware of --show-builtin that is a nice feature!

1 Like