authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2023-11-26 02:15:17-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-12 16:17:39-08:00
logf49a8c5431509bdcff75522a31c3ef637e504380
tree0f6b201cbb8a499aa0c6895c441790de8438c9c0
parent63de8a59891f2c342d1a51b808cf04a895ba54d6

std: make c.versionCheck() a comptime-known function


2 files changed, 18 insertions(+), 22 deletions(-)

lib/std/c.zig+14-18
...@@ -5,29 +5,25 @@ const page_size = std.mem.page_size;...@@ -5,29 +5,25 @@ const page_size = std.mem.page_size;
5const iovec = std.os.iovec;5const iovec = std.os.iovec;
6const iovec_const = std.os.iovec_const;6const iovec_const = std.os.iovec_const;
77
8/// The return type is `type` to force comptime function call execution.
9/// TODO: https://github.com/ziglang/zig/issues/425
10/// If not linking libc, returns struct{pub const ok = false;}8/// If not linking libc, returns struct{pub const ok = false;}
11/// If linking musl libc, returns struct{pub const ok = true;}9/// If linking musl libc, returns struct{pub const ok = true;}
12/// If linking gnu libc (glibc), the `ok` value will be true if the target10/// If linking gnu libc (glibc), the `ok` value will be true if the target
13/// version is greater than or equal to `glibc_version`.11/// version is greater than or equal to `glibc_version`.
14/// If linking a libc other than these, returns `false`.12/// If linking a libc other than these, returns `false`.
15pub fn versionCheck(comptime glibc_version: std.SemanticVersion) type {13pub inline fn versionCheck(comptime glibc_version: std.SemanticVersion) bool {
16 return struct {14 return comptime blk: {
17 pub const ok = blk: {15 if (!builtin.link_libc) break :blk false;
18 if (!builtin.link_libc) break :blk false;16 if (builtin.abi.isMusl()) break :blk true;
19 if (builtin.abi.isMusl()) break :blk true;17 if (builtin.target.isGnuLibC()) {
20 if (builtin.target.isGnuLibC()) {18 const ver = builtin.os.version_range.linux.glibc;
21 const ver = builtin.os.version_range.linux.glibc;19 const order = ver.order(glibc_version);
22 const order = ver.order(glibc_version);20 break :blk switch (order) {
23 break :blk switch (order) {21 .gt, .eq => true,
24 .gt, .eq => true,22 .lt => false,
25 .lt => false,23 };
26 };24 } else {
27 } else {25 break :blk false;
28 break :blk false;26 }
29 }
30 };
31 };27 };
32}28}
3329
lib/std/os.zig+4-4
...@@ -483,7 +483,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {...@@ -483,7 +483,7 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
483 if (builtin.os.tag == .linux or builtin.os.tag == .freebsd) {483 if (builtin.os.tag == .linux or builtin.os.tag == .freebsd) {
484 var buf = buffer;484 var buf = buffer;
485 const use_c = builtin.os.tag != .linux or485 const use_c = builtin.os.tag != .linux or
486 std.c.versionCheck(std.SemanticVersion{ .major = 2, .minor = 25, .patch = 0 }).ok;486 std.c.versionCheck(std.SemanticVersion{ .major = 2, .minor = 25, .patch = 0 });
487487
488 while (buf.len != 0) {488 while (buf.len != 0) {
489 const res = if (use_c) blk: {489 const res = if (use_c) blk: {
...@@ -6210,7 +6210,7 @@ pub fn sendfile(...@@ -6210,7 +6210,7 @@ pub fn sendfile(
6210 .linux => sf: {6210 .linux => sf: {
6211 // sendfile() first appeared in Linux 2.2, glibc 2.1.6211 // sendfile() first appeared in Linux 2.2, glibc 2.1.
6212 const call_sf = comptime if (builtin.link_libc)6212 const call_sf = comptime if (builtin.link_libc)
6213 std.c.versionCheck(.{ .major = 2, .minor = 1, .patch = 0 }).ok6213 std.c.versionCheck(.{ .major = 2, .minor = 1, .patch = 0 })
6214 else6214 else
6215 builtin.os.version_range.linux.range.max.order(.{ .major = 2, .minor = 2, .patch = 0 }) != .lt;6215 builtin.os.version_range.linux.range.max.order(.{ .major = 2, .minor = 2, .patch = 0 }) != .lt;
6216 if (!call_sf) break :sf;6216 if (!call_sf) break :sf;
...@@ -6510,7 +6510,7 @@ var has_copy_file_range_syscall = std.atomic.Value(bool).init(true);...@@ -6510,7 +6510,7 @@ var has_copy_file_range_syscall = std.atomic.Value(bool).init(true);
6510pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {6510pub fn copy_file_range(fd_in: fd_t, off_in: u64, fd_out: fd_t, off_out: u64, len: usize, flags: u32) CopyFileRangeError!usize {
6511 if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or6511 if ((comptime builtin.os.isAtLeast(.freebsd, .{ .major = 13, .minor = 0, .patch = 0 }) orelse false) or
6512 ((comptime builtin.os.isAtLeast(.linux, .{ .major = 4, .minor = 5, .patch = 0 }) orelse false and6512 ((comptime builtin.os.isAtLeast(.linux, .{ .major = 4, .minor = 5, .patch = 0 }) orelse false and
6513 std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok) and6513 std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 })) and
6514 has_copy_file_range_syscall.load(.Monotonic)))6514 has_copy_file_range_syscall.load(.Monotonic)))
6515 {6515 {
6516 var off_in_copy = @as(i64, @bitCast(off_in));6516 var off_in_copy = @as(i64, @bitCast(off_in));
...@@ -6829,7 +6829,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {...@@ -6829,7 +6829,7 @@ pub fn memfd_createZ(name: [*:0]const u8, flags: u32) MemFdCreateError!fd_t {
6829 switch (builtin.os.tag) {6829 switch (builtin.os.tag) {
6830 .linux => {6830 .linux => {
6831 // memfd_create is available only in glibc versions starting with 2.27.6831 // memfd_create is available only in glibc versions starting with 2.27.
6832 const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 }).ok;6832 const use_c = std.c.versionCheck(.{ .major = 2, .minor = 27, .patch = 0 });
6833 const sys = if (use_c) std.c else linux;6833 const sys = if (use_c) std.c else linux;
6834 const getErrno = if (use_c) std.c.getErrno else linux.getErrno;6834 const getErrno = if (use_c) std.c.getErrno else linux.getErrno;
6835 const rc = sys.memfd_create(name, flags);6835 const rc = sys.memfd_create(name, flags);