authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-31 16:59:31-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-04 00:27:08-08:00
logde8c4cd64e0599abda0a0c5e1187391352020478
tree729af246722fa0ae11bc4ad83493faa11bf22de2
parentf612464331a3f878bce2da284960bab349090c00

compiler: update to new std.process APIs


14 files changed, 386 insertions(+), 321 deletions(-)

lib/std/http/Client.zig+9-10
......@@ -1307,7 +1307,7 @@ pub fn deinit(client: *Client) void {
13071307/// Asserts the client has no active connections.
13081308/// Uses `arena` for a few small allocations that must outlive the client, or
13091309/// at least until those fields are set to different values.
1310pub fn initDefaultProxies(client: *Client, arena: Allocator) !void {
1310pub fn initDefaultProxies(client: *Client, arena: Allocator, env_map: *std.process.Environ.Map) !void {
13111311 // Prevent any new connections from being created.
13121312 client.connection_pool.mutex.lock();
13131313 defer client.connection_pool.mutex.unlock();
......@@ -1315,27 +1315,26 @@ pub fn initDefaultProxies(client: *Client, arena: Allocator) !void {
13151315 assert(client.connection_pool.used.first == null); // There are active requests.
13161316
13171317 if (client.http_proxy == null) {
1318 client.http_proxy = try createProxyFromEnvVar(arena, &.{
1318 client.http_proxy = try createProxyFromEnvVar(arena, env_map, &.{
13191319 "http_proxy", "HTTP_PROXY", "all_proxy", "ALL_PROXY",
13201320 });
13211321 }
13221322
13231323 if (client.https_proxy == null) {
1324 client.https_proxy = try createProxyFromEnvVar(arena, &.{
1324 client.https_proxy = try createProxyFromEnvVar(arena, env_map, &.{
13251325 "https_proxy", "HTTPS_PROXY", "all_proxy", "ALL_PROXY",
13261326 });
13271327 }
13281328}
13291329
1330fn createProxyFromEnvVar(arena: Allocator, env_var_names: []const []const u8) !?*Proxy {
1330fn createProxyFromEnvVar(
1331 arena: Allocator,
1332 env_map: *std.process.Environ.Map,
1333 env_var_names: []const []const u8,
1334) !?*Proxy {
13311335 const content = for (env_var_names) |name| {
1332 const content = std.process.getEnvVarOwned(arena, name) catch |err| switch (err) {
1333 error.EnvironmentVariableNotFound => continue,
1334 else => |e| return e,
1335 };
1336
1336 const content = env_map.get(name) orelse continue;
13371337 if (content.len == 0) continue;
1338
13391338 break content;
13401339 } else return null;
13411340
lib/std/process/Args.zig+8-8
......@@ -516,7 +516,7 @@ pub fn freeSlice(gpa: Allocator, to_slice_result: []const [:0]u8) void {
516516}
517517
518518test "Iterator.Windows" {
519 const t = testArgIteratorWindows;
519 const t = testIteratorWindows;
520520
521521 try t(
522522 \\"C:\Program Files\zig\zig.exe" run .\src\main.zig -target x86_64-windows-gnu -O ReleaseSafe -- --emoji=🗿 --eval="new Regex(\"Dwayne \\\"The Rock\\\" Johnson\")"
......@@ -648,7 +648,7 @@ test "Iterator.Windows" {
648648 try t("foo.exe \"\xed\xa0\x81\"\xed\xb0\xb7", &.{ "foo.exe", "𐐷" });
649649}
650650
651fn testArgIteratorWindows(cmd_line: []const u8, expected_args: []const []const u8) !void {
651fn testIteratorWindows(cmd_line: []const u8, expected_args: []const []const u8) !void {
652652 const cmd_line_w = try std.unicode.wtf8ToWtf16LeAllocZ(testing.allocator, cmd_line);
653653 defer testing.allocator.free(cmd_line_w);
654654
......@@ -679,7 +679,7 @@ fn testArgIteratorWindows(cmd_line: []const u8, expected_args: []const []const u
679679 }
680680}
681681
682test "general arg parsing" {
682test "general parsing" {
683683 try testGeneralCmdLine("a b\tc d", &.{ "a", "b", "c", "d" });
684684 try testGeneralCmdLine("\"abc\" d e", &.{ "abc", "d", "e" });
685685 try testGeneralCmdLine("a\\\\\\b d\"e f\"g h", &.{ "a\\\\\\b", "de fg", "h" });
......@@ -703,7 +703,7 @@ test "general arg parsing" {
703703}
704704
705705fn testGeneralCmdLine(input_cmd_line: []const u8, expected_args: []const []const u8) !void {
706 var it = try ArgIteratorGeneral(.{}).init(std.testing.allocator, input_cmd_line);
706 var it = try IteratorGeneral(.{}).init(std.testing.allocator, input_cmd_line);
707707 defer it.deinit();
708708 for (expected_args) |expected_arg| {
709709 const arg = it.next().?;
......@@ -712,14 +712,14 @@ fn testGeneralCmdLine(input_cmd_line: []const u8, expected_args: []const []const
712712 try testing.expect(it.next() == null);
713713}
714714
715/// Optional parameters for `ArgIteratorGeneral`
716pub const ArgIteratorGeneralOptions = struct {
715/// Optional parameters for `IteratorGeneral`
716pub const IteratorGeneralOptions = struct {
717717 comments: bool = false,
718718 single_quotes: bool = false,
719719};
720720
721721/// A general Iterator to parse a string into a set of arguments
722pub fn ArgIteratorGeneral(comptime options: ArgIteratorGeneralOptions) type {
722pub fn IteratorGeneral(comptime options: IteratorGeneralOptions) type {
723723 return struct {
724724 allocator: Allocator,
725725 index: usize = 0,
......@@ -947,7 +947,7 @@ test "response file arg parsing" {
947947}
948948
949949fn testResponseFileCmdLine(input_cmd_line: []const u8, expected_args: []const []const u8) !void {
950 var it = try ArgIteratorGeneral(.{ .comments = true, .single_quotes = true })
950 var it = try IteratorGeneral(.{ .comments = true, .single_quotes = true })
951951 .init(std.testing.allocator, input_cmd_line);
952952 defer it.deinit();
953953 for (expected_args) |expected_arg| {
lib/std/process/Environ.zig+1-1
......@@ -20,7 +20,7 @@ const mem = std.mem;
2020block: Block,
2121
2222pub const Block = switch (native_os) {
23 .windows => []const u16,
23 .windows => [*:0]const u16,
2424 .wasi => switch (builtin.link_libc) {
2525 false => void,
2626 true => [:null]const ?[*:0]const u8,
lib/std/start.zig+5-2
......@@ -524,9 +524,12 @@ fn WinStartup() callconv(.withStackAlign(.c, 1)) noreturn {
524524
525525 std.debug.maybeEnableSegfaultHandler();
526526
527 const peb = std.os.windows.peb();
528 const cmd_line = std.os.windows.peb().ProcessParameters.CommandLine;
529
527530 std.os.windows.ntdll.RtlExitUserProcess(callMain(
528 std.os.windows.peb().ProcessParameters.CommandLine,
529 std.os.windows.peb().ProcessParameters.Environment,
531 cmd_line.Buffer.?[0..@divExact(cmd_line.Length, 2)],
532 peb.ProcessParameters.Environment,
530533 ));
531534}
532535
lib/std/zig.zig+9
......@@ -741,9 +741,18 @@ pub const EnvVar = enum {
741741 ZIG_DEBUG_CMD,
742742 ZIG_IS_DETECTING_LIBC_PATHS,
743743 ZIG_IS_TRYING_TO_NOT_CALL_ITSELF,
744
745 NIX_CFLAGS_COMPILE,
746 NIX_CFLAGS_LINK,
747 NIX_LDFLAGS,
748 C_INCLUDE_PATH,
749 CPLUS_INCLUDE_PATH,
750 LIBRARY_PATH,
744751 CC,
752
745753 NO_COLOR,
746754 CLICOLOR_FORCE,
755
747756 XDG_CACHE_HOME,
748757 LOCALAPPDATA,
749758 HOME,
lib/std/zig/LibCDirs.zig+11-3
......@@ -28,6 +28,7 @@ pub fn detect(
2828 is_native_abi: bool,
2929 link_libc: bool,
3030 libc_installation: ?*const LibCInstallation,
31 env_map: *const std.process.Environ.Map,
3132) LibCInstallation.FindError!LibCDirs {
3233 if (!link_libc) {
3334 return .{
......@@ -47,7 +48,10 @@ pub fn detect(
4748 // using the system libc installation.
4849 if (is_native_abi and !target.isMinGW()) {
4950 const libc = try arena.create(LibCInstallation);
50 libc.* = LibCInstallation.findNative(arena, io, .{ .target = target }) catch |err| switch (err) {
51 libc.* = LibCInstallation.findNative(arena, io, .{
52 .target = target,
53 .env_map = env_map,
54 }) catch |err| switch (err) {
5155 error.CCompilerExitCode,
5256 error.CCompilerCrashed,
5357 error.CCompilerCannotFindHeaders,
......@@ -84,12 +88,16 @@ pub fn detect(
8488
8589 if (use_system_abi) {
8690 const libc = try arena.create(LibCInstallation);
87 libc.* = try LibCInstallation.findNative(arena, io, .{ .verbose = true, .target = target });
91 libc.* = try LibCInstallation.findNative(arena, io, .{
92 .verbose = true,
93 .target = target,
94 .env_map = env_map,
95 });
8896 return detectFromInstallation(arena, target, libc);
8997 }
9098
9199 return .{
92 .libc_include_dir_list = &[0][]u8{},
100 .libc_include_dir_list = &.{},
93101 .libc_installation = null,
94102 .libc_framework_dir_list = &.{},
95103 .sysroot = null,
lib/std/zig/LibCInstallation.zig+13-12
......@@ -167,6 +167,7 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {
167167
168168pub const FindNativeOptions = struct {
169169 target: *const std.Target,
170 env_map: *const std.process.Environ.Map,
170171
171172 /// If enabled, will print human-friendly errors to stderr.
172173 verbose: bool = false,
......@@ -238,10 +239,7 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void {
238239
239240fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
240241 // Detect infinite loops.
241 var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) {
242 error.Unexpected => unreachable, // WASI-only
243 else => |e| return e,
244 };
242 var env_map = try args.env_map.clone(gpa);
245243 defer env_map.deinit();
246244 const skip_cc_env_var = if (env_map.get(inf_loop_env_key)) |phase| blk: {
247245 if (std.mem.eql(u8, phase, "1")) {
......@@ -260,7 +258,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar
260258 var argv = std.array_list.Managed([]const u8).init(gpa);
261259 defer argv.deinit();
262260
263 try appendCcExe(&argv, skip_cc_env_var);
261 try appendCcExe(&argv, skip_cc_env_var, &env_map);
264262 try argv.appendSlice(&.{
265263 "-E",
266264 "-Wp,-v",
......@@ -449,6 +447,7 @@ fn findNativeCrtDirWindows(
449447
450448fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
451449 self.crt_dir = try ccPrintFileName(gpa, io, .{
450 .env_map = args.env_map,
452451 .search_basename = switch (args.target.os.tag) {
453452 .linux => if (args.target.abi.isAndroid()) "crtbegin_dynamic.o" else "crt1.o",
454453 else => "crt1.o",
......@@ -553,6 +552,7 @@ fn findNativeMsvcLibDir(
553552}
554553
555554pub const CCPrintFileNameOptions = struct {
555 env_map: *const std.process.Environ.Map,
556556 search_basename: []const u8,
557557 want_dirname: enum { full_path, only_dir },
558558 verbose: bool = false,
......@@ -561,10 +561,7 @@ pub const CCPrintFileNameOptions = struct {
561561/// caller owns returned memory
562562fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8 {
563563 // Detect infinite loops.
564 var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) {
565 error.Unexpected => unreachable, // WASI-only
566 else => |e| return e,
567 };
564 var env_map = try args.env_map.clone(gpa);
568565 defer env_map.deinit();
569566 const skip_cc_env_var = if (env_map.get(inf_loop_env_key)) |phase| blk: {
570567 if (std.mem.eql(u8, phase, "1")) {
......@@ -584,7 +581,7 @@ fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8
584581 const arg1 = try std.fmt.allocPrint(gpa, "-print-file-name={s}", .{args.search_basename});
585582 defer gpa.free(arg1);
586583
587 try appendCcExe(&argv, skip_cc_env_var);
584 try appendCcExe(&argv, skip_cc_env_var, &env_map);
588585 try argv.append(arg1);
589586
590587 const run_res = std.process.run(gpa, io, .{
......@@ -672,14 +669,18 @@ fn fillInstallations(
672669
673670const inf_loop_env_key = "ZIG_IS_DETECTING_LIBC_PATHS";
674671
675fn appendCcExe(args: *std.array_list.Managed([]const u8), skip_cc_env_var: bool) !void {
672fn appendCcExe(
673 args: *std.array_list.Managed([]const u8),
674 skip_cc_env_var: bool,
675 env_map: *const std.process.Environ.Map,
676) !void {
676677 const default_cc_exe = if (is_windows) "cc.exe" else "cc";
677678 try args.ensureUnusedCapacity(1);
678679 if (skip_cc_env_var) {
679680 args.appendAssumeCapacity(default_cc_exe);
680681 return;
681682 }
682 const cc_env_var = std.zig.EnvVar.CC.getPosix() orelse {
683 const cc_env_var = std.zig.EnvVar.CC.get(env_map) orelse {
683684 args.appendAssumeCapacity(default_cc_exe);
684685 return;
685686 };
lib/std/zig/WindowsSdk.zig+6-7
......@@ -951,15 +951,14 @@ const MsvcLibDir = struct {
951951 return msvc_dir;
952952 }
953953
954 fn findViaVs7Key(gpa: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 {
954 fn findViaVs7Key(
955 gpa: Allocator,
956 io: Io,
957 arch: std.Target.Cpu.Arch,
958 env_map: *const std.process.Environ.Map,
959 ) error{ OutOfMemory, PathNotFound }![]const u8 {
955960 var base_path: std.array_list.Managed(u8) = base_path: {
956961 try_env: {
957 var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) {
958 error.OutOfMemory => return error.OutOfMemory,
959 else => break :try_env,
960 };
961 defer env_map.deinit();
962
963962 if (env_map.get("VS140COMNTOOLS")) |VS140COMNTOOLS| {
964963 if (VS140COMNTOOLS.len < "C:\\Common7\\Tools".len) break :try_env;
965964 if (!Dir.path.isAbsolute(VS140COMNTOOLS)) break :try_env;
lib/std/zig/system/NativePaths.zig+16-19
......@@ -14,10 +14,16 @@ framework_dirs: std.ArrayList([]const u8) = .empty,
1414rpaths: std.ArrayList([]const u8) = .empty,
1515warnings: std.ArrayList([]const u8) = .empty,
1616
17pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !NativePaths {
17pub fn detect(
18 arena: Allocator,
19 io: Io,
20 native_target: *const std.Target,
21 env_map: *process.Environ.Map,
22) !NativePaths {
1823 var self: NativePaths = .{ .arena = arena };
1924 var is_nix = false;
20 if (process.getEnvVarOwned(arena, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
25
26 if (std.zig.EnvVar.NIX_CFLAGS_COMPILE.get(env_map)) |nix_cflags_compile| {
2127 is_nix = true;
2228 var it = mem.tokenizeScalar(u8, nix_cflags_compile, ' ');
2329 while (true) {
......@@ -41,12 +47,9 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ
4147 try self.addWarningFmt("Unrecognized C flag from NIX_CFLAGS_COMPILE: {s}", .{word});
4248 }
4349 }
44 } else |err| switch (err) {
45 error.InvalidWtf8 => unreachable,
46 error.EnvironmentVariableNotFound => {},
47 error.OutOfMemory => |e| return e,
4850 }
49 if (process.getEnvVarOwned(arena, "NIX_LDFLAGS")) |nix_ldflags| {
51
52 if (std.zig.EnvVar.NIX_LDFLAGS.get(env_map)) |nix_ldflags| {
5053 is_nix = true;
5154 var it = mem.tokenizeScalar(u8, nix_ldflags, ' ');
5255 while (true) {
......@@ -73,12 +76,9 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ
7376 break;
7477 }
7578 }
76 } else |err| switch (err) {
77 error.InvalidWtf8 => unreachable,
78 error.EnvironmentVariableNotFound => {},
79 error.OutOfMemory => |e| return e,
8079 }
81 if (process.getEnvVarOwned(arena, "NIX_CFLAGS_LINK")) |nix_cflags_link| {
80
81 if (std.zig.EnvVar.NIX_CFLAGS_LINK.get(env_map)) |nix_cflags_link| {
8282 is_nix = true;
8383 var it = mem.tokenizeScalar(u8, nix_cflags_link, ' ');
8484 while (true) {
......@@ -105,11 +105,8 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ
105105 break;
106106 }
107107 }
108 } else |err| switch (err) {
109 error.InvalidWtf8 => unreachable,
110 error.EnvironmentVariableNotFound => {},
111 error.OutOfMemory => |e| return e,
112108 }
109
113110 if (is_nix) {
114111 return self;
115112 }
......@@ -182,21 +179,21 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ
182179 // variables to search for headers and libraries.
183180 // We use os.getenv here since this part won't be executed on
184181 // windows, to get rid of unnecessary error handling.
185 if (std.posix.getenv("C_INCLUDE_PATH")) |c_include_path| {
182 if (std.zig.EnvVar.C_INCLUDE_PATH.get(env_map)) |c_include_path| {
186183 var it = mem.tokenizeScalar(u8, c_include_path, ':');
187184 while (it.next()) |dir| {
188185 try self.addIncludeDir(dir);
189186 }
190187 }
191188
192 if (std.posix.getenv("CPLUS_INCLUDE_PATH")) |cplus_include_path| {
189 if (std.zig.EnvVar.CPLUS_INCLUDE_PATH.get(env_map)) |cplus_include_path| {
193190 var it = mem.tokenizeScalar(u8, cplus_include_path, ':');
194191 while (it.next()) |dir| {
195192 try self.addIncludeDir(dir);
196193 }
197194 }
198195
199 if (std.posix.getenv("LIBRARY_PATH")) |library_path| {
196 if (std.zig.EnvVar.LIBRARY_PATH.get(env_map)) |library_path| {
200197 var it = mem.tokenizeScalar(u8, library_path, ':');
201198 while (it.next()) |dir| {
202199 try self.addLibDir(dir);
src/Compilation.zig+25-13
......@@ -54,6 +54,7 @@ gpa: Allocator,
5454/// threads at once.
5555arena: Allocator,
5656io: Io,
57environ_map: *std.process.Environ.Map,
5758thread_limit: usize,
5859/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
5960zcu: ?*Zcu,
......@@ -761,6 +762,7 @@ pub const Directories = struct {
761762 .wasi => void,
762763 else => []const u8,
763764 },
765 env_map: *std.process.Environ.Map,
764766 ) Directories {
765767 const wasi = builtin.target.os.tag == .wasi;
766768
......@@ -779,7 +781,7 @@ pub const Directories = struct {
779781 const global_cache: Cache.Directory = d: {
780782 if (override_global_cache) |path| break :d openUnresolved(arena, io, cwd, path, .@"global cache");
781783 if (wasi) break :d openWasiPreopen(wasi_preopens, "/cache");
782 const path = introspect.resolveGlobalCacheDir(arena) catch |err| {
784 const path = introspect.resolveGlobalCacheDir(arena, env_map) catch |err| {
783785 fatal("unable to resolve zig cache directory: {t}", .{err});
784786 };
785787 break :d openUnresolved(arena, io, cwd, path, .@"global cache");
......@@ -1797,6 +1799,8 @@ pub const CreateOptions = struct {
17971799
17981800 parent_whole_cache: ?ParentWholeCache = null,
17991801
1802 environ_map: *std.process.Environ.Map,
1803
18001804 pub const Entry = link.File.OpenOptions.Entry;
18011805
18021806 /// Which fields are valid depends on the `cache_mode` given.
......@@ -1967,6 +1971,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
19671971 options.root_mod.resolved_target.is_native_abi,
19681972 link_libc,
19691973 options.libc_installation,
1974 options.environ_map,
19701975 ) catch |err| switch (err) {
19711976 error.OutOfMemory => |e| return e,
19721977 // Every other error is specifically related to finding the native installation
......@@ -2306,6 +2311,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
23062311 .emit_llvm_ir = try options.emit_llvm_ir.resolve(arena, &options, .llvm_ir),
23072312 .emit_llvm_bc = try options.emit_llvm_bc.resolve(arena, &options, .llvm_bc),
23082313 .emit_docs = try options.emit_docs.resolve(arena, &options, .docs),
2314 .environ_map = options.environ_map,
23092315 };
23102316
23112317 errdefer {
......@@ -5503,6 +5509,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU
55035509 .verbose_llvm_bc = comp.verbose_llvm_bc,
55045510 .verbose_cimport = comp.verbose_cimport,
55055511 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
5512 .environ_map = comp.environ_map,
55065513 }) catch |err| switch (err) {
55075514 error.CreateFail => {
55085515 comp.lockAndSetMiscFailure(.docs_wasm, "sub-compilation of docs_wasm failed: {f}", .{sub_create_diag});
......@@ -5705,6 +5712,7 @@ pub fn translateC(
57055712 translated_basename: []const u8,
57065713 owner_mod: *Package.Module,
57075714 prog_node: std.Progress.Node,
5715 env_map: *std.process.Environ.Map,
57085716) !CImportResult {
57095717 dev.check(.translate_c_command);
57105718
......@@ -5774,7 +5782,7 @@ pub fn translateC(
57745782 }
57755783
57765784 var stdout: []u8 = undefined;
5777 try @import("main.zig").translateC(gpa, arena, io, argv.items, prog_node, &stdout);
5785 try @import("main.zig").translateC(gpa, arena, io, argv.items, env_map, prog_node, &stdout);
57785786
57795787 if (out_dep_path) |dep_file_path| add_deps: {
57805788 if (comp.verbose_cimport) log.info("processing dep file at {s}", .{dep_file_path});
......@@ -5861,7 +5869,8 @@ pub fn cImport(
58615869 defer arena_allocator.deinit();
58625870 const arena = arena_allocator.allocator();
58635871
5864 break :result try comp.translateC(
5872 break :result try translateC(
5873 comp,
58655874 arena,
58665875 &man,
58675876 .c,
......@@ -5869,6 +5878,7 @@ pub fn cImport(
58695878 translated_basename,
58705879 owner_mod,
58715880 prog_node,
5881 comp.environ_map,
58725882 );
58735883 };
58745884
......@@ -6741,15 +6751,16 @@ fn spawnZigRc(
67416751 var node_name: std.ArrayList(u8) = .empty;
67426752 defer node_name.deinit(arena);
67436753
6744 var child = std.process.Child.init(argv, arena);
6745 child.stdin_behavior = .ignore;
6746 child.stdout_behavior = .pipe;
6747 child.stderr_behavior = .pipe;
6748 child.progress_node = child_progress_node;
6749
6750 child.spawn(io) catch |err| {
6751 return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {t}", .{ argv[0], err });
6752 };
6754 var child = std.process.spawn(io, .{
6755 .argv = argv,
6756 .stdin = .ignore,
6757 .stdout = .pipe,
6758 .stderr = .pipe,
6759 .progress_node = child_progress_node,
6760 }) catch |err| return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {t}", .{
6761 argv[0], err,
6762 });
6763 defer child.kill(io);
67536764
67546765 var poller = std.Io.poll(comp.gpa, enum { stdout, stderr }, .{
67556766 .stdout = child.stdout.?,
......@@ -6781,7 +6792,7 @@ fn spawnZigRc(
67816792 const stderr = poller.reader(.stderr);
67826793
67836794 const term = child.wait(io) catch |err| {
6784 return comp.failWin32Resource(win32_resource, "unable to wait for {s} rc: {s}", .{ argv[0], @errorName(err) });
6795 return comp.failWin32Resource(win32_resource, "unable to wait for {s} rc: {t}", .{ argv[0], err });
67856796 };
67866797
67876798 switch (term) {
......@@ -7963,6 +7974,7 @@ fn buildOutputFromZig(
79637974 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
79647975 .clang_passthrough_mode = comp.clang_passthrough_mode,
79657976 .skip_linker_dependencies = true,
7977 .environ_map = comp.environ_map,
79667978 }) catch |err| switch (err) {
79677979 error.CreateFail => {
79687980 comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: {f}", .{ misc_task_tag, sub_create_diag });
src/introspect.zig+9-13
......@@ -101,31 +101,27 @@ pub fn findZigLibDirFromSelfExe(
101101 return error.FileNotFound;
102102}
103103
104/// Caller owns returned memory.
105pub fn resolveGlobalCacheDir(gpa: Allocator) ![]u8 {
106 if (try std.zig.EnvVar.ZIG_GLOBAL_CACHE_DIR.get(gpa)) |value| return value;
104pub fn resolveGlobalCacheDir(arena: Allocator, env_map: *std.process.Environ.Map) ![]const u8 {
105 if (std.zig.EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map)) |value| return value;
107106
108107 const app_name = "zig";
109108
110109 switch (builtin.os.tag) {
111110 .wasi => @compileError("on WASI the global cache dir must be resolved with preopens"),
112111 .windows => {
113 const local_app_data_dir = (std.zig.EnvVar.LOCALAPPDATA.get(gpa) catch |err| switch (err) {
114 error.OutOfMemory => |e| return e,
115 error.InvalidWtf8 => return error.AppDataDirUnavailable,
116 }) orelse return error.AppDataDirUnavailable;
117 defer gpa.free(local_app_data_dir);
118 return Dir.path.join(gpa, &.{ local_app_data_dir, app_name });
112 const local_app_data_dir = std.zig.EnvVar.LOCALAPPDATA.get(env_map) orelse
113 return error.AppDataDirUnavailable;
114 return Dir.path.join(arena, &.{ local_app_data_dir, app_name });
119115 },
120116 else => {
121 if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| {
117 if (std.zig.EnvVar.XDG_CACHE_HOME.get(env_map)) |cache_root| {
122118 if (cache_root.len > 0) {
123 return Dir.path.join(gpa, &.{ cache_root, app_name });
119 return Dir.path.join(arena, &.{ cache_root, app_name });
124120 }
125121 }
126 if (std.zig.EnvVar.HOME.getPosix()) |home| {
122 if (std.zig.EnvVar.HOME.get(env_map)) |home| {
127123 if (home.len > 0) {
128 return Dir.path.join(gpa, &.{ home, ".cache", app_name });
124 return Dir.path.join(arena, &.{ home, ".cache", app_name });
129125 }
130126 }
131127 return error.AppDataDirUnavailable;
src/link/Lld.zig+28-25
......@@ -1604,19 +1604,24 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
16041604 var stderr: []u8 = &.{};
16051605 defer gpa.free(stderr);
16061606
1607 var child = std.process.Child.init(argv, arena);
1607 // TODO rework this awkward logic to call child.kill() in the failure case
16081608 const term = (if (comp.clang_passthrough_mode) term: {
1609 child.stdin_behavior = .inherit;
1610 child.stdout_behavior = .inherit;
1611 child.stderr_behavior = .inherit;
1609 var child = std.process.spawn(io, .{
1610 .argv = argv,
1611 .stdin = .inherit,
1612 .stdout = .inherit,
1613 .stderr = .inherit,
1614 }) catch |err| break :term err;
16121615
1613 break :term child.spawnAndWait(io);
1616 break :term child.wait(io);
16141617 } else term: {
1615 child.stdin_behavior = .ignore;
1616 child.stdout_behavior = .ignore;
1617 child.stderr_behavior = .pipe;
1618 var child = std.process.spawn(io, .{
1619 .argv = argv,
1620 .stdin = .ignore,
1621 .stdout = .ignore,
1622 .stderr = .pipe,
1623 }) catch |err| break :term err;
16181624
1619 child.spawn(io) catch |err| break :term err;
16201625 var stderr_reader = child.stderr.?.readerStreaming(io, &.{});
16211626 stderr = try stderr_reader.interface.allocRemaining(gpa, .unlimited);
16221627 break :term child.wait(io);
......@@ -1650,23 +1655,21 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
16501655 try rsp_writer.flush();
16511656 }
16521657
1653 var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint(
1654 arena,
1655 "@{s}",
1656 .{try comp.dirs.local_cache.join(arena, &.{rsp_path})},
1657 ) }, arena);
1658 var rsp_child = std.process.spawn(io, .{
1659 .argv = &.{
1660 argv[0],
1661 argv[1],
1662 try std.fmt.allocPrint(arena, "@{s}", .{
1663 try comp.dirs.local_cache.join(arena, &.{rsp_path}),
1664 }),
1665 },
1666 .stdin = if (comp.clang_passthrough_mode) .inherit else .ignore,
1667 .stdout = if (comp.clang_passthrough_mode) .inherit else .ignore,
1668 .stderr = if (comp.clang_passthrough_mode) .inherit else .pipe,
1669 }) catch |err| break :err err;
16581670 if (comp.clang_passthrough_mode) {
1659 rsp_child.stdin_behavior = .inherit;
1660 rsp_child.stdout_behavior = .inherit;
1661 rsp_child.stderr_behavior = .inherit;
1662
1663 break :term rsp_child.spawnAndWait(io) catch |err| break :err err;
1671 break :term rsp_child.wait(io) catch |err| break :err err;
16641672 } else {
1665 rsp_child.stdin_behavior = .ignore;
1666 rsp_child.stdout_behavior = .ignore;
1667 rsp_child.stderr_behavior = .pipe;
1668
1669 rsp_child.spawn(io) catch |err| break :err err;
16701673 var stderr_reader = rsp_child.stderr.?.readerStreaming(io, &.{});
16711674 stderr = try stderr_reader.interface.allocRemaining(gpa, .unlimited);
16721675 break :term rsp_child.wait(io) catch |err| break :err err;
......@@ -1674,7 +1677,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
16741677 },
16751678 else => first_err,
16761679 };
1677 log.err("unable to spawn LLD {s}: {s}", .{ argv[0], @errorName(err) });
1680 log.err("unable to spawn LLD {s}: {t}", .{ argv[0], err });
16781681 return error.UnableToSpawnSelf;
16791682 };
16801683
src/main.zig+240-204
......@@ -42,7 +42,6 @@ test {
4242const thread_stack_size = 60 << 20;
4343
4444pub const std_options: std.Options = .{
45 .wasiCwd = wasi_cwd,
4645 .logFn = log,
4746
4847 .log_level = switch (builtin.mode) {
......@@ -51,6 +50,7 @@ pub const std_options: std.Options = .{
5150 .ReleaseSmall => .err,
5251 },
5352};
53pub const std_options_cwd = if (native_os == .wasi) wasi_cwd else null;
5454
5555pub const panic = crash_report.panic;
5656pub const debug = crash_report.debug;
......@@ -208,7 +208,15 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
208208 fatal("expected command argument", .{});
209209 }
210210
211 if (process.can_replace and std.zig.EnvVar.ZIG_IS_DETECTING_LIBC_PATHS.isSet(env_map)) {
211 var threaded: Io.Threaded = .init(gpa, .{
212 .argv0 = if (@hasField(Io.Threaded.Argv0, "value")) .{ .value = args[0] } else .{},
213 });
214 defer threaded.deinit();
215 threaded_impl_ptr = &threaded;
216 threaded.stack_size = thread_stack_size;
217 const io = threaded.io();
218
219 if (process.can_replace and EnvVar.ZIG_IS_DETECTING_LIBC_PATHS.isSet(env_map)) {
212220 dev.check(.cc_command);
213221 // In this case we have accidentally invoked ourselves as "the system C compiler"
214222 // to figure out where libc is installed. This is essentially infinite recursion
......@@ -217,7 +225,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
217225 // However it's possible Zig is installed as *that* C compiler as well, which is
218226 // why we have this additional environment variable here to check.
219227
220 const inf_loop_env_key: std.zig.EnvVar = .ZIG_IS_TRYING_TO_NOT_CALL_ITSELF;
228 const inf_loop_env_key: EnvVar = .ZIG_IS_TRYING_TO_NOT_CALL_ITSELF;
221229 if (inf_loop_env_key.isSet(env_map)) {
222230 fatal("{s}", .{
223231 "The compilation links against libc, but Zig is unable to provide a libc " ++
......@@ -233,42 +241,34 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
233241 // CC environment variable. We detect and support this scenario here because of
234242 // the ZIG_IS_DETECTING_LIBC_PATHS environment variable.
235243 if (mem.eql(u8, args[1], "cc")) {
236 return process.replace(.{ .argv = args[1..], .env_map = env_map });
244 return process.replace(io, .{ .argv = args[1..], .env_map = env_map });
237245 } else {
238246 const modified_args = try arena.dupe([]const u8, args);
239247 modified_args[0] = "cc";
240 return process.replace(.{ .argv = modified_args, .env_map = env_map });
248 return process.replace(io, .{ .argv = modified_args, .env_map = env_map });
241249 }
242250 }
243251
244 var threaded: Io.Threaded = .init(gpa, .{
245 .argv0 = if (@hasField(Io.Threaded.Argv0, "value")) .{ .value = args[0] } else .{},
246 });
247 defer threaded.deinit();
248 threaded_impl_ptr = &threaded;
249 threaded.stack_size = thread_stack_size;
250 const io = threaded.io();
251
252252 const cmd = args[1];
253253 const cmd_args = args[2..];
254254 if (mem.eql(u8, cmd, "build-exe")) {
255255 dev.check(.build_exe_command);
256 return buildOutputType(gpa, arena, io, args, .{ .build = .Exe });
256 return buildOutputType(gpa, arena, io, args, .{ .build = .Exe }, env_map);
257257 } else if (mem.eql(u8, cmd, "build-lib")) {
258258 dev.check(.build_lib_command);
259 return buildOutputType(gpa, arena, io, args, .{ .build = .Lib });
259 return buildOutputType(gpa, arena, io, args, .{ .build = .Lib }, env_map);
260260 } else if (mem.eql(u8, cmd, "build-obj")) {
261261 dev.check(.build_obj_command);
262 return buildOutputType(gpa, arena, io, args, .{ .build = .Obj });
262 return buildOutputType(gpa, arena, io, args, .{ .build = .Obj }, env_map);
263263 } else if (mem.eql(u8, cmd, "test")) {
264264 dev.check(.test_command);
265 return buildOutputType(gpa, arena, io, args, .zig_test);
265 return buildOutputType(gpa, arena, io, args, .zig_test, env_map);
266266 } else if (mem.eql(u8, cmd, "test-obj")) {
267267 dev.check(.test_command);
268 return buildOutputType(gpa, arena, io, args, .zig_test_obj);
268 return buildOutputType(gpa, arena, io, args, .zig_test_obj, env_map);
269269 } else if (mem.eql(u8, cmd, "run")) {
270270 dev.check(.run_command);
271 return buildOutputType(gpa, arena, io, args, .run);
271 return buildOutputType(gpa, arena, io, args, .run, env_map);
272272 } else if (mem.eql(u8, cmd, "dlltool") or
273273 mem.eql(u8, cmd, "ranlib") or
274274 mem.eql(u8, cmd, "lib") or
......@@ -278,7 +278,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
278278 return process.exit(try llvmArMain(arena, args));
279279 } else if (mem.eql(u8, cmd, "build")) {
280280 dev.check(.build_command);
281 return cmdBuild(gpa, arena, io, cmd_args);
281 return cmdBuild(gpa, arena, io, cmd_args, env_map);
282282 } else if (mem.eql(u8, cmd, "clang") or
283283 mem.eql(u8, cmd, "-cc1") or mem.eql(u8, cmd, "-cc1as"))
284284 {
......@@ -292,16 +292,16 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
292292 return process.exit(try lldMain(arena, args, true));
293293 } else if (mem.eql(u8, cmd, "cc")) {
294294 dev.check(.cc_command);
295 return buildOutputType(gpa, arena, io, args, .cc);
295 return buildOutputType(gpa, arena, io, args, .cc, env_map);
296296 } else if (mem.eql(u8, cmd, "c++")) {
297297 dev.check(.cc_command);
298 return buildOutputType(gpa, arena, io, args, .cpp);
298 return buildOutputType(gpa, arena, io, args, .cpp, env_map);
299299 } else if (mem.eql(u8, cmd, "translate-c")) {
300300 dev.check(.translate_c_command);
301 return buildOutputType(gpa, arena, io, args, .translate_c);
301 return buildOutputType(gpa, arena, io, args, .translate_c, env_map);
302302 } else if (mem.eql(u8, cmd, "rc")) {
303303 const use_server = cmd_args.len > 0 and std.mem.eql(u8, cmd_args[0], "--zig-integration");
304 return jitCmd(gpa, arena, io, cmd_args, .{
304 return jitCmd(gpa, arena, io, cmd_args, env_map, .{
305305 .cmd_name = "resinator",
306306 .root_src_path = "resinator/main.zig",
307307 .depend_on_aro = true,
......@@ -312,20 +312,20 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
312312 dev.check(.fmt_command);
313313 return @import("fmt.zig").run(gpa, arena, io, cmd_args);
314314 } else if (mem.eql(u8, cmd, "objcopy")) {
315 return jitCmd(gpa, arena, io, cmd_args, .{
315 return jitCmd(gpa, arena, io, cmd_args, env_map, .{
316316 .cmd_name = "objcopy",
317317 .root_src_path = "objcopy.zig",
318318 });
319319 } else if (mem.eql(u8, cmd, "fetch")) {
320 return cmdFetch(gpa, arena, io, cmd_args);
320 return cmdFetch(gpa, arena, io, cmd_args, env_map);
321321 } else if (mem.eql(u8, cmd, "libc")) {
322 return jitCmd(gpa, arena, io, cmd_args, .{
322 return jitCmd(gpa, arena, io, cmd_args, env_map, .{
323323 .cmd_name = "libc",
324324 .root_src_path = "libc.zig",
325325 .prepend_zig_lib_dir_path = true,
326326 });
327327 } else if (mem.eql(u8, cmd, "std")) {
328 return jitCmd(gpa, arena, io, cmd_args, .{
328 return jitCmd(gpa, arena, io, cmd_args, env_map, .{
329329 .cmd_name = "std",
330330 .root_src_path = "std-docs.zig",
331331 .prepend_zig_lib_dir_path = true,
......@@ -355,10 +355,11 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
355355 args,
356356 if (native_os == .wasi) wasi_preopens,
357357 &host,
358 env_map,
358359 );
359360 return stdout_writer.interface.flush();
360361 } else if (mem.eql(u8, cmd, "reduce")) {
361 return jitCmd(gpa, arena, io, cmd_args, .{
362 return jitCmd(gpa, arena, io, cmd_args, env_map, .{
362363 .cmd_name = "reduce",
363364 .root_src_path = "reduce.zig",
364365 });
......@@ -803,6 +804,7 @@ fn buildOutputType(
803804 io: Io,
804805 all_args: []const []const u8,
805806 arg_mode: ArgMode,
807 env_map: *process.Environ.Map,
806808) !void {
807809 var provided_name: ?[]const u8 = null;
808810 var root_src_file: ?[]const u8 = null;
......@@ -815,9 +817,9 @@ fn buildOutputType(
815817 var debug_compile_errors = false;
816818 var debug_incremental = false;
817819 var verbose_link = (native_os != .wasi or builtin.link_libc) and
818 EnvVar.ZIG_VERBOSE_LINK.isSet();
820 EnvVar.ZIG_VERBOSE_LINK.isSet(env_map);
819821 var verbose_cc = (native_os != .wasi or builtin.link_libc) and
820 EnvVar.ZIG_VERBOSE_CC.isSet();
822 EnvVar.ZIG_VERBOSE_CC.isSet(env_map);
821823 var verbose_air = false;
822824 var verbose_intern_pool = false;
823825 var verbose_generic_instances = false;
......@@ -889,9 +891,9 @@ fn buildOutputType(
889891 var runtime_args_start: ?usize = null;
890892 var test_filters: std.ArrayList([]const u8) = .empty;
891893 var test_runner_path: ?[]const u8 = null;
892 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);
893 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
894 var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);
894 var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(env_map);
895 var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
896 var override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(env_map);
895897 var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;
896898 var subsystem: ?std.zig.Subsystem = null;
897899 var major_subsystem_version: ?u16 = null;
......@@ -988,7 +990,7 @@ fn buildOutputType(
988990 .framework_dirs = .{},
989991 .rpath_list = .{},
990992 .each_lib_rpath = null,
991 .libc_paths_file = try EnvVar.ZIG_LIBC.get(arena),
993 .libc_paths_file = EnvVar.ZIG_LIBC.get(env_map),
992994 .native_system_include_paths = &.{},
993995 };
994996 defer create_module.link_inputs.deinit(gpa);
......@@ -997,9 +999,9 @@ fn buildOutputType(
997999 // if set, default the color setting to .off or .on, respectively
9981000 // explicit --color arguments will still override this setting.
9991001 // Disable color on WASI per https://github.com/WebAssembly/WASI/issues/162
1000 var color: Color = if (native_os == .wasi or EnvVar.NO_COLOR.isSet())
1002 var color: Color = if (native_os == .wasi or EnvVar.NO_COLOR.isSet(env_map))
10011003 .off
1002 else if (EnvVar.CLICOLOR_FORCE.isSet())
1004 else if (EnvVar.CLICOLOR_FORCE.isSet(env_map))
10031005 .on
10041006 else
10051007 .auto;
......@@ -3097,6 +3099,7 @@ fn buildOutputType(
30973099 },
30983100 if (native_os == .wasi) wasi_preopens,
30993101 self_exe_path,
3102 env_map,
31003103 );
31013104 defer dirs.deinit(io);
31023105
......@@ -3108,7 +3111,7 @@ fn buildOutputType(
31083111 create_module.opts.emit_bin = emit_bin != .no;
31093112 create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0;
31103113
3111 const main_mod = try createModule(gpa, arena, io, &create_module, 0, null, color);
3114 const main_mod = try createModule(gpa, arena, io, &create_module, 0, null, color, env_map);
31123115 for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| {
31133116 if (cli_mod.resolved == null)
31143117 fatal("module '{s}' declared but not used", .{key});
......@@ -3585,6 +3588,7 @@ fn buildOutputType(
35853588 .global_cc_argv = try cc_argv.toOwnedSlice(arena),
35863589 .file_system_inputs = &file_system_inputs,
35873590 .debug_compiler_runtime_libs = debug_compiler_runtime_libs,
3591 .environ_map = env_map,
35883592 }) catch |err| switch (err) {
35893593 error.CreateFail => switch (create_diag) {
35903594 .cross_libc_unavailable => {
......@@ -3648,6 +3652,7 @@ fn buildOutputType(
36483652 arg_mode,
36493653 all_args,
36503654 runtime_args_start,
3655 env_map,
36513656 );
36523657 return cleanExit(io);
36533658 },
......@@ -3674,6 +3679,7 @@ fn buildOutputType(
36743679 arg_mode,
36753680 all_args,
36763681 runtime_args_start,
3682 env_map,
36773683 );
36783684 return cleanExit(io);
36793685 },
......@@ -3686,7 +3692,7 @@ fn buildOutputType(
36863692 defer root_prog_node.end();
36873693
36883694 if (arg_mode == .translate_c) {
3689 return cmdTranslateC(comp, arena, null, null, root_prog_node);
3695 return cmdTranslateC(comp, arena, null, null, root_prog_node, env_map);
36903696 }
36913697
36923698 updateModule(comp, color, root_prog_node) catch |err| switch (err) {
......@@ -3754,6 +3760,7 @@ fn buildOutputType(
37543760 all_args,
37553761 runtime_args_start,
37563762 create_module.resolved_options.link_libc,
3763 env_map,
37573764 );
37583765 }
37593766
......@@ -3809,6 +3816,7 @@ fn createModule(
38093816 index: usize,
38103817 parent: ?*Package.Module,
38113818 color: std.zig.Color,
3819 env_map: *process.Environ.Map,
38123820) Allocator.Error!*Package.Module {
38133821 const cli_mod = &create_module.modules.values()[index];
38143822 if (cli_mod.resolved) |m| return m;
......@@ -3988,7 +3996,7 @@ fn createModule(
39883996 resolved_target.is_native_os and resolved_target.is_native_abi and
39893997 create_module.want_native_include_dirs)
39903998 {
3991 var paths = std.zig.system.NativePaths.detect(arena, io, target) catch |err|
3999 var paths = std.zig.system.NativePaths.detect(arena, io, target, env_map) catch |err|
39924000 fatal("unable to detect native system paths: {t}", .{err});
39934001 for (paths.warnings.items) |warning| {
39944002 warn("{s}", .{warning});
......@@ -4015,6 +4023,7 @@ fn createModule(
40154023 create_module.libc_installation = LibCInstallation.findNative(arena, io, .{
40164024 .verbose = true,
40174025 .target = target,
4026 .env_map = env_map,
40184027 }) catch |err| {
40194028 fatal("unable to find native libc installation: {t}", .{err});
40204029 };
......@@ -4119,7 +4128,7 @@ fn createModule(
41194128 for (cli_mod.deps) |dep| {
41204129 const dep_index = create_module.modules.getIndex(dep.value) orelse
41214130 fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key });
4122 const dep_mod = try createModule(gpa, arena, io, create_module, dep_index, mod, color);
4131 const dep_mod = try createModule(gpa, arena, io, create_module, dep_index, mod, color, env_map);
41234132 try mod.deps.put(arena, dep.key, dep_mod);
41244133 }
41254134
......@@ -4128,9 +4137,7 @@ fn createModule(
41284137
41294138fn saveState(comp: *Compilation, incremental: bool) void {
41304139 if (incremental) {
4131 comp.saveState() catch |err| {
4132 warn("unable to save incremental compilation state: {s}", .{@errorName(err)});
4133 };
4140 comp.saveState() catch |err| warn("unable to save incremental compilation state: {t}", .{err});
41344141 }
41354142}
41364143
......@@ -4143,6 +4150,7 @@ fn serve(
41434150 arg_mode: ArgMode,
41444151 all_args: []const []const u8,
41454152 runtime_args_start: ?usize,
4153 env_map: *process.Environ.Map,
41464154) !void {
41474155 const gpa = comp.gpa;
41484156 const io = comp.io;
......@@ -4190,7 +4198,7 @@ fn serve(
41904198 defer arena_instance.deinit();
41914199 const arena = arena_instance.allocator();
41924200 var output: Compilation.CImportResult = undefined;
4193 try cmdTranslateC(comp, arena, &output, file_system_inputs, main_progress_node);
4201 try cmdTranslateC(comp, arena, &output, file_system_inputs, main_progress_node, env_map);
41944202 defer output.deinit(gpa);
41954203
41964204 if (file_system_inputs.items.len != 0) {
......@@ -4390,6 +4398,7 @@ fn runOrTest(
43904398 all_args: []const []const u8,
43914399 runtime_args_start: ?usize,
43924400 link_libc: bool,
4401 env_map: *process.Environ.Map,
43934402) !void {
43944403 const raw_emit_bin = comp.emit_bin orelse return;
43954404 const exe_path = switch (comp.cache_use) {
......@@ -4426,77 +4435,90 @@ fn runOrTest(
44264435 if (runtime_args_start) |i| {
44274436 try argv.appendSlice(all_args[i..]);
44284437 }
4429 var env_map = try process.getEnvMap(arena);
44304438 try env_map.put("ZIG_EXE", self_exe_path);
44314439
44324440 // We do not execve for tests because if the test fails we want to print
44334441 // the error message and invocation below.
44344442 if (process.can_replace and arg_mode == .run) {
4435 // execv releases the locks; no need to destroy the Compilation here.
4443 // process replacement releases the locks; no need to destroy the Compilation here.
44364444 _ = try io.lockStderr(&.{}, .no_color);
4437 const err = process.execve(gpa, argv.items, &env_map);
4445 const err = process.replace(io, .{ .argv = argv.items, .env_map = env_map });
44384446 io.unlockStderr();
44394447 try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc);
44404448 const cmd = try std.mem.join(arena, " ", argv.items);
44414449 fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd });
4442 } else if (process.can_spawn) {
4443 var child = std.process.Child.init(argv.items, gpa);
4444 child.env_map = &env_map;
4445 child.stdin_behavior = .inherit;
4446 child.stdout_behavior = .inherit;
4447 child.stderr_behavior = .inherit;
4448
4450 } else if (!process.can_spawn) {
4451 const cmd = try std.mem.join(arena, " ", argv.items);
4452 fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{
4453 native_os, cmd,
4454 });
4455 }
4456 const term_result = (term: {
44494457 // Here we release all the locks associated with the Compilation so
44504458 // that whatever this child process wants to do won't deadlock.
44514459 comp.destroy();
44524460 comp_destroyed.* = true;
44534461
4454 const term_result = t: {
4455 _ = try io.lockStderr(&.{}, .no_color);
4456 defer io.unlockStderr();
4457 break :t child.spawnAndWait(io);
4458 };
4459 const term = term_result catch |err| {
4460 try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc);
4461 const cmd = try std.mem.join(arena, " ", argv.items);
4462 fatal("the following command failed with '{s}':\n{s}", .{ @errorName(err), cmd });
4463 };
4464 switch (arg_mode) {
4465 .run, .build => {
4466 switch (term) {
4467 .Exited => |code| {
4468 if (code == 0) {
4469 return cleanExit(io);
4470 } else {
4471 process.exit(code);
4472 }
4473 },
4474 else => {
4475 process.exit(1);
4476 },
4477 }
4478 },
4479 .zig_test => {
4480 switch (term) {
4481 .Exited => |code| {
4482 if (code == 0) {
4483 return cleanExit(io);
4484 } else {
4485 const cmd = try std.mem.join(arena, " ", argv.items);
4486 fatal("the following test command failed with exit code {d}:\n{s}", .{ code, cmd });
4487 }
4488 },
4489 else => {
4490 const cmd = try std.mem.join(arena, " ", argv.items);
4491 fatal("the following test command crashed:\n{s}", .{cmd});
4492 },
4493 }
4494 },
4495 else => unreachable,
4496 }
4497 } else {
4462 _ = try io.lockStderr(&.{}, .no_color);
4463 defer io.unlockStderr();
4464
4465 var child = std.process.spawn(io, .{
4466 .argv = argv.items,
4467 .env_map = env_map,
4468 .stdin = .inherit,
4469 .stdout = .inherit,
4470 .stderr = .inherit,
4471 }) catch |err| break :term err;
4472 defer child.kill(io);
4473
4474 break :term child.wait(io);
4475 });
4476
4477 const term = term_result catch |err| {
4478 try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc);
44984479 const cmd = try std.mem.join(arena, " ", argv.items);
4499 fatal("the following command cannot be executed ({s} does not support spawning a child process):\n{s}", .{ @tagName(native_os), cmd });
4480 fatal("the following command failed with {t}:\n{s}", .{ err, cmd });
4481 };
4482 switch (arg_mode) {
4483 .run, .build => {
4484 switch (term) {
4485 .exited => |code| {
4486 if (code == 0) {
4487 return cleanExit(io);
4488 } else {
4489 process.exit(code);
4490 }
4491 },
4492 .signal => |sig| {
4493 const cmd = try std.mem.join(arena, " ", argv.items);
4494 fatal("the following command terminated with signal {t}:\n{s}", .{ sig, cmd });
4495 },
4496 else => {
4497 process.exit(1);
4498 },
4499 }
4500 },
4501 .zig_test => {
4502 switch (term) {
4503 .exited => |code| {
4504 if (code == 0) {
4505 return cleanExit(io);
4506 } else {
4507 const cmd = try std.mem.join(arena, " ", argv.items);
4508 fatal("the following test command failed with exit code {d}:\n{s}", .{ code, cmd });
4509 }
4510 },
4511 .signal => |sig| {
4512 const cmd = try std.mem.join(arena, " ", argv.items);
4513 fatal("the following test command terminated with signal {t}:\n{s}", .{ sig, cmd });
4514 },
4515 else => {
4516 const cmd = try std.mem.join(arena, " ", argv.items);
4517 fatal("the following test command crashed:\n{s}", .{cmd});
4518 },
4519 }
4520 },
4521 else => unreachable,
45004522 }
45014523}
45024524
......@@ -4559,13 +4581,13 @@ fn runOrTestHotSwap(
45594581 try argv.appendSlice(all_args[i..]);
45604582 }
45614583
4562 var child = try std.process.spwan(io, .{
4584 var child = try std.process.spawn(io, .{
45634585 .argv = argv.items,
45644586 .stdin = .inherit,
45654587 .stdout = .inherit,
45664588 .stderr = .inherit,
45674589 });
4568 return child.id;
4590 return child.id.?;
45694591}
45704592
45714593const UpdateModuleError = Compilation.UpdateError || error{
......@@ -4597,6 +4619,7 @@ fn cmdTranslateC(
45974619 fancy_output: ?*Compilation.CImportResult,
45984620 file_system_inputs: ?*std.ArrayList(u8),
45994621 prog_node: std.Progress.Node,
4622 env_map: *process.Environ.Map,
46004623) !void {
46014624 dev.check(.translate_c_command);
46024625
......@@ -4630,6 +4653,7 @@ fn cmdTranslateC(
46304653 translated_basename,
46314654 comp.root_mod,
46324655 prog_node,
4656 env_map,
46334657 );
46344658
46354659 if (result.errors.errorMessageCount() != 0) {
......@@ -4677,10 +4701,11 @@ pub fn translateC(
46774701 arena: Allocator,
46784702 io: Io,
46794703 argv: []const []const u8,
4704 env_map: *process.Environ.Map,
46804705 prog_node: std.Progress.Node,
46814706 capture: ?*[]u8,
46824707) !void {
4683 try jitCmd(gpa, arena, io, argv, .{
4708 try jitCmd(gpa, arena, io, argv, env_map, .{
46844709 .cmd_name = "translate-c",
46854710 .root_src_path = "translate-c/main.zig",
46864711 .depend_on_aro = true,
......@@ -4837,21 +4862,21 @@ test sanitizeExampleName {
48374862 try std.testing.expectEqualStrings("test_project", try sanitizeExampleName(arena, "test project"));
48384863}
48394864
4840fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8) !void {
4865fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8, env_map: *process.Environ.Map) !void {
48414866 dev.check(.build_command);
48424867
48434868 var build_file: ?[]const u8 = null;
4844 var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);
4845 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
4846 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);
4847 var override_build_runner: ?[]const u8 = try EnvVar.ZIG_BUILD_RUNNER.get(arena);
4869 var override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(env_map);
4870 var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
4871 var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(env_map);
4872 var override_build_runner: ?[]const u8 = EnvVar.ZIG_BUILD_RUNNER.get(env_map);
48484873 var child_argv = std.array_list.Managed([]const u8).init(arena);
48494874 var reference_trace: ?u32 = null;
48504875 var debug_compile_errors = false;
48514876 var verbose_link = (native_os != .wasi or builtin.link_libc) and
4852 EnvVar.ZIG_VERBOSE_LINK.isSet();
4877 EnvVar.ZIG_VERBOSE_LINK.isSet(env_map);
48534878 var verbose_cc = (native_os != .wasi or builtin.link_libc) and
4854 EnvVar.ZIG_VERBOSE_CC.isSet();
4879 EnvVar.ZIG_VERBOSE_CC.isSet(env_map);
48554880 var verbose_air = false;
48564881 var verbose_intern_pool = false;
48574882 var verbose_generic_instances = false;
......@@ -5048,7 +5073,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
50485073 }
50495074
50505075 const work_around_btrfs_bug = native_os == .linux and
5051 EnvVar.ZIG_BTRFS_WORKAROUND.isSet();
5076 EnvVar.ZIG_BTRFS_WORKAROUND.isSet(env_map);
50525077 const root_prog_node = std.Progress.start(io, .{
50535078 .disable_printing = (color == .off),
50545079 .root_name = "Compile Build Script",
......@@ -5108,6 +5133,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
51085133 } },
51095134 {},
51105135 self_exe_path,
5136 env_map,
51115137 );
51125138 defer dirs.deinit(io);
51135139
......@@ -5210,7 +5236,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
52105236 job_queue.read_only = true;
52115237 cleanup_build_dir = job_queue.global_cache.handle;
52125238 } else {
5213 try http_client.initDefaultProxies(arena);
5239 try http_client.initDefaultProxies(arena, env_map);
52145240 }
52155241
52165242 try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1);
......@@ -5364,6 +5390,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
53645390 .cache_mode = .whole,
53655391 .reference_trace = reference_trace,
53665392 .debug_compile_errors = debug_compile_errors,
5393 .environ_map = env_map,
53675394 }) catch |err| switch (err) {
53685395 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
53695396 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),
......@@ -5385,81 +5412,81 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
53855412 });
53865413 }
53875414
5388 if (process.can_spawn) {
5389 var child = std.process.Child.init(child_argv.items, gpa);
5390 child.stdin_behavior = .inherit;
5391 child.stdout_behavior = .inherit;
5392 child.stderr_behavior = .inherit;
5393
5394 const term = t: {
5395 _ = try io.lockStderr(&.{}, .no_color);
5396 defer io.unlockStderr();
5397 break :t child.spawnAndWait(io) catch |err|
5398 fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err });
5399 };
5400
5401 switch (term) {
5402 .Exited => |code| {
5403 if (code == 0) return cleanExit(io);
5404 // Indicates that the build runner has reported compile errors
5405 // and this parent process does not need to report any further
5406 // diagnostics.
5407 if (code == 2) process.exit(2);
5408
5409 if (code == 3) {
5410 if (!dev.env.supports(.fetch_command)) process.exit(3);
5411 // Indicates the configure phase failed due to missing lazy
5412 // dependencies and stdout contains the hashes of the ones
5413 // that are missing.
5414 const s = fs.path.sep_str;
5415 const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce;
5416 const stdout = dirs.local_cache.handle.readFileAlloc(io, tmp_sub_path, arena, .limited(50 * 1024 * 1024)) catch |err| {
5417 fatal("unable to read results of configure phase from '{f}{s}': {s}", .{
5418 dirs.local_cache, tmp_sub_path, @errorName(err),
5415 if (!process.can_spawn) {
5416 const cmd = try std.mem.join(arena, " ", child_argv.items);
5417 fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{ native_os, cmd });
5418 }
5419 switch (term: {
5420 _ = try io.lockStderr(&.{}, .no_color);
5421 defer io.unlockStderr();
5422 var child = std.process.spawn(io, .{
5423 .argv = child_argv.items,
5424 }) catch |err| fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err });
5425 defer child.kill(io);
5426 break :term child.wait(io) catch |err|
5427 fatal("failed to wait build runner {s}: {t}", .{ child_argv.items[0], err });
5428 }) {
5429 .exited => |code| {
5430 if (code == 0) return cleanExit(io);
5431 // Indicates that the build runner has reported compile errors
5432 // and this parent process does not need to report any further
5433 // diagnostics.
5434 if (code == 2) process.exit(2);
5435
5436 if (code == 3) {
5437 if (!dev.env.supports(.fetch_command)) process.exit(3);
5438 // Indicates the configure phase failed due to missing lazy
5439 // dependencies and stdout contains the hashes of the ones
5440 // that are missing.
5441 const s = fs.path.sep_str;
5442 const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce;
5443 const stdout = dirs.local_cache.handle.readFileAlloc(io, tmp_sub_path, arena, .limited(50 * 1024 * 1024)) catch |err| {
5444 fatal("unable to read results of configure phase from '{f}{s}': {t}", .{
5445 dirs.local_cache, tmp_sub_path, err,
5446 });
5447 };
5448 dirs.local_cache.handle.deleteFile(io, tmp_sub_path) catch {};
5449
5450 var it = mem.splitScalar(u8, stdout, '\n');
5451 var any_errors = false;
5452 while (it.next()) |hash| {
5453 if (hash.len == 0) continue;
5454 if (hash.len > Package.Hash.max_len) {
5455 std.log.err("invalid digest (length {d} exceeds maximum): '{s}'", .{
5456 hash.len, hash,
54195457 });
5420 };
5421 dirs.local_cache.handle.deleteFile(io, tmp_sub_path) catch {};
5422
5423 var it = mem.splitScalar(u8, stdout, '\n');
5424 var any_errors = false;
5425 while (it.next()) |hash| {
5426 if (hash.len == 0) continue;
5427 if (hash.len > Package.Hash.max_len) {
5428 std.log.err("invalid digest (length {d} exceeds maximum): '{s}'", .{
5429 hash.len, hash,
5430 });
5431 any_errors = true;
5432 continue;
5433 }
5434 try unlazy_set.put(arena, .fromSlice(hash), {});
5458 any_errors = true;
5459 continue;
54355460 }
5436 if (any_errors) process.exit(3);
5437 if (system_pkg_dir_path) |p| {
5438 // In this mode, the system needs to provide these packages; they
5439 // cannot be fetched by Zig.
5440 for (unlazy_set.keys()) |*hash| {
5441 std.log.err("lazy dependency package not found: {s}" ++ s ++ "{s}", .{
5442 p, hash.toSlice(),
5443 });
5444 }
5445 std.log.info("remote package fetching disabled due to --system mode", .{});
5446 std.log.info("dependencies might be avoidable depending on build configuration", .{});
5447 process.exit(3);
5461 try unlazy_set.put(arena, .fromSlice(hash), {});
5462 }
5463 if (any_errors) process.exit(3);
5464 if (system_pkg_dir_path) |p| {
5465 // In this mode, the system needs to provide these packages; they
5466 // cannot be fetched by Zig.
5467 for (unlazy_set.keys()) |*hash| {
5468 std.log.err("lazy dependency package not found: {s}" ++ s ++ "{s}", .{
5469 p, hash.toSlice(),
5470 });
54485471 }
5449 continue;
5472 std.log.info("remote package fetching disabled due to --system mode", .{});
5473 std.log.info("dependencies might be avoidable depending on build configuration", .{});
5474 process.exit(3);
54505475 }
5476 continue;
5477 }
54515478
5452 const cmd = try std.mem.join(arena, " ", child_argv.items);
5453 fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });
5454 },
5455 else => {
5456 const cmd = try std.mem.join(arena, " ", child_argv.items);
5457 fatal("the following build command crashed:\n{s}", .{cmd});
5458 },
5459 }
5460 } else {
5461 const cmd = try std.mem.join(arena, " ", child_argv.items);
5462 fatal("the following command cannot be executed ({s} does not support spawning a child process):\n{s}", .{ @tagName(native_os), cmd });
5479 const cmd = try std.mem.join(arena, " ", child_argv.items);
5480 fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });
5481 },
5482 .signal => |sig| {
5483 const cmd = try std.mem.join(arena, " ", child_argv.items);
5484 fatal("the following build command terminated with signal {t}:\n{s}", .{ sig, cmd });
5485 },
5486 else => {
5487 const cmd = try std.mem.join(arena, " ", child_argv.items);
5488 fatal("the following build command crashed:\n{s}", .{cmd});
5489 },
54635490 }
54645491 }
54655492}
......@@ -5482,6 +5509,7 @@ fn jitCmd(
54825509 arena: Allocator,
54835510 io: Io,
54845511 args: []const []const u8,
5512 env_map: *process.Environ.Map,
54855513 options: JitCmdOptions,
54865514) !void {
54875515 dev.check(.jit_command);
......@@ -5503,13 +5531,13 @@ fn jitCmd(
55035531 const self_exe_path = process.executablePathAlloc(io, arena) catch |err|
55045532 fatal("unable to find self exe path: {t}", .{err});
55055533
5506 const optimize_mode: std.builtin.OptimizeMode = if (EnvVar.ZIG_DEBUG_CMD.isSet())
5534 const optimize_mode: std.builtin.OptimizeMode = if (EnvVar.ZIG_DEBUG_CMD.isSet(env_map))
55075535 .Debug
55085536 else
55095537 .ReleaseFast;
55105538 const strip = optimize_mode != .Debug;
5511 const override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);
5512 const override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
5539 const override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(env_map);
5540 const override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
55135541
55145542 // This `init` calls `fatal` on error.
55155543 var dirs: Compilation.Directories = .init(
......@@ -5520,6 +5548,7 @@ fn jitCmd(
55205548 .global,
55215549 if (native_os == .wasi) wasi_preopens,
55225550 self_exe_path,
5551 env_map,
55235552 );
55245553 defer dirs.deinit(io);
55255554
......@@ -5593,6 +5622,7 @@ fn jitCmd(
55935622 .self_exe_path = self_exe_path,
55945623 .thread_limit = thread_limit,
55955624 .cache_mode = .whole,
5625 .environ_map = env_map,
55965626 }) catch |err| switch (err) {
55975627 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
55985628 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),
......@@ -5639,31 +5669,33 @@ fn jitCmd(
56395669 child_argv.appendSliceAssumeCapacity(args);
56405670
56415671 if (process.can_replace and options.capture == null) {
5642 if (EnvVar.ZIG_DEBUG_CMD.isSet()) {
5672 if (EnvVar.ZIG_DEBUG_CMD.isSet(env_map)) {
56435673 const cmd = try std.mem.join(arena, " ", child_argv.items);
56445674 std.debug.print("{s}\n", .{cmd});
56455675 }
5646 const err = process.execv(gpa, child_argv.items);
5676 const err = process.replace(io, .{ .argv = child_argv.items, .env_map = env_map });
56475677 const cmd = try std.mem.join(arena, " ", child_argv.items);
56485678 fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd });
56495679 }
56505680
56515681 if (!process.can_spawn) {
56525682 const cmd = try std.mem.join(arena, " ", child_argv.items);
5653 fatal("the following command cannot be executed ({s} does not support spawning a child process):\n{s}", .{
5654 @tagName(native_os), cmd,
5683 fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{
5684 native_os, cmd,
56555685 });
56565686 }
56575687
5658 var child = std.process.Child.init(child_argv.items, gpa);
5659 child.stdin_behavior = .inherit;
5660 child.stdout_behavior = if (options.capture == null) .inherit else .pipe;
5661 child.stderr_behavior = .inherit;
5662
5663 const term = t: {
5688 switch (t: {
56645689 _ = try io.lockStderr(&.{}, .no_color);
56655690 defer io.unlockStderr();
5666 try child.spawn(io);
5691
5692 var child = std.process.spawn(io, .{
5693 .argv = child_argv.items,
5694 .stdin = .inherit,
5695 .stdout = if (options.capture == null) .inherit else .pipe,
5696 .stderr = .inherit,
5697 }) catch |err| fatal("failed to spawn {s}: {t}", .{ child_argv.items[0], err });
5698 defer child.kill(io);
56675699
56685700 if (options.capture) |ptr| {
56695701 var stdout_reader = child.stdout.?.readerStreaming(io, &.{});
......@@ -5671,9 +5703,8 @@ fn jitCmd(
56715703 }
56725704
56735705 break :t try child.wait(io);
5674 };
5675 switch (term) {
5676 .Exited => |code| {
5706 }) {
5707 .exited => |code| {
56775708 if (code == 0) {
56785709 if (options.capture != null) return;
56795710 return cleanExit(io);
......@@ -5681,6 +5712,10 @@ fn jitCmd(
56815712 const cmd = try std.mem.join(arena, " ", child_argv.items);
56825713 fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });
56835714 },
5715 .signal => |sig| {
5716 const cmd = try std.mem.join(arena, " ", child_argv.items);
5717 fatal("the following build command terminated with signal {t}:\n{s}", .{ sig, cmd });
5718 },
56845719 else => {
56855720 const cmd = try std.mem.join(arena, " ", child_argv.items);
56865721 fatal("the following build command crashed:\n{s}", .{cmd});
......@@ -5796,7 +5831,7 @@ pub fn lldMain(
57965831 return @intFromBool(!ok);
57975832}
57985833
5799const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, .single_quotes = true });
5834const ArgIteratorResponseFile = process.Args.IteratorGeneral(.{ .comments = true, .single_quotes = true });
58005835
58015836/// Initialize the arguments from a Response File. "*.rsp"
58025837fn initArgIteratorResponseFile(allocator: Allocator, io: Io, resp_file_path: []const u8) !ArgIteratorResponseFile {
......@@ -6872,14 +6907,15 @@ fn cmdFetch(
68726907 arena: Allocator,
68736908 io: Io,
68746909 args: []const []const u8,
6910 env_map: *process.Environ.Map,
68756911) !void {
68766912 dev.check(.fetch_command);
68776913
68786914 const color: Color = .auto;
68796915 const work_around_btrfs_bug = native_os == .linux and
6880 EnvVar.ZIG_BTRFS_WORKAROUND.isSet();
6916 EnvVar.ZIG_BTRFS_WORKAROUND.isSet(env_map);
68816917 var opt_path_or_url: ?[]const u8 = null;
6882 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
6918 var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
68836919 var debug_hash: bool = false;
68846920 var save: union(enum) {
68856921 no,
......@@ -6925,7 +6961,7 @@ fn cmdFetch(
69256961 var http_client: std.http.Client = .{ .allocator = gpa, .io = io };
69266962 defer http_client.deinit();
69276963
6928 try http_client.initDefaultProxies(arena);
6964 try http_client.initDefaultProxies(arena, env_map);
69296965
69306966 var root_prog_node = std.Progress.start(io, .{
69316967 .root_name = "Fetch",
......@@ -6933,7 +6969,7 @@ fn cmdFetch(
69336969 defer root_prog_node.end();
69346970
69356971 var global_cache_directory: Directory = l: {
6936 const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena);
6972 const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena, env_map);
69376973 break :l .{
69386974 .handle = try Io.Dir.cwd().createDirPathOpen(io, p, .{}),
69396975 .path = p,
src/print_env.zig+6-4
......@@ -19,9 +19,10 @@ pub fn cmdEnv(
1919 else => void,
2020 },
2121 host: *const std.Target,
22 env_map: *std.process.Environ.Map,
2223) !void {
23 const override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);
24 const override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
24 const override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(env_map);
25 const override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
2526
2627 const self_exe_path = switch (builtin.target.os.tag) {
2728 .wasi => args[0],
......@@ -38,6 +39,7 @@ pub fn cmdEnv(
3839 .global,
3940 if (builtin.target.os.tag == .wasi) wasi_preopens,
4041 if (builtin.target.os.tag != .wasi) self_exe_path,
42 env_map,
4143 );
4244 defer dirs.deinit(io);
4345
......@@ -56,8 +58,8 @@ pub fn cmdEnv(
5658 try root.field("version", build_options.version, .{});
5759 try root.field("target", triple, .{});
5860 var env = try root.beginStructField("env", .{});
59 inline for (@typeInfo(std.zig.EnvVar).@"enum".fields) |field| {
60 try env.field(field.name, try @field(std.zig.EnvVar, field.name).get(arena), .{});
61 inline for (@typeInfo(EnvVar).@"enum".fields) |field| {
62 try env.field(field.name, @field(EnvVar, field.name).get(env_map), .{});
6163 }
6264 try env.end();
6365 try root.end();