Skip to content

Commit

Permalink
src/target: Restrict usable glibc versions
Browse files Browse the repository at this point in the history
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 ziglang#17034
Fixes ziglang#17769
  • Loading branch information
rootbeer committed Nov 29, 2023
1 parent b73c725 commit 621100d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/glibc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub const Lib = struct {
};

pub const ABI = struct {
all_versions: []const Version,
all_versions: []const Version, // all defined versions (one abilist from v2.0.0 up to current)
all_targets: []const target_util.ArchOsAbi,
/// The bytes from the file verbatim, starting from the u16 number
/// of function inclusions.
Expand Down
9 changes: 6 additions & 3 deletions src/print_targets.zig
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,12 @@ pub fn cmdTargets(
try jws.objectField("glibc");
try jws.beginArray();
for (glibc_abi.all_versions) |ver| {
const tmp = try std.fmt.allocPrint(allocator, "{}", .{ver});
defer allocator.free(tmp);
try jws.write(tmp);
// Actual glibc minimum is architecture specific. This just covers the broadest minimum.
if (ver.order(target.glibc_min_version) != .lt) {
const tmp = try std.fmt.allocPrint(allocator, "{}", .{ver});
defer allocator.free(tmp);
try jws.write(tmp);
}
}
try jws.endArray();

Expand Down
25 changes: 22 additions & 3 deletions src/target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ pub const ArchOsAbi = struct {
os: std.Target.Os.Tag,
abi: std.Target.Abi,
os_ver: ?std.SemanticVersion = null,

// Minimum glibc version that provides support for the arch/os (for
// .abi = .gnu). For most entries, the .glibc_min is null,
// meaning the Zig minimum required by the standard library (see
// glibc_min_version) is sufficient.
glibc_min: ?std.SemanticVersion = null,
};

pub const available_libcs = [_]ArchOsAbi{
.{ .arch = .aarch64_be, .os = .linux, .abi = .gnu },
.{ .arch = .aarch64_be, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 17, .patch = 0 } },
.{ .arch = .aarch64_be, .os = .linux, .abi = .musl },
.{ .arch = .aarch64_be, .os = .windows, .abi = .gnu },
.{ .arch = .aarch64, .os = .linux, .abi = .gnu },
Expand Down Expand Up @@ -51,14 +57,14 @@ pub const available_libcs = [_]ArchOsAbi{
.{ .arch = .mips, .os = .linux, .abi = .gnueabi },
.{ .arch = .mips, .os = .linux, .abi = .gnueabihf },
.{ .arch = .mips, .os = .linux, .abi = .musl },
.{ .arch = .powerpc64le, .os = .linux, .abi = .gnu },
.{ .arch = .powerpc64le, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 19, .patch = 0 } },
.{ .arch = .powerpc64le, .os = .linux, .abi = .musl },
.{ .arch = .powerpc64, .os = .linux, .abi = .gnu },
.{ .arch = .powerpc64, .os = .linux, .abi = .musl },
.{ .arch = .powerpc, .os = .linux, .abi = .gnueabi },
.{ .arch = .powerpc, .os = .linux, .abi = .gnueabihf },
.{ .arch = .powerpc, .os = .linux, .abi = .musl },
.{ .arch = .riscv64, .os = .linux, .abi = .gnu },
.{ .arch = .riscv64, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 27, .patch = 0 } },
.{ .arch = .riscv64, .os = .linux, .abi = .musl },
.{ .arch = .s390x, .os = .linux, .abi = .gnu },
.{ .arch = .s390x, .os = .linux, .abi = .musl },
Expand All @@ -73,6 +79,9 @@ pub const available_libcs = [_]ArchOsAbi{
.{ .arch = .x86_64, .os = .macos, .abi = .none, .os_ver = .{ .major = 10, .minor = 7, .patch = 0 } },
};

/// Minimum glibc version, due to dependencies from the Zig standard library on glibc symbols
pub const glibc_min_version: std.SemanticVersion = .{ .major = 2, .minor = 17, .patch = 0 };

pub fn libCGenericName(target: std.Target) [:0]const u8 {
switch (target.os.tag) {
.windows => return "mingw",
Expand Down Expand Up @@ -151,6 +160,16 @@ pub fn canBuildLibC(target: std.Target) bool {
const ver = target.os.version_range.semver;
return ver.min.order(libc.os_ver.?) != .lt;
}
// Ensure target glibc version is supported
if (target.abi.isGnu()) {
if (target.os.tag != .linux) { // Zig only supports glibc on Linux
return false;
}

const min_glibc_ver = libc.glibc_min orelse glibc_min_version;
const target_glibc_ver = target.os.version_range.linux.glibc;
return target_glibc_ver.order(min_glibc_ver) != .lt;
}
return true;
}
}
Expand Down

0 comments on commit 621100d

Please sign in to comment.