Open Ogromny opened 1 week ago
Please try this with a nightly build from https://ziglang.org/download as there have been multiple changes to std.Target.DynamicLinker
in master.
Please try this with a nightly build from https://ziglang.org/download as there have been multiple changes to
std.Target.DynamicLinker
in master.
Unfortunately I get the same issue with the latest nightly build
I guess it's similar reason as in https://github.com/ziglang/zig/issues/21941#issuecomment-2481272623 :
Yes, because it checks /usr/bin/env or its interpreter (/usr/bin/coreutils, /bin/sh) to find out libc, and if you compile it statically, it would assume that whole system is static -> musl needed.
In kiss-chroot-24.06.14-2
:
$ file usr/bin/env
usr/bin/env: symbolic link to busybox
$ file usr/bin/busybox
usr/bin/busybox: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
$ file usr/bin/x86_64-pc-linux-musl-gcc
usr/bin/x86_64-pc-linux-musl-gcc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, stripped
So if you start zig build-exe --show-builtin
:
pub const abi = std.Target.Abi.musl;
// ...
pub const os = std.Target.Os{
.tag = .linux,
.version_range = .{ .linux = .{
.range = .{
.min = .{
.major = 6,
.minor = 11,
.patch = 5,
},
.max = .{
.major = 6,
.minor = 11,
.patch = 5,
},
},
.glibc = .{
.major = 2,
.minor = 28,
.patch = 0,
},
}},
};
pub const target: std.Target = .{
.cpu = cpu,
.os = os,
.abi = abi,
.ofmt = object_format,
.dynamic_linker = std.Target.DynamicLinker.none,
};
But if I replace env
with x86_64-pc-linux-musl-gcc
, this part changes:
pub const target: std.Target = .{
.cpu = cpu,
.os = os,
.abi = abi,
.ofmt = object_format,
.dynamic_linker = std.Target.DynamicLinker.init("/lib/ld-musl-x86_64.so.1"),
};
I assume result above is what you want?
I guess it's similar reason as in #21941 (comment) :
Yes, because it checks /usr/bin/env or its interpreter (/usr/bin/coreutils, /bin/sh) to find out libc, and if you compile it statically, it would assume that whole system is static -> musl needed.
In
kiss-chroot-24.06.14-2
:$ file usr/bin/env usr/bin/env: symbolic link to busybox $ file usr/bin/busybox usr/bin/busybox: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped $ file usr/bin/x86_64-pc-linux-musl-gcc usr/bin/x86_64-pc-linux-musl-gcc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-x86_64.so.1, stripped
So if you start
zig build-exe --show-builtin
:pub const abi = std.Target.Abi.musl; // ... pub const os = std.Target.Os{ .tag = .linux, .version_range = .{ .linux = .{ .range = .{ .min = .{ .major = 6, .minor = 11, .patch = 5, }, .max = .{ .major = 6, .minor = 11, .patch = 5, }, }, .glibc = .{ .major = 2, .minor = 28, .patch = 0, }, }}, }; pub const target: std.Target = .{ .cpu = cpu, .os = os, .abi = abi, .ofmt = object_format, .dynamic_linker = std.Target.DynamicLinker.none, };
But if I replace
env
withx86_64-pc-linux-musl-gcc
, this part changes:pub const target: std.Target = .{ .cpu = cpu, .os = os, .abi = abi, .ofmt = object_format, .dynamic_linker = std.Target.DynamicLinker.init("/lib/ld-musl-x86_64.so.1"), };
I assume result above is what you want?
Yes, this is exactly what I want, a workaround for this issue is to simply manually set the dynamic_linker
as you shown in the build.zig
like this:
const std = @import("std");
pub fn build(b: *std.Build) void {
b.host.query.dynamic_linker = std.Target.DynamicLinker.init("/usr/lib/ld-musl-x86_64.so.1");
const exe = b.addExecutable(.{
.name = "hello",
.root_source_file = b.path("main.zig"),
.target = b.host,
.optimize = .Debug,
});
exe.linkLibC();
b.installArtifact(exe);
}
Yes, this is exactly what I want, a workaround for this issue is to simply manually set the
dynamic_linker
as you shown in thebuild.zig
like this:
As an easier alternative, you can pass zig build -Ddynamic-linker=/usr/lib/...
in projects that use b.standardTargetOptions
in their build.zig, same way as you passed --dynamic-linker /usr/lib/ld-musl-x86_64.so.1
in zig build-exe
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
On KissLinux:
pub fn main() !void { _ = c.puts("hello"); }
gdb output
After digging a little bit I realized that the linking stage was failing but still outputs the executable:
By taking the exact build command and removing the
listen=-
argument and adding--dynamic-linker /usr/lib/ld-musl-x86_64.so.1
the executable get successfully linked and works as expectedWhat can be the cause of this issue ?
Expected Behavior
The executable gets linked successfully