From c4504e64ad24ee335dbb5cd06322f890ab95a07e Mon Sep 17 00:00:00 2001 From: Jan200101 Date: Mon, 19 Jul 2021 22:38:11 +0200 Subject: [PATCH] add native libc detection patch this fixes an issue where setting CC to `zig cc` could cause a recursive call and cause failures during linkage. --- ...tection-respect-spaces-in-CC-env-var.patch | 192 ++++++++++++++++++ zig.spec | 8 +- 2 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 0003-native-libc-detection-respect-spaces-in-CC-env-var.patch diff --git a/0003-native-libc-detection-respect-spaces-in-CC-env-var.patch b/0003-native-libc-detection-respect-spaces-in-CC-env-var.patch new file mode 100644 index 0000000..17239ec --- /dev/null +++ b/0003-native-libc-detection-respect-spaces-in-CC-env-var.patch @@ -0,0 +1,192 @@ +From 7c6f80f74395e546382c0400ef6db50c1b3e6439 Mon Sep 17 00:00:00 2001 +From: Andrew Kelley +Date: Tue, 8 Jun 2021 12:48:48 -0700 +Subject: [PATCH] native libc detection: respect spaces in CC env var + +Zig has detection for when it is accidentally being called recursively +when trying to find the native libc installation. However it was not +working, resulting in a cryptic failure, because zig tried to execute +a command which had spaces in it rather than tokenizing it. + +This improves the user experience of `zig cc` for systems that Zig +does not support cross-compiling for. + +Closes #8960 + +Signed-off-by: Jan200101 +--- + src/libc_installation.zig | 99 +++++++++++++++++++++++++++------------ + 1 file changed, 70 insertions(+), 29 deletions(-) + +diff --git a/src/libc_installation.zig b/src/libc_installation.zig +index 2286b2c85..783f76b9b 100644 +--- a/src/libc_installation.zig ++++ b/src/libc_installation.zig +@@ -237,26 +237,38 @@ pub const LibCInstallation = struct { + + fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void { + const allocator = args.allocator; ++ ++ // Detect infinite loops. ++ var env_map = try std.process.getEnvMap(allocator); ++ defer env_map.deinit(); ++ const skip_cc_env_var = if (env_map.get(inf_loop_env_key)) |phase| blk: { ++ if (std.mem.eql(u8, phase, "1")) { ++ try env_map.put(inf_loop_env_key, "2"); ++ break :blk true; ++ } else { ++ return error.ZigIsTheCCompiler; ++ } ++ } else blk: { ++ try env_map.put(inf_loop_env_key, "1"); ++ break :blk false; ++ }; ++ + const dev_null = if (is_windows) "nul" else "/dev/null"; +- const cc_exe = std.os.getenvZ("CC") orelse default_cc_exe; +- const argv = [_][]const u8{ +- cc_exe, ++ ++ var argv = std.ArrayList([]const u8).init(allocator); ++ defer argv.deinit(); ++ ++ try appendCcExe(&argv, skip_cc_env_var); ++ try argv.appendSlice(&.{ + "-E", + "-Wp,-v", + "-xc", + dev_null, +- }; +- var env_map = try std.process.getEnvMap(allocator); +- defer env_map.deinit(); +- +- // Detect infinite loops. +- const inf_loop_env_key = "ZIG_IS_DETECTING_LIBC_PATHS"; +- if (env_map.get(inf_loop_env_key) != null) return error.ZigIsTheCCompiler; +- try env_map.put(inf_loop_env_key, "1"); ++ }); + + const exec_res = std.ChildProcess.exec(.{ + .allocator = allocator, +- .argv = &argv, ++ .argv = argv.items, + .max_output_bytes = 1024 * 1024, + .env_map = &env_map, + // Some C compilers, such as Clang, are known to rely on argv[0] to find the path +@@ -267,7 +279,7 @@ pub const LibCInstallation = struct { + }) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + else => { +- printVerboseInvocation(&argv, null, args.verbose, null); ++ printVerboseInvocation(argv.items, null, args.verbose, null); + return error.UnableToSpawnCCompiler; + }, + }; +@@ -277,11 +289,11 @@ pub const LibCInstallation = struct { + } + switch (exec_res.term) { + .Exited => |code| if (code != 0) { +- printVerboseInvocation(&argv, null, args.verbose, exec_res.stderr); ++ printVerboseInvocation(argv.items, null, args.verbose, exec_res.stderr); + return error.CCompilerExitCode; + }, + else => { +- printVerboseInvocation(&argv, null, args.verbose, exec_res.stderr); ++ printVerboseInvocation(argv.items, null, args.verbose, exec_res.stderr); + return error.CCompilerCrashed; + }, + } +@@ -540,8 +552,6 @@ pub const LibCInstallation = struct { + } + }; + +-const default_cc_exe = if (is_windows) "cc.exe" else "cc"; +- + pub const CCPrintFileNameOptions = struct { + allocator: *Allocator, + search_basename: []const u8, +@@ -553,22 +563,33 @@ pub const CCPrintFileNameOptions = struct { + fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 { + const allocator = args.allocator; + +- const cc_exe = std.os.getenvZ("CC") orelse default_cc_exe; +- const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={s}", .{args.search_basename}); +- defer allocator.free(arg1); +- const argv = [_][]const u8{ cc_exe, arg1 }; +- ++ // Detect infinite loops. + var env_map = try std.process.getEnvMap(allocator); + defer env_map.deinit(); ++ const skip_cc_env_var = if (env_map.get(inf_loop_env_key)) |phase| blk: { ++ if (std.mem.eql(u8, phase, "1")) { ++ try env_map.put(inf_loop_env_key, "2"); ++ break :blk true; ++ } else { ++ return error.ZigIsTheCCompiler; ++ } ++ } else blk: { ++ try env_map.put(inf_loop_env_key, "1"); ++ break :blk false; ++ }; + +- // Detect infinite loops. +- const inf_loop_env_key = "ZIG_IS_DETECTING_LIBC_PATHS"; +- if (env_map.get(inf_loop_env_key) != null) return error.ZigIsTheCCompiler; +- try env_map.put(inf_loop_env_key, "1"); ++ var argv = std.ArrayList([]const u8).init(allocator); ++ defer argv.deinit(); ++ ++ const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={s}", .{args.search_basename}); ++ defer allocator.free(arg1); ++ ++ try appendCcExe(&argv, skip_cc_env_var); ++ try argv.append(arg1); + + const exec_res = std.ChildProcess.exec(.{ + .allocator = allocator, +- .argv = &argv, ++ .argv = argv.items, + .max_output_bytes = 1024 * 1024, + .env_map = &env_map, + // Some C compilers, such as Clang, are known to rely on argv[0] to find the path +@@ -586,11 +607,11 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 { + } + switch (exec_res.term) { + .Exited => |code| if (code != 0) { +- printVerboseInvocation(&argv, args.search_basename, args.verbose, exec_res.stderr); ++ printVerboseInvocation(argv.items, args.search_basename, args.verbose, exec_res.stderr); + return error.CCompilerExitCode; + }, + else => { +- printVerboseInvocation(&argv, args.search_basename, args.verbose, exec_res.stderr); ++ printVerboseInvocation(argv.items, args.search_basename, args.verbose, exec_res.stderr); + return error.CCompilerCrashed; + }, + } +@@ -659,3 +680,23 @@ fn fillSearch(search_buf: *[2]Search, sdk: *ZigWindowsSDK) []Search { + } + return search_buf[0..search_end]; + } ++ ++const inf_loop_env_key = "ZIG_IS_DETECTING_LIBC_PATHS"; ++ ++fn appendCcExe(args: *std.ArrayList([]const u8), skip_cc_env_var: bool) !void { ++ const default_cc_exe = if (is_windows) "cc.exe" else "cc"; ++ try args.ensureUnusedCapacity(1); ++ if (skip_cc_env_var) { ++ args.appendAssumeCapacity(default_cc_exe); ++ return; ++ } ++ const cc_env_var = std.os.getenvZ("CC") orelse { ++ args.appendAssumeCapacity(default_cc_exe); ++ return; ++ }; ++ // Respect space-separated flags to the C compiler. ++ var it = std.mem.tokenize(cc_env_var, " "); ++ while (it.next()) |arg| { ++ try args.append(arg); ++ } ++} +-- +2.31.1 + diff --git a/zig.spec b/zig.spec index 90391cf..7eb7f89 100644 --- a/zig.spec +++ b/zig.spec @@ -7,7 +7,7 @@ Name: zig Version: 0.8.0 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Programming language for maintaining robust, optimal, and reusable software License: MIT and NCSA and LGPLv2+ and LGPLv2+ with exceptions and GPLv2+ and GPLv2+ with exceptions and BSD and Inner-Net and ISC and Public Domain and GFDL and ZPLv2.1 @@ -18,6 +18,9 @@ Source1: macros.%{name} # https://github.com/ziglang/zig/pull/9020 Patch0: 0001-specify-the-output-lib-exe-and-include-paths-with-fl.patch Patch1: 0002-zig-build-rename-lib-dir-include-dir-exe-dir.patch +# https://github.com/ziglang/zig/commit/d128ec39df4c0a701523d7d7161df3808a6939d2 +# prevents zig from recursively calling itself +Patch2: 0003-native-libc-detection-respect-spaces-in-CC-env-var.patch BuildRequires: gcc BuildRequires: gcc-c++ @@ -141,6 +144,9 @@ sed -i -e "s|@@ZIG_VERSION@@|%{version}|" %{buildroot}%{_rpmconfigdir}/macros.d %{_rpmconfigdir}/macros.d/macros.%{name} %changelog +* Mon Jul 19 2021 Jan Drögehoff - 0.8.0-6 +- add native libc detection patch + * Sun Jul 04 2021 Jan Drögehoff - 0.8.0-5 - correct newline in macro that caused DESTDIR to be ignored