authorgravatar for pat.github@tullmann.orgPat Tullmann <pat.github@tullmann.org> 2023-10-29 14:38:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-04 17:12:07-07:00
logc22d1c00a8825f60e7b01b97c6f73cbc21ca8257
treefb4d555cdb776c4d4aca0e649e299ce6689b8d8a
parent71e809852c34a5a75f86829a188028ec12bbd4ec

src/target: Restrict usable glibc versions

At a minimum required glibc is v2.17, as earlier versions do not define some symbols (e.g., getauxval()) used by the Zig standard library. Additionally, glibc only supports some architectures at more recent versions (e.g., riscv64 support came in glibc v2.27). So add a `glibc_min` field to `available_libcs` for architectures with stronger version requirements. Extend the existing `canBuildLibC` function to check the target against the Zig minimum, and the architecture/os minimum. Also filter the list shown by `zig targets`, too: $ zig targets | jq -c '.glibc' ["2.17.0","2.18.0","2.19.0","2.20.0","2.21.0","2.22.0","2.23.0","2.24.0","2.25.0","2.26.0","2.27.0","2.28.0","2.29.0","2.30.0","2.31.0","2.32.0","2.33.0","2.34.0","2.35.0","2.36.0","2.37.0","2.38.0"] Fixes #17034 Fixes #17769

3 files changed, 25 insertions(+), 7 deletions(-)

src/glibc.zig+1-1
...@@ -20,7 +20,7 @@ pub const Lib = struct {...@@ -20,7 +20,7 @@ pub const Lib = struct {
20};20};
2121
22pub const ABI = struct {22pub const ABI = struct {
23 all_versions: []const Version,23 all_versions: []const Version, // all defined versions (one abilist from v2.0.0 up to current)
24 all_targets: []const target_util.ArchOsAbi,24 all_targets: []const target_util.ArchOsAbi,
25 /// The bytes from the file verbatim, starting from the u16 number25 /// The bytes from the file verbatim, starting from the u16 number
26 /// of function inclusions.26 /// of function inclusions.
src/print_targets.zig+6-3
...@@ -79,9 +79,12 @@ pub fn cmdTargets(...@@ -79,9 +79,12 @@ pub fn cmdTargets(
79 try jws.objectField("glibc");79 try jws.objectField("glibc");
80 try jws.beginArray();80 try jws.beginArray();
81 for (glibc_abi.all_versions) |ver| {81 for (glibc_abi.all_versions) |ver| {
82 const tmp = try std.fmt.allocPrint(allocator, "{}", .{ver});82 // Actual glibc minimum is architecture specific. This just covers the broadest minimum.
83 defer allocator.free(tmp);83 if (ver.order(target.glibc_min_version) != .lt) {
84 try jws.write(tmp);84 const tmp = try std.fmt.allocPrint(allocator, "{}", .{ver});
85 defer allocator.free(tmp);
86 try jws.write(tmp);
87 }
85 }88 }
86 try jws.endArray();89 try jws.endArray();
8790
src/target.zig+18-3
...@@ -11,10 +11,16 @@ pub const ArchOsAbi = struct {...@@ -11,10 +11,16 @@ pub const ArchOsAbi = struct {
11 os: std.Target.Os.Tag,11 os: std.Target.Os.Tag,
12 abi: std.Target.Abi,12 abi: std.Target.Abi,
13 os_ver: ?std.SemanticVersion = null,13 os_ver: ?std.SemanticVersion = null,
14
15 // Minimum glibc version that provides support for the arch/os (for
16 // .abi = .gnu). For most entries, the .glibc_min is null,
17 // meaning the Zig minimum required by the standard library (see
18 // glibc_min_version) is sufficient.
19 glibc_min: ?std.SemanticVersion = null,
14};20};
1521
16pub const available_libcs = [_]ArchOsAbi{22pub const available_libcs = [_]ArchOsAbi{
17 .{ .arch = .aarch64_be, .os = .linux, .abi = .gnu },23 .{ .arch = .aarch64_be, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 17, .patch = 0 } },
18 .{ .arch = .aarch64_be, .os = .linux, .abi = .musl },24 .{ .arch = .aarch64_be, .os = .linux, .abi = .musl },
19 .{ .arch = .aarch64_be, .os = .windows, .abi = .gnu },25 .{ .arch = .aarch64_be, .os = .windows, .abi = .gnu },
20 .{ .arch = .aarch64, .os = .linux, .abi = .gnu },26 .{ .arch = .aarch64, .os = .linux, .abi = .gnu },
...@@ -54,14 +60,14 @@ pub const available_libcs = [_]ArchOsAbi{...@@ -54,14 +60,14 @@ pub const available_libcs = [_]ArchOsAbi{
54 .{ .arch = .mips, .os = .linux, .abi = .gnueabi },60 .{ .arch = .mips, .os = .linux, .abi = .gnueabi },
55 .{ .arch = .mips, .os = .linux, .abi = .gnueabihf },61 .{ .arch = .mips, .os = .linux, .abi = .gnueabihf },
56 .{ .arch = .mips, .os = .linux, .abi = .musl },62 .{ .arch = .mips, .os = .linux, .abi = .musl },
57 .{ .arch = .powerpc64le, .os = .linux, .abi = .gnu },63 .{ .arch = .powerpc64le, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 19, .patch = 0 } },
58 .{ .arch = .powerpc64le, .os = .linux, .abi = .musl },64 .{ .arch = .powerpc64le, .os = .linux, .abi = .musl },
59 .{ .arch = .powerpc64, .os = .linux, .abi = .gnu },65 .{ .arch = .powerpc64, .os = .linux, .abi = .gnu },
60 .{ .arch = .powerpc64, .os = .linux, .abi = .musl },66 .{ .arch = .powerpc64, .os = .linux, .abi = .musl },
61 .{ .arch = .powerpc, .os = .linux, .abi = .gnueabi },67 .{ .arch = .powerpc, .os = .linux, .abi = .gnueabi },
62 .{ .arch = .powerpc, .os = .linux, .abi = .gnueabihf },68 .{ .arch = .powerpc, .os = .linux, .abi = .gnueabihf },
63 .{ .arch = .powerpc, .os = .linux, .abi = .musl },69 .{ .arch = .powerpc, .os = .linux, .abi = .musl },
64 .{ .arch = .riscv64, .os = .linux, .abi = .gnu },70 .{ .arch = .riscv64, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 27, .patch = 0 } },
65 .{ .arch = .riscv64, .os = .linux, .abi = .musl },71 .{ .arch = .riscv64, .os = .linux, .abi = .musl },
66 .{ .arch = .s390x, .os = .linux, .abi = .gnu },72 .{ .arch = .s390x, .os = .linux, .abi = .gnu },
67 .{ .arch = .s390x, .os = .linux, .abi = .musl },73 .{ .arch = .s390x, .os = .linux, .abi = .musl },
...@@ -76,6 +82,9 @@ pub const available_libcs = [_]ArchOsAbi{...@@ -76,6 +82,9 @@ pub const available_libcs = [_]ArchOsAbi{
76 .{ .arch = .x86_64, .os = .macos, .abi = .none, .os_ver = .{ .major = 10, .minor = 7, .patch = 0 } },82 .{ .arch = .x86_64, .os = .macos, .abi = .none, .os_ver = .{ .major = 10, .minor = 7, .patch = 0 } },
77};83};
7884
85/// Minimum glibc version, due to dependencies from the Zig standard library on glibc symbols
86pub const glibc_min_version: std.SemanticVersion = .{ .major = 2, .minor = 17, .patch = 0 };
87
79pub fn libCGenericName(target: std.Target) [:0]const u8 {88pub fn libCGenericName(target: std.Target) [:0]const u8 {
80 switch (target.os.tag) {89 switch (target.os.tag) {
81 .windows => return "mingw",90 .windows => return "mingw",
...@@ -154,6 +163,12 @@ pub fn canBuildLibC(target: std.Target) bool {...@@ -154,6 +163,12 @@ pub fn canBuildLibC(target: std.Target) bool {
154 const ver = target.os.version_range.semver;163 const ver = target.os.version_range.semver;
155 return ver.min.order(libc.os_ver.?) != .lt;164 return ver.min.order(libc.os_ver.?) != .lt;
156 }165 }
166 // Ensure glibc (aka *-linux-gnu) version is supported
167 if ((target.os.tag == .linux) and target.abi.isGnu()) {
168 const min_glibc_ver = libc.glibc_min orelse glibc_min_version;
169 const target_glibc_ver = target.os.version_range.linux.glibc;
170 return target_glibc_ver.order(min_glibc_ver) != .lt;
171 }
157 return true;172 return true;
158 }173 }
159 }174 }