diff options
author | Eric Joldasov <bratishkaerik@getgoogleoff.me> | 2023-10-10 09:12:16 +0600 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2023-10-27 03:53:03 +0100 |
commit | 42ac667416fe133255c3baca620e9af61315cb3b (patch) | |
tree | 5ef97d8f5e583f982e7940600cb6ff7b8c27e98a | |
parent | toolchain.eclass: add -fno-harden-control-flow-redundancy to old-compiler fil... (diff) | |
download | gentoo-42ac667416fe133255c3baca620e9af61315cb3b.tar.gz gentoo-42ac667416fe133255c3baca620e9af61315cb3b.tar.bz2 gentoo-42ac667416fe133255c3baca620e9af61315cb3b.zip |
dev-lang/zig: patch 0.11.0 to use getconf when detecting glibc version
Bug: https://bugs.gentoo.org/914731
Bug: https://bugs.gentoo.org/914101
Signed-off-by: Eric Joldasov <bratishkaerik@getgoogleoff.me>
Signed-off-by: Sam James <sam@gentoo.org>
-rw-r--r-- | dev-lang/zig/files/zig-0.11.0-first-try-getconf.patch | 109 | ||||
-rw-r--r-- | dev-lang/zig/zig-0.11.0-r1.ebuild (renamed from dev-lang/zig/zig-0.11.0.ebuild) | 4 |
2 files changed, 113 insertions, 0 deletions
diff --git a/dev-lang/zig/files/zig-0.11.0-first-try-getconf.patch b/dev-lang/zig/files/zig-0.11.0-first-try-getconf.patch new file mode 100644 index 000000000000..6d1b3ca7e5b7 --- /dev/null +++ b/dev-lang/zig/files/zig-0.11.0-first-try-getconf.patch @@ -0,0 +1,109 @@ +From: Eric Joldasov <bratishkaerik@getgoogleoff.me> + +Based on https://github.com/ziglang/zig/pull/12567 and https://github.com/ziglang/zig/pull/17671 +with small fixes, all ported to 0.11.0. + +First try `getconf GNU_LIBC_VERSION` to detect glibc version, +If there are any errors, skip to the upstream logic. + +Also fix glibc version parsing: if version string does not contain third (patch) component, "std.SemanticVersion.parse" returns parsing error. +For example, this currently happens with "GLIBC_2.37" or "glibc 2.37" inputs. +To fix this, we use copy-pasted "std.zig.CrossTarget.parse" function here, that sets omitted patch component to 0. + +After applying this patch, both `zig build-exe --show-builtin` and `zig env` show correct version on my default/linux/amd64/17.1/desktop/plasma : +glibc 2.37. + +Bug: https://bugs.gentoo.org/914731 +Bug: https://bugs.gentoo.org/914101 + +diff --git a/lib/std/zig/system/NativeTargetInfo.zig b/lib/std/zig/system/NativeTargetInfo.zig +index 99a1a8f2e..d1032a716 100644 +--- a/lib/std/zig/system/NativeTargetInfo.zig ++++ b/lib/std/zig/system/NativeTargetInfo.zig +@@ -19,6 +19,32 @@ dynamic_linker: DynamicLinker = DynamicLinker{}, + + pub const DynamicLinker = Target.DynamicLinker; + ++// Copy-pasted from `std.zig.CrossTarget.parse` to avoid changing visibility of mentioned function. ++/// Parses a version with an omitted patch component, such as "1.0", ++/// which SemanticVersion.parse is not capable of. ++fn parseWithOptionalPatchField(ver: []const u8) error{ InvalidVersion, Overflow }!std.SemanticVersion { ++ const parseVersionComponent = struct { ++ fn parseVersionComponent(component: []const u8) !usize { ++ return std.fmt.parseUnsigned(usize, component, 10) catch |err| { ++ switch (err) { ++ error.InvalidCharacter => return error.InvalidVersion, ++ error.Overflow => return error.Overflow, ++ } ++ }; ++ } ++ }.parseVersionComponent; ++ var version_components = mem.split(u8, ver, "."); ++ const major = version_components.first(); ++ const minor = version_components.next() orelse return error.InvalidVersion; ++ const patch = version_components.next() orelse "0"; ++ if (version_components.next() != null) return error.InvalidVersion; ++ return .{ ++ .major = try parseVersionComponent(major), ++ .minor = try parseVersionComponent(minor), ++ .patch = try parseVersionComponent(patch), ++ }; ++} ++ + pub const DetectError = error{ + FileSystem, + SystemResources, +@@ -307,6 +333,35 @@ fn detectAbiAndDynamicLinker( + } + const ld_info_list = ld_info_list_buffer[0..ld_info_list_len]; + ++ if (is_linux and !os_is_non_native and cross_target.glibc_version == null) try_getconf: { ++ var buf: [4096]u8 = undefined; ++ var fba = std.heap.FixedBufferAllocator.init(&buf); ++ const allocator = fba.allocator(); ++ ++ const getconf = std.process.Child.exec(.{ ++ .allocator = allocator, ++ .argv = &.{ "getconf", "GNU_LIBC_VERSION" }, ++ .max_output_bytes = 1024, ++ }) catch break :try_getconf; ++ if (!std.mem.startsWith(u8, getconf.stdout, "glibc ")) break :try_getconf; ++ const version_string = getconf.stdout["glibc ".len..]; ++ const glibc_version = parseWithOptionalPatchField(version_string) catch break :try_getconf; ++ ++ var os_with_glibc = os; ++ os_with_glibc.version_range.linux.glibc = glibc_version; ++ ++ const result: NativeTargetInfo = .{ ++ .target = .{ ++ .cpu = cpu, ++ .os = os_with_glibc, ++ .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os_with_glibc), ++ .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os_with_glibc.tag, cpu.arch), ++ }, ++ .dynamic_linker = cross_target.dynamic_linker, ++ }; ++ return result; ++ } ++ + // Best case scenario: the executable is dynamically linked, and we can iterate + // over our own shared objects and find a dynamic linker. + const elf_file = blk: { +@@ -563,7 +618,7 @@ fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion { + while (it.next()) |s| { + if (mem.startsWith(u8, s, "GLIBC_2.")) { + const chopped = s["GLIBC_".len..]; +- const ver = std.SemanticVersion.parse(chopped) catch |err| switch (err) { ++ const ver = parseWithOptionalPatchField(chopped) catch |err| switch (err) { + error.Overflow => return error.InvalidGnuLibCVersion, + error.InvalidVersion => return error.InvalidGnuLibCVersion, + }; +@@ -586,7 +641,7 @@ fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) !std.Semantic + } + // chop off "libc-" and ".so" + const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len]; +- return std.SemanticVersion.parse(link_name_chopped) catch |err| switch (err) { ++ return parseWithOptionalPatchField(link_name_chopped) catch |err| switch (err) { + error.Overflow => return error.InvalidGnuLibCVersion, + error.InvalidVersion => return error.InvalidGnuLibCVersion, + }; diff --git a/dev-lang/zig/zig-0.11.0.ebuild b/dev-lang/zig/zig-0.11.0-r1.ebuild index 1644ef100c5c..0984f904d28c 100644 --- a/dev-lang/zig/zig-0.11.0.ebuild +++ b/dev-lang/zig/zig-0.11.0-r1.ebuild @@ -58,6 +58,10 @@ QA_FLAGS_IGNORED="usr/.*/zig/${PV}/bin/zig" # Zig uses self-hosted compiler only CHECKREQS_MEMORY="4G" +PATCHES=( + "${FILESDIR}/zig-0.11.0-first-try-getconf.patch" +) + llvm_check_deps() { has_version "sys-devel/clang:${LLVM_SLOT}" } |