diff --git a/src/glibc.zig b/src/glibc.zig index d4b6174021..b7483b7012 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -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. diff --git a/src/print_targets.zig b/src/print_targets.zig index bfb2ac0177..f8390a03b9 100644 --- a/src/print_targets.zig +++ b/src/print_targets.zig @@ -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(); diff --git a/src/target.zig b/src/target.zig index 5ae5c420c2..acfa089034 100644 --- a/src/target.zig +++ b/src/target.zig @@ -11,10 +11,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 }, @@ -54,14 +60,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 }, @@ -76,6 +82,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", @@ -154,6 +163,12 @@ pub fn canBuildLibC(target: std.Target) bool { const ver = target.os.version_range.semver; return ver.min.order(libc.os_ver.?) != .lt; } + // Ensure glibc (aka *-linux-gnu) version is supported + if ((target.os.tag == .linux) and target.abi.isGnu()) { + 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; } }