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 {...@@ -1307,7 +1307,7 @@ pub fn deinit(client: *Client) void {
1307/// Asserts the client has no active connections.1307/// Asserts the client has no active connections.
1308/// Uses `arena` for a few small allocations that must outlive the client, or1308/// Uses `arena` for a few small allocations that must outlive the client, or
1309/// at least until those fields are set to different values.1309/// 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 {
1311 // Prevent any new connections from being created.1311 // Prevent any new connections from being created.
1312 client.connection_pool.mutex.lock();1312 client.connection_pool.mutex.lock();
1313 defer client.connection_pool.mutex.unlock();1313 defer client.connection_pool.mutex.unlock();
...@@ -1315,27 +1315,26 @@ pub fn initDefaultProxies(client: *Client, arena: Allocator) !void {...@@ -1315,27 +1315,26 @@ pub fn initDefaultProxies(client: *Client, arena: Allocator) !void {
1315 assert(client.connection_pool.used.first == null); // There are active requests.1315 assert(client.connection_pool.used.first == null); // There are active requests.
13161316
1317 if (client.http_proxy == null) {1317 if (client.http_proxy == null) {
1318 client.http_proxy = try createProxyFromEnvVar(arena, &.{1318 client.http_proxy = try createProxyFromEnvVar(arena, env_map, &.{
1319 "http_proxy", "HTTP_PROXY", "all_proxy", "ALL_PROXY",1319 "http_proxy", "HTTP_PROXY", "all_proxy", "ALL_PROXY",
1320 });1320 });
1321 }1321 }
13221322
1323 if (client.https_proxy == null) {1323 if (client.https_proxy == null) {
1324 client.https_proxy = try createProxyFromEnvVar(arena, &.{1324 client.https_proxy = try createProxyFromEnvVar(arena, env_map, &.{
1325 "https_proxy", "HTTPS_PROXY", "all_proxy", "ALL_PROXY",1325 "https_proxy", "HTTPS_PROXY", "all_proxy", "ALL_PROXY",
1326 });1326 });
1327 }1327 }
1328}1328}
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 {
1331 const content = for (env_var_names) |name| {1335 const content = for (env_var_names) |name| {
1332 const content = std.process.getEnvVarOwned(arena, name) catch |err| switch (err) {1336 const content = env_map.get(name) orelse continue;
1333 error.EnvironmentVariableNotFound => continue,
1334 else => |e| return e,
1335 };
1336
1337 if (content.len == 0) continue;1337 if (content.len == 0) continue;
1338
1339 break content;1338 break content;
1340 } else return null;1339 } 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 {...@@ -516,7 +516,7 @@ pub fn freeSlice(gpa: Allocator, to_slice_result: []const [:0]u8) void {
516}516}
517517
518test "Iterator.Windows" {518test "Iterator.Windows" {
519 const t = testArgIteratorWindows;519 const t = testIteratorWindows;
520520
521 try t(521 try t(
522 \\"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\")"522 \\"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" {...@@ -648,7 +648,7 @@ test "Iterator.Windows" {
648 try t("foo.exe \"\xed\xa0\x81\"\xed\xb0\xb7", &.{ "foo.exe", "𐐷" });648 try t("foo.exe \"\xed\xa0\x81\"\xed\xb0\xb7", &.{ "foo.exe", "𐐷" });
649}649}
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 {
652 const cmd_line_w = try std.unicode.wtf8ToWtf16LeAllocZ(testing.allocator, cmd_line);652 const cmd_line_w = try std.unicode.wtf8ToWtf16LeAllocZ(testing.allocator, cmd_line);
653 defer testing.allocator.free(cmd_line_w);653 defer testing.allocator.free(cmd_line_w);
654654
...@@ -679,7 +679,7 @@ fn testArgIteratorWindows(cmd_line: []const u8, expected_args: []const []const u...@@ -679,7 +679,7 @@ fn testArgIteratorWindows(cmd_line: []const u8, expected_args: []const []const u
679 }679 }
680}680}
681681
682test "general arg parsing" {682test "general parsing" {
683 try testGeneralCmdLine("a b\tc d", &.{ "a", "b", "c", "d" });683 try testGeneralCmdLine("a b\tc d", &.{ "a", "b", "c", "d" });
684 try testGeneralCmdLine("\"abc\" d e", &.{ "abc", "d", "e" });684 try testGeneralCmdLine("\"abc\" d e", &.{ "abc", "d", "e" });
685 try testGeneralCmdLine("a\\\\\\b d\"e f\"g h", &.{ "a\\\\\\b", "de fg", "h" });685 try testGeneralCmdLine("a\\\\\\b d\"e f\"g h", &.{ "a\\\\\\b", "de fg", "h" });
...@@ -703,7 +703,7 @@ test "general arg parsing" {...@@ -703,7 +703,7 @@ test "general arg parsing" {
703}703}
704704
705fn testGeneralCmdLine(input_cmd_line: []const u8, expected_args: []const []const u8) !void {705fn 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);
707 defer it.deinit();707 defer it.deinit();
708 for (expected_args) |expected_arg| {708 for (expected_args) |expected_arg| {
709 const arg = it.next().?;709 const arg = it.next().?;
...@@ -712,14 +712,14 @@ fn testGeneralCmdLine(input_cmd_line: []const u8, expected_args: []const []const...@@ -712,14 +712,14 @@ fn testGeneralCmdLine(input_cmd_line: []const u8, expected_args: []const []const
712 try testing.expect(it.next() == null);712 try testing.expect(it.next() == null);
713}713}
714714
715/// Optional parameters for `ArgIteratorGeneral`715/// Optional parameters for `IteratorGeneral`
716pub const ArgIteratorGeneralOptions = struct {716pub const IteratorGeneralOptions = struct {
717 comments: bool = false,717 comments: bool = false,
718 single_quotes: bool = false,718 single_quotes: bool = false,
719};719};
720720
721/// A general Iterator to parse a string into a set of arguments721/// 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 {
723 return struct {723 return struct {
724 allocator: Allocator,724 allocator: Allocator,
725 index: usize = 0,725 index: usize = 0,
...@@ -947,7 +947,7 @@ test "response file arg parsing" {...@@ -947,7 +947,7 @@ test "response file arg parsing" {
947}947}
948948
949fn testResponseFileCmdLine(input_cmd_line: []const u8, expected_args: []const []const u8) !void {949fn 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 })
951 .init(std.testing.allocator, input_cmd_line);951 .init(std.testing.allocator, input_cmd_line);
952 defer it.deinit();952 defer it.deinit();
953 for (expected_args) |expected_arg| {953 for (expected_args) |expected_arg| {
lib/std/process/Environ.zig+1-1
...@@ -20,7 +20,7 @@ const mem = std.mem;...@@ -20,7 +20,7 @@ const mem = std.mem;
20block: Block,20block: Block,
2121
22pub const Block = switch (native_os) {22pub const Block = switch (native_os) {
23 .windows => []const u16,23 .windows => [*:0]const u16,
24 .wasi => switch (builtin.link_libc) {24 .wasi => switch (builtin.link_libc) {
25 false => void,25 false => void,
26 true => [:null]const ?[*:0]const u8,26 true => [:null]const ?[*:0]const u8,
lib/std/start.zig+5-2
...@@ -524,9 +524,12 @@ fn WinStartup() callconv(.withStackAlign(.c, 1)) noreturn {...@@ -524,9 +524,12 @@ fn WinStartup() callconv(.withStackAlign(.c, 1)) noreturn {
524524
525 std.debug.maybeEnableSegfaultHandler();525 std.debug.maybeEnableSegfaultHandler();
526526
527 const peb = std.os.windows.peb();
528 const cmd_line = std.os.windows.peb().ProcessParameters.CommandLine;
529
527 std.os.windows.ntdll.RtlExitUserProcess(callMain(530 std.os.windows.ntdll.RtlExitUserProcess(callMain(
528 std.os.windows.peb().ProcessParameters.CommandLine,531 cmd_line.Buffer.?[0..@divExact(cmd_line.Length, 2)],
529 std.os.windows.peb().ProcessParameters.Environment,532 peb.ProcessParameters.Environment,
530 ));533 ));
531}534}
532535
lib/std/zig.zig+9
...@@ -741,9 +741,18 @@ pub const EnvVar = enum {...@@ -741,9 +741,18 @@ pub const EnvVar = enum {
741 ZIG_DEBUG_CMD,741 ZIG_DEBUG_CMD,
742 ZIG_IS_DETECTING_LIBC_PATHS,742 ZIG_IS_DETECTING_LIBC_PATHS,
743 ZIG_IS_TRYING_TO_NOT_CALL_ITSELF,743 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,
744 CC,751 CC,
752
745 NO_COLOR,753 NO_COLOR,
746 CLICOLOR_FORCE,754 CLICOLOR_FORCE,
755
747 XDG_CACHE_HOME,756 XDG_CACHE_HOME,
748 LOCALAPPDATA,757 LOCALAPPDATA,
749 HOME,758 HOME,
lib/std/zig/LibCDirs.zig+11-3
...@@ -28,6 +28,7 @@ pub fn detect(...@@ -28,6 +28,7 @@ pub fn detect(
28 is_native_abi: bool,28 is_native_abi: bool,
29 link_libc: bool,29 link_libc: bool,
30 libc_installation: ?*const LibCInstallation,30 libc_installation: ?*const LibCInstallation,
31 env_map: *const std.process.Environ.Map,
31) LibCInstallation.FindError!LibCDirs {32) LibCInstallation.FindError!LibCDirs {
32 if (!link_libc) {33 if (!link_libc) {
33 return .{34 return .{
...@@ -47,7 +48,10 @@ pub fn detect(...@@ -47,7 +48,10 @@ pub fn detect(
47 // using the system libc installation.48 // using the system libc installation.
48 if (is_native_abi and !target.isMinGW()) {49 if (is_native_abi and !target.isMinGW()) {
49 const libc = try arena.create(LibCInstallation);50 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) {
51 error.CCompilerExitCode,55 error.CCompilerExitCode,
52 error.CCompilerCrashed,56 error.CCompilerCrashed,
53 error.CCompilerCannotFindHeaders,57 error.CCompilerCannotFindHeaders,
...@@ -84,12 +88,16 @@ pub fn detect(...@@ -84,12 +88,16 @@ pub fn detect(
8488
85 if (use_system_abi) {89 if (use_system_abi) {
86 const libc = try arena.create(LibCInstallation);90 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 });
88 return detectFromInstallation(arena, target, libc);96 return detectFromInstallation(arena, target, libc);
89 }97 }
9098
91 return .{99 return .{
92 .libc_include_dir_list = &[0][]u8{},100 .libc_include_dir_list = &.{},
93 .libc_installation = null,101 .libc_installation = null,
94 .libc_framework_dir_list = &.{},102 .libc_framework_dir_list = &.{},
95 .sysroot = null,103 .sysroot = null,
lib/std/zig/LibCInstallation.zig+13-12
...@@ -167,6 +167,7 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {...@@ -167,6 +167,7 @@ pub fn render(self: LibCInstallation, out: *std.Io.Writer) !void {
167167
168pub const FindNativeOptions = struct {168pub const FindNativeOptions = struct {
169 target: *const std.Target,169 target: *const std.Target,
170 env_map: *const std.process.Environ.Map,
170171
171 /// If enabled, will print human-friendly errors to stderr.172 /// If enabled, will print human-friendly errors to stderr.
172 verbose: bool = false,173 verbose: bool = false,
...@@ -238,10 +239,7 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void {...@@ -238,10 +239,7 @@ pub fn deinit(self: *LibCInstallation, allocator: Allocator) void {
238239
239fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {240fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
240 // Detect infinite loops.241 // Detect infinite loops.
241 var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) {242 var env_map = try args.env_map.clone(gpa);
242 error.Unexpected => unreachable, // WASI-only
243 else => |e| return e,
244 };
245 defer env_map.deinit();243 defer env_map.deinit();
246 const skip_cc_env_var = if (env_map.get(inf_loop_env_key)) |phase| blk: {244 const skip_cc_env_var = if (env_map.get(inf_loop_env_key)) |phase| blk: {
247 if (std.mem.eql(u8, phase, "1")) {245 if (std.mem.eql(u8, phase, "1")) {
...@@ -260,7 +258,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar...@@ -260,7 +258,7 @@ fn findNativeIncludeDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, ar
260 var argv = std.array_list.Managed([]const u8).init(gpa);258 var argv = std.array_list.Managed([]const u8).init(gpa);
261 defer argv.deinit();259 defer argv.deinit();
262260
263 try appendCcExe(&argv, skip_cc_env_var);261 try appendCcExe(&argv, skip_cc_env_var, &env_map);
264 try argv.appendSlice(&.{262 try argv.appendSlice(&.{
265 "-E",263 "-E",
266 "-Wp,-v",264 "-Wp,-v",
...@@ -449,6 +447,7 @@ fn findNativeCrtDirWindows(...@@ -449,6 +447,7 @@ fn findNativeCrtDirWindows(
449447
450fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {448fn findNativeCrtDirPosix(self: *LibCInstallation, gpa: Allocator, io: Io, args: FindNativeOptions) FindError!void {
451 self.crt_dir = try ccPrintFileName(gpa, io, .{449 self.crt_dir = try ccPrintFileName(gpa, io, .{
450 .env_map = args.env_map,
452 .search_basename = switch (args.target.os.tag) {451 .search_basename = switch (args.target.os.tag) {
453 .linux => if (args.target.abi.isAndroid()) "crtbegin_dynamic.o" else "crt1.o",452 .linux => if (args.target.abi.isAndroid()) "crtbegin_dynamic.o" else "crt1.o",
454 else => "crt1.o",453 else => "crt1.o",
...@@ -553,6 +552,7 @@ fn findNativeMsvcLibDir(...@@ -553,6 +552,7 @@ fn findNativeMsvcLibDir(
553}552}
554553
555pub const CCPrintFileNameOptions = struct {554pub const CCPrintFileNameOptions = struct {
555 env_map: *const std.process.Environ.Map,
556 search_basename: []const u8,556 search_basename: []const u8,
557 want_dirname: enum { full_path, only_dir },557 want_dirname: enum { full_path, only_dir },
558 verbose: bool = false,558 verbose: bool = false,
...@@ -561,10 +561,7 @@ pub const CCPrintFileNameOptions = struct {...@@ -561,10 +561,7 @@ pub const CCPrintFileNameOptions = struct {
561/// caller owns returned memory561/// caller owns returned memory
562fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8 {562fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8 {
563 // Detect infinite loops.563 // Detect infinite loops.
564 var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) {564 var env_map = try args.env_map.clone(gpa);
565 error.Unexpected => unreachable, // WASI-only
566 else => |e| return e,
567 };
568 defer env_map.deinit();565 defer env_map.deinit();
569 const skip_cc_env_var = if (env_map.get(inf_loop_env_key)) |phase| blk: {566 const skip_cc_env_var = if (env_map.get(inf_loop_env_key)) |phase| blk: {
570 if (std.mem.eql(u8, phase, "1")) {567 if (std.mem.eql(u8, phase, "1")) {
...@@ -584,7 +581,7 @@ fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8...@@ -584,7 +581,7 @@ fn ccPrintFileName(gpa: Allocator, io: Io, args: CCPrintFileNameOptions) ![:0]u8
584 const arg1 = try std.fmt.allocPrint(gpa, "-print-file-name={s}", .{args.search_basename});581 const arg1 = try std.fmt.allocPrint(gpa, "-print-file-name={s}", .{args.search_basename});
585 defer gpa.free(arg1);582 defer gpa.free(arg1);
586583
587 try appendCcExe(&argv, skip_cc_env_var);584 try appendCcExe(&argv, skip_cc_env_var, &env_map);
588 try argv.append(arg1);585 try argv.append(arg1);
589586
590 const run_res = std.process.run(gpa, io, .{587 const run_res = std.process.run(gpa, io, .{
...@@ -672,14 +669,18 @@ fn fillInstallations(...@@ -672,14 +669,18 @@ fn fillInstallations(
672669
673const inf_loop_env_key = "ZIG_IS_DETECTING_LIBC_PATHS";670const 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 {
676 const default_cc_exe = if (is_windows) "cc.exe" else "cc";677 const default_cc_exe = if (is_windows) "cc.exe" else "cc";
677 try args.ensureUnusedCapacity(1);678 try args.ensureUnusedCapacity(1);
678 if (skip_cc_env_var) {679 if (skip_cc_env_var) {
679 args.appendAssumeCapacity(default_cc_exe);680 args.appendAssumeCapacity(default_cc_exe);
680 return;681 return;
681 }682 }
682 const cc_env_var = std.zig.EnvVar.CC.getPosix() orelse {683 const cc_env_var = std.zig.EnvVar.CC.get(env_map) orelse {
683 args.appendAssumeCapacity(default_cc_exe);684 args.appendAssumeCapacity(default_cc_exe);
684 return;685 return;
685 };686 };
lib/std/zig/WindowsSdk.zig+6-7
...@@ -951,15 +951,14 @@ const MsvcLibDir = struct {...@@ -951,15 +951,14 @@ const MsvcLibDir = struct {
951 return msvc_dir;951 return msvc_dir;
952 }952 }
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 {
955 var base_path: std.array_list.Managed(u8) = base_path: {960 var base_path: std.array_list.Managed(u8) = base_path: {
956 try_env: {961 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
963 if (env_map.get("VS140COMNTOOLS")) |VS140COMNTOOLS| {962 if (env_map.get("VS140COMNTOOLS")) |VS140COMNTOOLS| {
964 if (VS140COMNTOOLS.len < "C:\\Common7\\Tools".len) break :try_env;963 if (VS140COMNTOOLS.len < "C:\\Common7\\Tools".len) break :try_env;
965 if (!Dir.path.isAbsolute(VS140COMNTOOLS)) break :try_env;964 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,...@@ -14,10 +14,16 @@ framework_dirs: std.ArrayList([]const u8) = .empty,
14rpaths: std.ArrayList([]const u8) = .empty,14rpaths: std.ArrayList([]const u8) = .empty,
15warnings: std.ArrayList([]const u8) = .empty,15warnings: 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 {
18 var self: NativePaths = .{ .arena = arena };23 var self: NativePaths = .{ .arena = arena };
19 var is_nix = false;24 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| {
21 is_nix = true;27 is_nix = true;
22 var it = mem.tokenizeScalar(u8, nix_cflags_compile, ' ');28 var it = mem.tokenizeScalar(u8, nix_cflags_compile, ' ');
23 while (true) {29 while (true) {
...@@ -41,12 +47,9 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ...@@ -41,12 +47,9 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ
41 try self.addWarningFmt("Unrecognized C flag from NIX_CFLAGS_COMPILE: {s}", .{word});47 try self.addWarningFmt("Unrecognized C flag from NIX_CFLAGS_COMPILE: {s}", .{word});
42 }48 }
43 }49 }
44 } else |err| switch (err) {
45 error.InvalidWtf8 => unreachable,
46 error.EnvironmentVariableNotFound => {},
47 error.OutOfMemory => |e| return e,
48 }50 }
49 if (process.getEnvVarOwned(arena, "NIX_LDFLAGS")) |nix_ldflags| {51
52 if (std.zig.EnvVar.NIX_LDFLAGS.get(env_map)) |nix_ldflags| {
50 is_nix = true;53 is_nix = true;
51 var it = mem.tokenizeScalar(u8, nix_ldflags, ' ');54 var it = mem.tokenizeScalar(u8, nix_ldflags, ' ');
52 while (true) {55 while (true) {
...@@ -73,12 +76,9 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ...@@ -73,12 +76,9 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ
73 break;76 break;
74 }77 }
75 }78 }
76 } else |err| switch (err) {
77 error.InvalidWtf8 => unreachable,
78 error.EnvironmentVariableNotFound => {},
79 error.OutOfMemory => |e| return e,
80 }79 }
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| {
82 is_nix = true;82 is_nix = true;
83 var it = mem.tokenizeScalar(u8, nix_cflags_link, ' ');83 var it = mem.tokenizeScalar(u8, nix_cflags_link, ' ');
84 while (true) {84 while (true) {
...@@ -105,11 +105,8 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ...@@ -105,11 +105,8 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ
105 break;105 break;
106 }106 }
107 }107 }
108 } else |err| switch (err) {
109 error.InvalidWtf8 => unreachable,
110 error.EnvironmentVariableNotFound => {},
111 error.OutOfMemory => |e| return e,
112 }108 }
109
113 if (is_nix) {110 if (is_nix) {
114 return self;111 return self;
115 }112 }
...@@ -182,21 +179,21 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ...@@ -182,21 +179,21 @@ pub fn detect(arena: Allocator, io: Io, native_target: *const std.Target) !Nativ
182 // variables to search for headers and libraries.179 // variables to search for headers and libraries.
183 // We use os.getenv here since this part won't be executed on180 // We use os.getenv here since this part won't be executed on
184 // windows, to get rid of unnecessary error handling.181 // 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| {
186 var it = mem.tokenizeScalar(u8, c_include_path, ':');183 var it = mem.tokenizeScalar(u8, c_include_path, ':');
187 while (it.next()) |dir| {184 while (it.next()) |dir| {
188 try self.addIncludeDir(dir);185 try self.addIncludeDir(dir);
189 }186 }
190 }187 }
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| {
193 var it = mem.tokenizeScalar(u8, cplus_include_path, ':');190 var it = mem.tokenizeScalar(u8, cplus_include_path, ':');
194 while (it.next()) |dir| {191 while (it.next()) |dir| {
195 try self.addIncludeDir(dir);192 try self.addIncludeDir(dir);
196 }193 }
197 }194 }
198195
199 if (std.posix.getenv("LIBRARY_PATH")) |library_path| {196 if (std.zig.EnvVar.LIBRARY_PATH.get(env_map)) |library_path| {
200 var it = mem.tokenizeScalar(u8, library_path, ':');197 var it = mem.tokenizeScalar(u8, library_path, ':');
201 while (it.next()) |dir| {198 while (it.next()) |dir| {
202 try self.addLibDir(dir);199 try self.addLibDir(dir);
src/Compilation.zig+25-13
...@@ -54,6 +54,7 @@ gpa: Allocator,...@@ -54,6 +54,7 @@ gpa: Allocator,
54/// threads at once.54/// threads at once.
55arena: Allocator,55arena: Allocator,
56io: Io,56io: Io,
57environ_map: *std.process.Environ.Map,
57thread_limit: usize,58thread_limit: usize,
58/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.59/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
59zcu: ?*Zcu,60zcu: ?*Zcu,
...@@ -761,6 +762,7 @@ pub const Directories = struct {...@@ -761,6 +762,7 @@ pub const Directories = struct {
761 .wasi => void,762 .wasi => void,
762 else => []const u8,763 else => []const u8,
763 },764 },
765 env_map: *std.process.Environ.Map,
764 ) Directories {766 ) Directories {
765 const wasi = builtin.target.os.tag == .wasi;767 const wasi = builtin.target.os.tag == .wasi;
766768
...@@ -779,7 +781,7 @@ pub const Directories = struct {...@@ -779,7 +781,7 @@ pub const Directories = struct {
779 const global_cache: Cache.Directory = d: {781 const global_cache: Cache.Directory = d: {
780 if (override_global_cache) |path| break :d openUnresolved(arena, io, cwd, path, .@"global cache");782 if (override_global_cache) |path| break :d openUnresolved(arena, io, cwd, path, .@"global cache");
781 if (wasi) break :d openWasiPreopen(wasi_preopens, "/cache");783 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| {
783 fatal("unable to resolve zig cache directory: {t}", .{err});785 fatal("unable to resolve zig cache directory: {t}", .{err});
784 };786 };
785 break :d openUnresolved(arena, io, cwd, path, .@"global cache");787 break :d openUnresolved(arena, io, cwd, path, .@"global cache");
...@@ -1797,6 +1799,8 @@ pub const CreateOptions = struct {...@@ -1797,6 +1799,8 @@ pub const CreateOptions = struct {
17971799
1798 parent_whole_cache: ?ParentWholeCache = null,1800 parent_whole_cache: ?ParentWholeCache = null,
17991801
1802 environ_map: *std.process.Environ.Map,
1803
1800 pub const Entry = link.File.OpenOptions.Entry;1804 pub const Entry = link.File.OpenOptions.Entry;
18011805
1802 /// Which fields are valid depends on the `cache_mode` given.1806 /// 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,...@@ -1967,6 +1971,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
1967 options.root_mod.resolved_target.is_native_abi,1971 options.root_mod.resolved_target.is_native_abi,
1968 link_libc,1972 link_libc,
1969 options.libc_installation,1973 options.libc_installation,
1974 options.environ_map,
1970 ) catch |err| switch (err) {1975 ) catch |err| switch (err) {
1971 error.OutOfMemory => |e| return e,1976 error.OutOfMemory => |e| return e,
1972 // Every other error is specifically related to finding the native installation1977 // 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,...@@ -2306,6 +2311,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
2306 .emit_llvm_ir = try options.emit_llvm_ir.resolve(arena, &options, .llvm_ir),2311 .emit_llvm_ir = try options.emit_llvm_ir.resolve(arena, &options, .llvm_ir),
2307 .emit_llvm_bc = try options.emit_llvm_bc.resolve(arena, &options, .llvm_bc),2312 .emit_llvm_bc = try options.emit_llvm_bc.resolve(arena, &options, .llvm_bc),
2308 .emit_docs = try options.emit_docs.resolve(arena, &options, .docs),2313 .emit_docs = try options.emit_docs.resolve(arena, &options, .docs),
2314 .environ_map = options.environ_map,
2309 };2315 };
23102316
2311 errdefer {2317 errdefer {
...@@ -5503,6 +5509,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU...@@ -5503,6 +5509,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) SubU
5503 .verbose_llvm_bc = comp.verbose_llvm_bc,5509 .verbose_llvm_bc = comp.verbose_llvm_bc,
5504 .verbose_cimport = comp.verbose_cimport,5510 .verbose_cimport = comp.verbose_cimport,
5505 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,5511 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
5512 .environ_map = comp.environ_map,
5506 }) catch |err| switch (err) {5513 }) catch |err| switch (err) {
5507 error.CreateFail => {5514 error.CreateFail => {
5508 comp.lockAndSetMiscFailure(.docs_wasm, "sub-compilation of docs_wasm failed: {f}", .{sub_create_diag});5515 comp.lockAndSetMiscFailure(.docs_wasm, "sub-compilation of docs_wasm failed: {f}", .{sub_create_diag});
...@@ -5705,6 +5712,7 @@ pub fn translateC(...@@ -5705,6 +5712,7 @@ pub fn translateC(
5705 translated_basename: []const u8,5712 translated_basename: []const u8,
5706 owner_mod: *Package.Module,5713 owner_mod: *Package.Module,
5707 prog_node: std.Progress.Node,5714 prog_node: std.Progress.Node,
5715 env_map: *std.process.Environ.Map,
5708) !CImportResult {5716) !CImportResult {
5709 dev.check(.translate_c_command);5717 dev.check(.translate_c_command);
57105718
...@@ -5774,7 +5782,7 @@ pub fn translateC(...@@ -5774,7 +5782,7 @@ pub fn translateC(
5774 }5782 }
57755783
5776 var stdout: []u8 = undefined;5784 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
5779 if (out_dep_path) |dep_file_path| add_deps: {5787 if (out_dep_path) |dep_file_path| add_deps: {
5780 if (comp.verbose_cimport) log.info("processing dep file at {s}", .{dep_file_path});5788 if (comp.verbose_cimport) log.info("processing dep file at {s}", .{dep_file_path});
...@@ -5861,7 +5869,8 @@ pub fn cImport(...@@ -5861,7 +5869,8 @@ pub fn cImport(
5861 defer arena_allocator.deinit();5869 defer arena_allocator.deinit();
5862 const arena = arena_allocator.allocator();5870 const arena = arena_allocator.allocator();
58635871
5864 break :result try comp.translateC(5872 break :result try translateC(
5873 comp,
5865 arena,5874 arena,
5866 &man,5875 &man,
5867 .c,5876 .c,
...@@ -5869,6 +5878,7 @@ pub fn cImport(...@@ -5869,6 +5878,7 @@ pub fn cImport(
5869 translated_basename,5878 translated_basename,
5870 owner_mod,5879 owner_mod,
5871 prog_node,5880 prog_node,
5881 comp.environ_map,
5872 );5882 );
5873 };5883 };
58745884
...@@ -6741,15 +6751,16 @@ fn spawnZigRc(...@@ -6741,15 +6751,16 @@ fn spawnZigRc(
6741 var node_name: std.ArrayList(u8) = .empty;6751 var node_name: std.ArrayList(u8) = .empty;
6742 defer node_name.deinit(arena);6752 defer node_name.deinit(arena);
67436753
6744 var child = std.process.Child.init(argv, arena);6754 var child = std.process.spawn(io, .{
6745 child.stdin_behavior = .ignore;6755 .argv = argv,
6746 child.stdout_behavior = .pipe;6756 .stdin = .ignore,
6747 child.stderr_behavior = .pipe;6757 .stdout = .pipe,
6748 child.progress_node = child_progress_node;6758 .stderr = .pipe,
67496759 .progress_node = child_progress_node,
6750 child.spawn(io) catch |err| {6760 }) catch |err| return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {t}", .{
6751 return comp.failWin32Resource(win32_resource, "unable to spawn {s} rc: {t}", .{ argv[0], err });6761 argv[0], err,
6752 };6762 });
6763 defer child.kill(io);
67536764
6754 var poller = std.Io.poll(comp.gpa, enum { stdout, stderr }, .{6765 var poller = std.Io.poll(comp.gpa, enum { stdout, stderr }, .{
6755 .stdout = child.stdout.?,6766 .stdout = child.stdout.?,
...@@ -6781,7 +6792,7 @@ fn spawnZigRc(...@@ -6781,7 +6792,7 @@ fn spawnZigRc(
6781 const stderr = poller.reader(.stderr);6792 const stderr = poller.reader(.stderr);
67826793
6783 const term = child.wait(io) catch |err| {6794 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 });
6785 };6796 };
67866797
6787 switch (term) {6798 switch (term) {
...@@ -7963,6 +7974,7 @@ fn buildOutputFromZig(...@@ -7963,6 +7974,7 @@ fn buildOutputFromZig(
7963 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,7974 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
7964 .clang_passthrough_mode = comp.clang_passthrough_mode,7975 .clang_passthrough_mode = comp.clang_passthrough_mode,
7965 .skip_linker_dependencies = true,7976 .skip_linker_dependencies = true,
7977 .environ_map = comp.environ_map,
7966 }) catch |err| switch (err) {7978 }) catch |err| switch (err) {
7967 error.CreateFail => {7979 error.CreateFail => {
7968 comp.lockAndSetMiscFailure(misc_task_tag, "sub-compilation of {t} failed: {f}", .{ misc_task_tag, sub_create_diag });7980 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(...@@ -101,31 +101,27 @@ pub fn findZigLibDirFromSelfExe(
101 return error.FileNotFound;101 return error.FileNotFound;
102}102}
103103
104/// Caller owns returned memory.104pub fn resolveGlobalCacheDir(arena: Allocator, env_map: *std.process.Environ.Map) ![]const u8 {
105pub fn resolveGlobalCacheDir(gpa: Allocator) ![]u8 {105 if (std.zig.EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map)) |value| return value;
106 if (try std.zig.EnvVar.ZIG_GLOBAL_CACHE_DIR.get(gpa)) |value| return value;
107106
108 const app_name = "zig";107 const app_name = "zig";
109108
110 switch (builtin.os.tag) {109 switch (builtin.os.tag) {
111 .wasi => @compileError("on WASI the global cache dir must be resolved with preopens"),110 .wasi => @compileError("on WASI the global cache dir must be resolved with preopens"),
112 .windows => {111 .windows => {
113 const local_app_data_dir = (std.zig.EnvVar.LOCALAPPDATA.get(gpa) catch |err| switch (err) {112 const local_app_data_dir = std.zig.EnvVar.LOCALAPPDATA.get(env_map) orelse
114 error.OutOfMemory => |e| return e,113 return error.AppDataDirUnavailable;
115 error.InvalidWtf8 => return error.AppDataDirUnavailable,114 return Dir.path.join(arena, &.{ local_app_data_dir, app_name });
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 });
119 },115 },
120 else => {116 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| {
122 if (cache_root.len > 0) {118 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 });
124 }120 }
125 }121 }
126 if (std.zig.EnvVar.HOME.getPosix()) |home| {122 if (std.zig.EnvVar.HOME.get(env_map)) |home| {
127 if (home.len > 0) {123 if (home.len > 0) {
128 return Dir.path.join(gpa, &.{ home, ".cache", app_name });124 return Dir.path.join(arena, &.{ home, ".cache", app_name });
129 }125 }
130 }126 }
131 return error.AppDataDirUnavailable;127 return error.AppDataDirUnavailable;
src/link/Lld.zig+28-25
...@@ -1604,19 +1604,24 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi...@@ -1604,19 +1604,24 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
1604 var stderr: []u8 = &.{};1604 var stderr: []u8 = &.{};
1605 defer gpa.free(stderr);1605 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
1608 const term = (if (comp.clang_passthrough_mode) term: {1608 const term = (if (comp.clang_passthrough_mode) term: {
1609 child.stdin_behavior = .inherit;1609 var child = std.process.spawn(io, .{
1610 child.stdout_behavior = .inherit;1610 .argv = argv,
1611 child.stderr_behavior = .inherit;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);
1614 } else term: {1617 } else term: {
1615 child.stdin_behavior = .ignore;1618 var child = std.process.spawn(io, .{
1616 child.stdout_behavior = .ignore;1619 .argv = argv,
1617 child.stderr_behavior = .pipe;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;
1620 var stderr_reader = child.stderr.?.readerStreaming(io, &.{});1625 var stderr_reader = child.stderr.?.readerStreaming(io, &.{});
1621 stderr = try stderr_reader.interface.allocRemaining(gpa, .unlimited);1626 stderr = try stderr_reader.interface.allocRemaining(gpa, .unlimited);
1622 break :term child.wait(io);1627 break :term child.wait(io);
...@@ -1650,23 +1655,21 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi...@@ -1650,23 +1655,21 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
1650 try rsp_writer.flush();1655 try rsp_writer.flush();
1651 }1656 }
16521657
1653 var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint(1658 var rsp_child = std.process.spawn(io, .{
1654 arena,1659 .argv = &.{
1655 "@{s}",1660 argv[0],
1656 .{try comp.dirs.local_cache.join(arena, &.{rsp_path})},1661 argv[1],
1657 ) }, arena);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;
1658 if (comp.clang_passthrough_mode) {1670 if (comp.clang_passthrough_mode) {
1659 rsp_child.stdin_behavior = .inherit;1671 break :term rsp_child.wait(io) catch |err| break :err err;
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;
1664 } else {1672 } 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;
1670 var stderr_reader = rsp_child.stderr.?.readerStreaming(io, &.{});1673 var stderr_reader = rsp_child.stderr.?.readerStreaming(io, &.{});
1671 stderr = try stderr_reader.interface.allocRemaining(gpa, .unlimited);1674 stderr = try stderr_reader.interface.allocRemaining(gpa, .unlimited);
1672 break :term rsp_child.wait(io) catch |err| break :err err;1675 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...@@ -1674,7 +1677,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
1674 },1677 },
1675 else => first_err,1678 else => first_err,
1676 };1679 };
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 });
1678 return error.UnableToSpawnSelf;1681 return error.UnableToSpawnSelf;
1679 };1682 };
16801683
src/main.zig+240-204
...@@ -42,7 +42,6 @@ test {...@@ -42,7 +42,6 @@ test {
42const thread_stack_size = 60 << 20;42const thread_stack_size = 60 << 20;
4343
44pub const std_options: std.Options = .{44pub const std_options: std.Options = .{
45 .wasiCwd = wasi_cwd,
46 .logFn = log,45 .logFn = log,
4746
48 .log_level = switch (builtin.mode) {47 .log_level = switch (builtin.mode) {
...@@ -51,6 +50,7 @@ pub const std_options: std.Options = .{...@@ -51,6 +50,7 @@ pub const std_options: std.Options = .{
51 .ReleaseSmall => .err,50 .ReleaseSmall => .err,
52 },51 },
53};52};
53pub const std_options_cwd = if (native_os == .wasi) wasi_cwd else null;
5454
55pub const panic = crash_report.panic;55pub const panic = crash_report.panic;
56pub const debug = crash_report.debug;56pub const debug = crash_report.debug;
...@@ -208,7 +208,15 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma...@@ -208,7 +208,15 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
208 fatal("expected command argument", .{});208 fatal("expected command argument", .{});
209 }209 }
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)) {
212 dev.check(.cc_command);220 dev.check(.cc_command);
213 // In this case we have accidentally invoked ourselves as "the system C compiler"221 // In this case we have accidentally invoked ourselves as "the system C compiler"
214 // to figure out where libc is installed. This is essentially infinite recursion222 // 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...@@ -217,7 +225,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
217 // However it's possible Zig is installed as *that* C compiler as well, which is225 // However it's possible Zig is installed as *that* C compiler as well, which is
218 // why we have this additional environment variable here to check.226 // 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;
221 if (inf_loop_env_key.isSet(env_map)) {229 if (inf_loop_env_key.isSet(env_map)) {
222 fatal("{s}", .{230 fatal("{s}", .{
223 "The compilation links against libc, but Zig is unable to provide a libc " ++231 "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...@@ -233,42 +241,34 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
233 // CC environment variable. We detect and support this scenario here because of241 // CC environment variable. We detect and support this scenario here because of
234 // the ZIG_IS_DETECTING_LIBC_PATHS environment variable.242 // the ZIG_IS_DETECTING_LIBC_PATHS environment variable.
235 if (mem.eql(u8, args[1], "cc")) {243 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 });
237 } else {245 } else {
238 const modified_args = try arena.dupe([]const u8, args);246 const modified_args = try arena.dupe([]const u8, args);
239 modified_args[0] = "cc";247 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 });
241 }249 }
242 }250 }
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
252 const cmd = args[1];252 const cmd = args[1];
253 const cmd_args = args[2..];253 const cmd_args = args[2..];
254 if (mem.eql(u8, cmd, "build-exe")) {254 if (mem.eql(u8, cmd, "build-exe")) {
255 dev.check(.build_exe_command);255 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);
257 } else if (mem.eql(u8, cmd, "build-lib")) {257 } else if (mem.eql(u8, cmd, "build-lib")) {
258 dev.check(.build_lib_command);258 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);
260 } else if (mem.eql(u8, cmd, "build-obj")) {260 } else if (mem.eql(u8, cmd, "build-obj")) {
261 dev.check(.build_obj_command);261 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);
263 } else if (mem.eql(u8, cmd, "test")) {263 } else if (mem.eql(u8, cmd, "test")) {
264 dev.check(.test_command);264 dev.check(.test_command);
265 return buildOutputType(gpa, arena, io, args, .zig_test);265 return buildOutputType(gpa, arena, io, args, .zig_test, env_map);
266 } else if (mem.eql(u8, cmd, "test-obj")) {266 } else if (mem.eql(u8, cmd, "test-obj")) {
267 dev.check(.test_command);267 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);
269 } else if (mem.eql(u8, cmd, "run")) {269 } else if (mem.eql(u8, cmd, "run")) {
270 dev.check(.run_command);270 dev.check(.run_command);
271 return buildOutputType(gpa, arena, io, args, .run);271 return buildOutputType(gpa, arena, io, args, .run, env_map);
272 } else if (mem.eql(u8, cmd, "dlltool") or272 } else if (mem.eql(u8, cmd, "dlltool") or
273 mem.eql(u8, cmd, "ranlib") or273 mem.eql(u8, cmd, "ranlib") or
274 mem.eql(u8, cmd, "lib") or274 mem.eql(u8, cmd, "lib") or
...@@ -278,7 +278,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma...@@ -278,7 +278,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
278 return process.exit(try llvmArMain(arena, args));278 return process.exit(try llvmArMain(arena, args));
279 } else if (mem.eql(u8, cmd, "build")) {279 } else if (mem.eql(u8, cmd, "build")) {
280 dev.check(.build_command);280 dev.check(.build_command);
281 return cmdBuild(gpa, arena, io, cmd_args);281 return cmdBuild(gpa, arena, io, cmd_args, env_map);
282 } else if (mem.eql(u8, cmd, "clang") or282 } else if (mem.eql(u8, cmd, "clang") or
283 mem.eql(u8, cmd, "-cc1") or mem.eql(u8, cmd, "-cc1as"))283 mem.eql(u8, cmd, "-cc1") or mem.eql(u8, cmd, "-cc1as"))
284 {284 {
...@@ -292,16 +292,16 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma...@@ -292,16 +292,16 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
292 return process.exit(try lldMain(arena, args, true));292 return process.exit(try lldMain(arena, args, true));
293 } else if (mem.eql(u8, cmd, "cc")) {293 } else if (mem.eql(u8, cmd, "cc")) {
294 dev.check(.cc_command);294 dev.check(.cc_command);
295 return buildOutputType(gpa, arena, io, args, .cc);295 return buildOutputType(gpa, arena, io, args, .cc, env_map);
296 } else if (mem.eql(u8, cmd, "c++")) {296 } else if (mem.eql(u8, cmd, "c++")) {
297 dev.check(.cc_command);297 dev.check(.cc_command);
298 return buildOutputType(gpa, arena, io, args, .cpp);298 return buildOutputType(gpa, arena, io, args, .cpp, env_map);
299 } else if (mem.eql(u8, cmd, "translate-c")) {299 } else if (mem.eql(u8, cmd, "translate-c")) {
300 dev.check(.translate_c_command);300 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);
302 } else if (mem.eql(u8, cmd, "rc")) {302 } else if (mem.eql(u8, cmd, "rc")) {
303 const use_server = cmd_args.len > 0 and std.mem.eql(u8, cmd_args[0], "--zig-integration");303 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, .{
305 .cmd_name = "resinator",305 .cmd_name = "resinator",
306 .root_src_path = "resinator/main.zig",306 .root_src_path = "resinator/main.zig",
307 .depend_on_aro = true,307 .depend_on_aro = true,
...@@ -312,20 +312,20 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma...@@ -312,20 +312,20 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
312 dev.check(.fmt_command);312 dev.check(.fmt_command);
313 return @import("fmt.zig").run(gpa, arena, io, cmd_args);313 return @import("fmt.zig").run(gpa, arena, io, cmd_args);
314 } else if (mem.eql(u8, cmd, "objcopy")) {314 } 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, .{
316 .cmd_name = "objcopy",316 .cmd_name = "objcopy",
317 .root_src_path = "objcopy.zig",317 .root_src_path = "objcopy.zig",
318 });318 });
319 } else if (mem.eql(u8, cmd, "fetch")) {319 } 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);
321 } else if (mem.eql(u8, cmd, "libc")) {321 } 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, .{
323 .cmd_name = "libc",323 .cmd_name = "libc",
324 .root_src_path = "libc.zig",324 .root_src_path = "libc.zig",
325 .prepend_zig_lib_dir_path = true,325 .prepend_zig_lib_dir_path = true,
326 });326 });
327 } else if (mem.eql(u8, cmd, "std")) {327 } 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, .{
329 .cmd_name = "std",329 .cmd_name = "std",
330 .root_src_path = "std-docs.zig",330 .root_src_path = "std-docs.zig",
331 .prepend_zig_lib_dir_path = true,331 .prepend_zig_lib_dir_path = true,
...@@ -355,10 +355,11 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma...@@ -355,10 +355,11 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const [:0]const u8, env_ma
355 args,355 args,
356 if (native_os == .wasi) wasi_preopens,356 if (native_os == .wasi) wasi_preopens,
357 &host,357 &host,
358 env_map,
358 );359 );
359 return stdout_writer.interface.flush();360 return stdout_writer.interface.flush();
360 } else if (mem.eql(u8, cmd, "reduce")) {361 } 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, .{
362 .cmd_name = "reduce",363 .cmd_name = "reduce",
363 .root_src_path = "reduce.zig",364 .root_src_path = "reduce.zig",
364 });365 });
...@@ -803,6 +804,7 @@ fn buildOutputType(...@@ -803,6 +804,7 @@ fn buildOutputType(
803 io: Io,804 io: Io,
804 all_args: []const []const u8,805 all_args: []const []const u8,
805 arg_mode: ArgMode,806 arg_mode: ArgMode,
807 env_map: *process.Environ.Map,
806) !void {808) !void {
807 var provided_name: ?[]const u8 = null;809 var provided_name: ?[]const u8 = null;
808 var root_src_file: ?[]const u8 = null;810 var root_src_file: ?[]const u8 = null;
...@@ -815,9 +817,9 @@ fn buildOutputType(...@@ -815,9 +817,9 @@ fn buildOutputType(
815 var debug_compile_errors = false;817 var debug_compile_errors = false;
816 var debug_incremental = false;818 var debug_incremental = false;
817 var verbose_link = (native_os != .wasi or builtin.link_libc) and819 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);
819 var verbose_cc = (native_os != .wasi or builtin.link_libc) and821 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);
821 var verbose_air = false;823 var verbose_air = false;
822 var verbose_intern_pool = false;824 var verbose_intern_pool = false;
823 var verbose_generic_instances = false;825 var verbose_generic_instances = false;
...@@ -889,9 +891,9 @@ fn buildOutputType(...@@ -889,9 +891,9 @@ fn buildOutputType(
889 var runtime_args_start: ?usize = null;891 var runtime_args_start: ?usize = null;
890 var test_filters: std.ArrayList([]const u8) = .empty;892 var test_filters: std.ArrayList([]const u8) = .empty;
891 var test_runner_path: ?[]const u8 = null;893 var test_runner_path: ?[]const u8 = null;
892 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);894 var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(env_map);
893 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);895 var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
894 var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);896 var override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(env_map);
895 var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;897 var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;
896 var subsystem: ?std.zig.Subsystem = null;898 var subsystem: ?std.zig.Subsystem = null;
897 var major_subsystem_version: ?u16 = null;899 var major_subsystem_version: ?u16 = null;
...@@ -988,7 +990,7 @@ fn buildOutputType(...@@ -988,7 +990,7 @@ fn buildOutputType(
988 .framework_dirs = .{},990 .framework_dirs = .{},
989 .rpath_list = .{},991 .rpath_list = .{},
990 .each_lib_rpath = null,992 .each_lib_rpath = null,
991 .libc_paths_file = try EnvVar.ZIG_LIBC.get(arena),993 .libc_paths_file = EnvVar.ZIG_LIBC.get(env_map),
992 .native_system_include_paths = &.{},994 .native_system_include_paths = &.{},
993 };995 };
994 defer create_module.link_inputs.deinit(gpa);996 defer create_module.link_inputs.deinit(gpa);
...@@ -997,9 +999,9 @@ fn buildOutputType(...@@ -997,9 +999,9 @@ fn buildOutputType(
997 // if set, default the color setting to .off or .on, respectively999 // if set, default the color setting to .off or .on, respectively
998 // explicit --color arguments will still override this setting.1000 // explicit --color arguments will still override this setting.
999 // Disable color on WASI per https://github.com/WebAssembly/WASI/issues/1621001 // 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))
1001 .off1003 .off
1002 else if (EnvVar.CLICOLOR_FORCE.isSet())1004 else if (EnvVar.CLICOLOR_FORCE.isSet(env_map))
1003 .on1005 .on
1004 else1006 else
1005 .auto;1007 .auto;
...@@ -3097,6 +3099,7 @@ fn buildOutputType(...@@ -3097,6 +3099,7 @@ fn buildOutputType(
3097 },3099 },
3098 if (native_os == .wasi) wasi_preopens,3100 if (native_os == .wasi) wasi_preopens,
3099 self_exe_path,3101 self_exe_path,
3102 env_map,
3100 );3103 );
3101 defer dirs.deinit(io);3104 defer dirs.deinit(io);
31023105
...@@ -3108,7 +3111,7 @@ fn buildOutputType(...@@ -3108,7 +3111,7 @@ fn buildOutputType(
3108 create_module.opts.emit_bin = emit_bin != .no;3111 create_module.opts.emit_bin = emit_bin != .no;
3109 create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0;3112 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);
3112 for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| {3115 for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| {
3113 if (cli_mod.resolved == null)3116 if (cli_mod.resolved == null)
3114 fatal("module '{s}' declared but not used", .{key});3117 fatal("module '{s}' declared but not used", .{key});
...@@ -3585,6 +3588,7 @@ fn buildOutputType(...@@ -3585,6 +3588,7 @@ fn buildOutputType(
3585 .global_cc_argv = try cc_argv.toOwnedSlice(arena),3588 .global_cc_argv = try cc_argv.toOwnedSlice(arena),
3586 .file_system_inputs = &file_system_inputs,3589 .file_system_inputs = &file_system_inputs,
3587 .debug_compiler_runtime_libs = debug_compiler_runtime_libs,3590 .debug_compiler_runtime_libs = debug_compiler_runtime_libs,
3591 .environ_map = env_map,
3588 }) catch |err| switch (err) {3592 }) catch |err| switch (err) {
3589 error.CreateFail => switch (create_diag) {3593 error.CreateFail => switch (create_diag) {
3590 .cross_libc_unavailable => {3594 .cross_libc_unavailable => {
...@@ -3648,6 +3652,7 @@ fn buildOutputType(...@@ -3648,6 +3652,7 @@ fn buildOutputType(
3648 arg_mode,3652 arg_mode,
3649 all_args,3653 all_args,
3650 runtime_args_start,3654 runtime_args_start,
3655 env_map,
3651 );3656 );
3652 return cleanExit(io);3657 return cleanExit(io);
3653 },3658 },
...@@ -3674,6 +3679,7 @@ fn buildOutputType(...@@ -3674,6 +3679,7 @@ fn buildOutputType(
3674 arg_mode,3679 arg_mode,
3675 all_args,3680 all_args,
3676 runtime_args_start,3681 runtime_args_start,
3682 env_map,
3677 );3683 );
3678 return cleanExit(io);3684 return cleanExit(io);
3679 },3685 },
...@@ -3686,7 +3692,7 @@ fn buildOutputType(...@@ -3686,7 +3692,7 @@ fn buildOutputType(
3686 defer root_prog_node.end();3692 defer root_prog_node.end();
36873693
3688 if (arg_mode == .translate_c) {3694 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);
3690 }3696 }
36913697
3692 updateModule(comp, color, root_prog_node) catch |err| switch (err) {3698 updateModule(comp, color, root_prog_node) catch |err| switch (err) {
...@@ -3754,6 +3760,7 @@ fn buildOutputType(...@@ -3754,6 +3760,7 @@ fn buildOutputType(
3754 all_args,3760 all_args,
3755 runtime_args_start,3761 runtime_args_start,
3756 create_module.resolved_options.link_libc,3762 create_module.resolved_options.link_libc,
3763 env_map,
3757 );3764 );
3758 }3765 }
37593766
...@@ -3809,6 +3816,7 @@ fn createModule(...@@ -3809,6 +3816,7 @@ fn createModule(
3809 index: usize,3816 index: usize,
3810 parent: ?*Package.Module,3817 parent: ?*Package.Module,
3811 color: std.zig.Color,3818 color: std.zig.Color,
3819 env_map: *process.Environ.Map,
3812) Allocator.Error!*Package.Module {3820) Allocator.Error!*Package.Module {
3813 const cli_mod = &create_module.modules.values()[index];3821 const cli_mod = &create_module.modules.values()[index];
3814 if (cli_mod.resolved) |m| return m;3822 if (cli_mod.resolved) |m| return m;
...@@ -3988,7 +3996,7 @@ fn createModule(...@@ -3988,7 +3996,7 @@ fn createModule(
3988 resolved_target.is_native_os and resolved_target.is_native_abi and3996 resolved_target.is_native_os and resolved_target.is_native_abi and
3989 create_module.want_native_include_dirs)3997 create_module.want_native_include_dirs)
3990 {3998 {
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|
3992 fatal("unable to detect native system paths: {t}", .{err});4000 fatal("unable to detect native system paths: {t}", .{err});
3993 for (paths.warnings.items) |warning| {4001 for (paths.warnings.items) |warning| {
3994 warn("{s}", .{warning});4002 warn("{s}", .{warning});
...@@ -4015,6 +4023,7 @@ fn createModule(...@@ -4015,6 +4023,7 @@ fn createModule(
4015 create_module.libc_installation = LibCInstallation.findNative(arena, io, .{4023 create_module.libc_installation = LibCInstallation.findNative(arena, io, .{
4016 .verbose = true,4024 .verbose = true,
4017 .target = target,4025 .target = target,
4026 .env_map = env_map,
4018 }) catch |err| {4027 }) catch |err| {
4019 fatal("unable to find native libc installation: {t}", .{err});4028 fatal("unable to find native libc installation: {t}", .{err});
4020 };4029 };
...@@ -4119,7 +4128,7 @@ fn createModule(...@@ -4119,7 +4128,7 @@ fn createModule(
4119 for (cli_mod.deps) |dep| {4128 for (cli_mod.deps) |dep| {
4120 const dep_index = create_module.modules.getIndex(dep.value) orelse4129 const dep_index = create_module.modules.getIndex(dep.value) orelse
4121 fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key });4130 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);
4123 try mod.deps.put(arena, dep.key, dep_mod);4132 try mod.deps.put(arena, dep.key, dep_mod);
4124 }4133 }
41254134
...@@ -4128,9 +4137,7 @@ fn createModule(...@@ -4128,9 +4137,7 @@ fn createModule(
41284137
4129fn saveState(comp: *Compilation, incremental: bool) void {4138fn saveState(comp: *Compilation, incremental: bool) void {
4130 if (incremental) {4139 if (incremental) {
4131 comp.saveState() catch |err| {4140 comp.saveState() catch |err| warn("unable to save incremental compilation state: {t}", .{err});
4132 warn("unable to save incremental compilation state: {s}", .{@errorName(err)});
4133 };
4134 }4141 }
4135}4142}
41364143
...@@ -4143,6 +4150,7 @@ fn serve(...@@ -4143,6 +4150,7 @@ fn serve(
4143 arg_mode: ArgMode,4150 arg_mode: ArgMode,
4144 all_args: []const []const u8,4151 all_args: []const []const u8,
4145 runtime_args_start: ?usize,4152 runtime_args_start: ?usize,
4153 env_map: *process.Environ.Map,
4146) !void {4154) !void {
4147 const gpa = comp.gpa;4155 const gpa = comp.gpa;
4148 const io = comp.io;4156 const io = comp.io;
...@@ -4190,7 +4198,7 @@ fn serve(...@@ -4190,7 +4198,7 @@ fn serve(
4190 defer arena_instance.deinit();4198 defer arena_instance.deinit();
4191 const arena = arena_instance.allocator();4199 const arena = arena_instance.allocator();
4192 var output: Compilation.CImportResult = undefined;4200 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);
4194 defer output.deinit(gpa);4202 defer output.deinit(gpa);
41954203
4196 if (file_system_inputs.items.len != 0) {4204 if (file_system_inputs.items.len != 0) {
...@@ -4390,6 +4398,7 @@ fn runOrTest(...@@ -4390,6 +4398,7 @@ fn runOrTest(
4390 all_args: []const []const u8,4398 all_args: []const []const u8,
4391 runtime_args_start: ?usize,4399 runtime_args_start: ?usize,
4392 link_libc: bool,4400 link_libc: bool,
4401 env_map: *process.Environ.Map,
4393) !void {4402) !void {
4394 const raw_emit_bin = comp.emit_bin orelse return;4403 const raw_emit_bin = comp.emit_bin orelse return;
4395 const exe_path = switch (comp.cache_use) {4404 const exe_path = switch (comp.cache_use) {
...@@ -4426,77 +4435,90 @@ fn runOrTest(...@@ -4426,77 +4435,90 @@ fn runOrTest(
4426 if (runtime_args_start) |i| {4435 if (runtime_args_start) |i| {
4427 try argv.appendSlice(all_args[i..]);4436 try argv.appendSlice(all_args[i..]);
4428 }4437 }
4429 var env_map = try process.getEnvMap(arena);
4430 try env_map.put("ZIG_EXE", self_exe_path);4438 try env_map.put("ZIG_EXE", self_exe_path);
44314439
4432 // We do not execve for tests because if the test fails we want to print4440 // We do not execve for tests because if the test fails we want to print
4433 // the error message and invocation below.4441 // the error message and invocation below.
4434 if (process.can_replace and arg_mode == .run) {4442 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.
4436 _ = try io.lockStderr(&.{}, .no_color);4444 _ = 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 });
4438 io.unlockStderr();4446 io.unlockStderr();
4439 try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc);4447 try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc);
4440 const cmd = try std.mem.join(arena, " ", argv.items);4448 const cmd = try std.mem.join(arena, " ", argv.items);
4441 fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd });4449 fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd });
4442 } else if (process.can_spawn) {4450 } else if (!process.can_spawn) {
4443 var child = std.process.Child.init(argv.items, gpa);4451 const cmd = try std.mem.join(arena, " ", argv.items);
4444 child.env_map = &env_map;4452 fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{
4445 child.stdin_behavior = .inherit;4453 native_os, cmd,
4446 child.stdout_behavior = .inherit;4454 });
4447 child.stderr_behavior = .inherit;4455 }
44484456 const term_result = (term: {
4449 // Here we release all the locks associated with the Compilation so4457 // Here we release all the locks associated with the Compilation so
4450 // that whatever this child process wants to do won't deadlock.4458 // that whatever this child process wants to do won't deadlock.
4451 comp.destroy();4459 comp.destroy();
4452 comp_destroyed.* = true;4460 comp_destroyed.* = true;
44534461
4454 const term_result = t: {4462 _ = try io.lockStderr(&.{}, .no_color);
4455 _ = try io.lockStderr(&.{}, .no_color);4463 defer io.unlockStderr();
4456 defer io.unlockStderr();4464
4457 break :t child.spawnAndWait(io);4465 var child = std.process.spawn(io, .{
4458 };4466 .argv = argv.items,
4459 const term = term_result catch |err| {4467 .env_map = env_map,
4460 try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc);4468 .stdin = .inherit,
4461 const cmd = try std.mem.join(arena, " ", argv.items);4469 .stdout = .inherit,
4462 fatal("the following command failed with '{s}':\n{s}", .{ @errorName(err), cmd });4470 .stderr = .inherit,
4463 };4471 }) catch |err| break :term err;
4464 switch (arg_mode) {4472 defer child.kill(io);
4465 .run, .build => {4473
4466 switch (term) {4474 break :term child.wait(io);
4467 .Exited => |code| {4475 });
4468 if (code == 0) {4476
4469 return cleanExit(io);4477 const term = term_result catch |err| {
4470 } else {4478 try warnAboutForeignBinaries(io, arena, arg_mode, target, link_libc);
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 {
4498 const cmd = try std.mem.join(arena, " ", argv.items);4479 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,
4500 }4522 }
4501}4523}
45024524
...@@ -4559,13 +4581,13 @@ fn runOrTestHotSwap(...@@ -4559,13 +4581,13 @@ fn runOrTestHotSwap(
4559 try argv.appendSlice(all_args[i..]);4581 try argv.appendSlice(all_args[i..]);
4560 }4582 }
45614583
4562 var child = try std.process.spwan(io, .{4584 var child = try std.process.spawn(io, .{
4563 .argv = argv.items,4585 .argv = argv.items,
4564 .stdin = .inherit,4586 .stdin = .inherit,
4565 .stdout = .inherit,4587 .stdout = .inherit,
4566 .stderr = .inherit,4588 .stderr = .inherit,
4567 });4589 });
4568 return child.id;4590 return child.id.?;
4569}4591}
45704592
4571const UpdateModuleError = Compilation.UpdateError || error{4593const UpdateModuleError = Compilation.UpdateError || error{
...@@ -4597,6 +4619,7 @@ fn cmdTranslateC(...@@ -4597,6 +4619,7 @@ fn cmdTranslateC(
4597 fancy_output: ?*Compilation.CImportResult,4619 fancy_output: ?*Compilation.CImportResult,
4598 file_system_inputs: ?*std.ArrayList(u8),4620 file_system_inputs: ?*std.ArrayList(u8),
4599 prog_node: std.Progress.Node,4621 prog_node: std.Progress.Node,
4622 env_map: *process.Environ.Map,
4600) !void {4623) !void {
4601 dev.check(.translate_c_command);4624 dev.check(.translate_c_command);
46024625
...@@ -4630,6 +4653,7 @@ fn cmdTranslateC(...@@ -4630,6 +4653,7 @@ fn cmdTranslateC(
4630 translated_basename,4653 translated_basename,
4631 comp.root_mod,4654 comp.root_mod,
4632 prog_node,4655 prog_node,
4656 env_map,
4633 );4657 );
46344658
4635 if (result.errors.errorMessageCount() != 0) {4659 if (result.errors.errorMessageCount() != 0) {
...@@ -4677,10 +4701,11 @@ pub fn translateC(...@@ -4677,10 +4701,11 @@ pub fn translateC(
4677 arena: Allocator,4701 arena: Allocator,
4678 io: Io,4702 io: Io,
4679 argv: []const []const u8,4703 argv: []const []const u8,
4704 env_map: *process.Environ.Map,
4680 prog_node: std.Progress.Node,4705 prog_node: std.Progress.Node,
4681 capture: ?*[]u8,4706 capture: ?*[]u8,
4682) !void {4707) !void {
4683 try jitCmd(gpa, arena, io, argv, .{4708 try jitCmd(gpa, arena, io, argv, env_map, .{
4684 .cmd_name = "translate-c",4709 .cmd_name = "translate-c",
4685 .root_src_path = "translate-c/main.zig",4710 .root_src_path = "translate-c/main.zig",
4686 .depend_on_aro = true,4711 .depend_on_aro = true,
...@@ -4837,21 +4862,21 @@ test sanitizeExampleName {...@@ -4837,21 +4862,21 @@ test sanitizeExampleName {
4837 try std.testing.expectEqualStrings("test_project", try sanitizeExampleName(arena, "test project"));4862 try std.testing.expectEqualStrings("test_project", try sanitizeExampleName(arena, "test project"));
4838}4863}
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 {
4841 dev.check(.build_command);4866 dev.check(.build_command);
48424867
4843 var build_file: ?[]const u8 = null;4868 var build_file: ?[]const u8 = null;
4844 var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);4869 var override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(env_map);
4845 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);4870 var override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
4846 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);4871 var override_local_cache_dir: ?[]const u8 = EnvVar.ZIG_LOCAL_CACHE_DIR.get(env_map);
4847 var override_build_runner: ?[]const u8 = try EnvVar.ZIG_BUILD_RUNNER.get(arena);4872 var override_build_runner: ?[]const u8 = EnvVar.ZIG_BUILD_RUNNER.get(env_map);
4848 var child_argv = std.array_list.Managed([]const u8).init(arena);4873 var child_argv = std.array_list.Managed([]const u8).init(arena);
4849 var reference_trace: ?u32 = null;4874 var reference_trace: ?u32 = null;
4850 var debug_compile_errors = false;4875 var debug_compile_errors = false;
4851 var verbose_link = (native_os != .wasi or builtin.link_libc) and4876 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);
4853 var verbose_cc = (native_os != .wasi or builtin.link_libc) and4878 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);
4855 var verbose_air = false;4880 var verbose_air = false;
4856 var verbose_intern_pool = false;4881 var verbose_intern_pool = false;
4857 var verbose_generic_instances = false;4882 var verbose_generic_instances = false;
...@@ -5048,7 +5073,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)...@@ -5048,7 +5073,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
5048 }5073 }
50495074
5050 const work_around_btrfs_bug = native_os == .linux and5075 const work_around_btrfs_bug = native_os == .linux and
5051 EnvVar.ZIG_BTRFS_WORKAROUND.isSet();5076 EnvVar.ZIG_BTRFS_WORKAROUND.isSet(env_map);
5052 const root_prog_node = std.Progress.start(io, .{5077 const root_prog_node = std.Progress.start(io, .{
5053 .disable_printing = (color == .off),5078 .disable_printing = (color == .off),
5054 .root_name = "Compile Build Script",5079 .root_name = "Compile Build Script",
...@@ -5108,6 +5133,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)...@@ -5108,6 +5133,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
5108 } },5133 } },
5109 {},5134 {},
5110 self_exe_path,5135 self_exe_path,
5136 env_map,
5111 );5137 );
5112 defer dirs.deinit(io);5138 defer dirs.deinit(io);
51135139
...@@ -5210,7 +5236,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)...@@ -5210,7 +5236,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
5210 job_queue.read_only = true;5236 job_queue.read_only = true;
5211 cleanup_build_dir = job_queue.global_cache.handle;5237 cleanup_build_dir = job_queue.global_cache.handle;
5212 } else {5238 } else {
5213 try http_client.initDefaultProxies(arena);5239 try http_client.initDefaultProxies(arena, env_map);
5214 }5240 }
52155241
5216 try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1);5242 try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1);
...@@ -5364,6 +5390,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)...@@ -5364,6 +5390,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
5364 .cache_mode = .whole,5390 .cache_mode = .whole,
5365 .reference_trace = reference_trace,5391 .reference_trace = reference_trace,
5366 .debug_compile_errors = debug_compile_errors,5392 .debug_compile_errors = debug_compile_errors,
5393 .environ_map = env_map,
5367 }) catch |err| switch (err) {5394 }) catch |err| switch (err) {
5368 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),5395 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
5369 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),5396 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)...@@ -5385,81 +5412,81 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, io: Io, args: []const []const u8)
5385 });5412 });
5386 }5413 }
53875414
5388 if (process.can_spawn) {5415 if (!process.can_spawn) {
5389 var child = std.process.Child.init(child_argv.items, gpa);5416 const cmd = try std.mem.join(arena, " ", child_argv.items);
5390 child.stdin_behavior = .inherit;5417 fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{ native_os, cmd });
5391 child.stdout_behavior = .inherit;5418 }
5392 child.stderr_behavior = .inherit;5419 switch (term: {
53935420 _ = try io.lockStderr(&.{}, .no_color);
5394 const term = t: {5421 defer io.unlockStderr();
5395 _ = try io.lockStderr(&.{}, .no_color);5422 var child = std.process.spawn(io, .{
5396 defer io.unlockStderr();5423 .argv = child_argv.items,
5397 break :t child.spawnAndWait(io) catch |err|5424 }) catch |err| fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err });
5398 fatal("failed to spawn build runner {s}: {t}", .{ child_argv.items[0], err });5425 defer child.kill(io);
5399 };5426 break :term child.wait(io) catch |err|
54005427 fatal("failed to wait build runner {s}: {t}", .{ child_argv.items[0], err });
5401 switch (term) {5428 }) {
5402 .Exited => |code| {5429 .exited => |code| {
5403 if (code == 0) return cleanExit(io);5430 if (code == 0) return cleanExit(io);
5404 // Indicates that the build runner has reported compile errors5431 // Indicates that the build runner has reported compile errors
5405 // and this parent process does not need to report any further5432 // and this parent process does not need to report any further
5406 // diagnostics.5433 // diagnostics.
5407 if (code == 2) process.exit(2);5434 if (code == 2) process.exit(2);
54085435
5409 if (code == 3) {5436 if (code == 3) {
5410 if (!dev.env.supports(.fetch_command)) process.exit(3);5437 if (!dev.env.supports(.fetch_command)) process.exit(3);
5411 // Indicates the configure phase failed due to missing lazy5438 // Indicates the configure phase failed due to missing lazy
5412 // dependencies and stdout contains the hashes of the ones5439 // dependencies and stdout contains the hashes of the ones
5413 // that are missing.5440 // that are missing.
5414 const s = fs.path.sep_str;5441 const s = fs.path.sep_str;
5415 const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce;5442 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| {5443 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}", .{5444 fatal("unable to read results of configure phase from '{f}{s}': {t}", .{
5418 dirs.local_cache, tmp_sub_path, @errorName(err),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,
5419 });5457 });
5420 };5458 any_errors = true;
5421 dirs.local_cache.handle.deleteFile(io, tmp_sub_path) catch {};5459 continue;
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), {});
5435 }5460 }
5436 if (any_errors) process.exit(3);5461 try unlazy_set.put(arena, .fromSlice(hash), {});
5437 if (system_pkg_dir_path) |p| {5462 }
5438 // In this mode, the system needs to provide these packages; they5463 if (any_errors) process.exit(3);
5439 // cannot be fetched by Zig.5464 if (system_pkg_dir_path) |p| {
5440 for (unlazy_set.keys()) |*hash| {5465 // In this mode, the system needs to provide these packages; they
5441 std.log.err("lazy dependency package not found: {s}" ++ s ++ "{s}", .{5466 // cannot be fetched by Zig.
5442 p, hash.toSlice(),5467 for (unlazy_set.keys()) |*hash| {
5443 });5468 std.log.err("lazy dependency package not found: {s}" ++ s ++ "{s}", .{
5444 }5469 p, hash.toSlice(),
5445 std.log.info("remote package fetching disabled due to --system mode", .{});5470 });
5446 std.log.info("dependencies might be avoidable depending on build configuration", .{});
5447 process.exit(3);
5448 }5471 }
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);
5450 }5475 }
5476 continue;
5477 }
54515478
5452 const cmd = try std.mem.join(arena, " ", child_argv.items);5479 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 });5480 fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });
5454 },5481 },
5455 else => {5482 .signal => |sig| {
5456 const cmd = try std.mem.join(arena, " ", child_argv.items);5483 const cmd = try std.mem.join(arena, " ", child_argv.items);
5457 fatal("the following build command crashed:\n{s}", .{cmd});5484 fatal("the following build command terminated with signal {t}:\n{s}", .{ sig, cmd });
5458 },5485 },
5459 }5486 else => {
5460 } else {5487 const cmd = try std.mem.join(arena, " ", child_argv.items);
5461 const cmd = try std.mem.join(arena, " ", child_argv.items);5488 fatal("the following build command crashed:\n{s}", .{cmd});
5462 fatal("the following command cannot be executed ({s} does not support spawning a child process):\n{s}", .{ @tagName(native_os), cmd });5489 },
5463 }5490 }
5464 }5491 }
5465}5492}
...@@ -5482,6 +5509,7 @@ fn jitCmd(...@@ -5482,6 +5509,7 @@ fn jitCmd(
5482 arena: Allocator,5509 arena: Allocator,
5483 io: Io,5510 io: Io,
5484 args: []const []const u8,5511 args: []const []const u8,
5512 env_map: *process.Environ.Map,
5485 options: JitCmdOptions,5513 options: JitCmdOptions,
5486) !void {5514) !void {
5487 dev.check(.jit_command);5515 dev.check(.jit_command);
...@@ -5503,13 +5531,13 @@ fn jitCmd(...@@ -5503,13 +5531,13 @@ fn jitCmd(
5503 const self_exe_path = process.executablePathAlloc(io, arena) catch |err|5531 const self_exe_path = process.executablePathAlloc(io, arena) catch |err|
5504 fatal("unable to find self exe path: {t}", .{err});5532 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))
5507 .Debug5535 .Debug
5508 else5536 else
5509 .ReleaseFast;5537 .ReleaseFast;
5510 const strip = optimize_mode != .Debug;5538 const strip = optimize_mode != .Debug;
5511 const override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);5539 const override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(env_map);
5512 const override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);5540 const override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
55135541
5514 // This `init` calls `fatal` on error.5542 // This `init` calls `fatal` on error.
5515 var dirs: Compilation.Directories = .init(5543 var dirs: Compilation.Directories = .init(
...@@ -5520,6 +5548,7 @@ fn jitCmd(...@@ -5520,6 +5548,7 @@ fn jitCmd(
5520 .global,5548 .global,
5521 if (native_os == .wasi) wasi_preopens,5549 if (native_os == .wasi) wasi_preopens,
5522 self_exe_path,5550 self_exe_path,
5551 env_map,
5523 );5552 );
5524 defer dirs.deinit(io);5553 defer dirs.deinit(io);
55255554
...@@ -5593,6 +5622,7 @@ fn jitCmd(...@@ -5593,6 +5622,7 @@ fn jitCmd(
5593 .self_exe_path = self_exe_path,5622 .self_exe_path = self_exe_path,
5594 .thread_limit = thread_limit,5623 .thread_limit = thread_limit,
5595 .cache_mode = .whole,5624 .cache_mode = .whole,
5625 .environ_map = env_map,
5596 }) catch |err| switch (err) {5626 }) catch |err| switch (err) {
5597 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),5627 error.CreateFail => fatal("failed to create compilation: {f}", .{create_diag}),
5598 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),5628 else => fatal("failed to create compilation: {s}", .{@errorName(err)}),
...@@ -5639,31 +5669,33 @@ fn jitCmd(...@@ -5639,31 +5669,33 @@ fn jitCmd(
5639 child_argv.appendSliceAssumeCapacity(args);5669 child_argv.appendSliceAssumeCapacity(args);
56405670
5641 if (process.can_replace and options.capture == null) {5671 if (process.can_replace and options.capture == null) {
5642 if (EnvVar.ZIG_DEBUG_CMD.isSet()) {5672 if (EnvVar.ZIG_DEBUG_CMD.isSet(env_map)) {
5643 const cmd = try std.mem.join(arena, " ", child_argv.items);5673 const cmd = try std.mem.join(arena, " ", child_argv.items);
5644 std.debug.print("{s}\n", .{cmd});5674 std.debug.print("{s}\n", .{cmd});
5645 }5675 }
5646 const err = process.execv(gpa, child_argv.items);5676 const err = process.replace(io, .{ .argv = child_argv.items, .env_map = env_map });
5647 const cmd = try std.mem.join(arena, " ", child_argv.items);5677 const cmd = try std.mem.join(arena, " ", child_argv.items);
5648 fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd });5678 fatal("the following command failed to execve with '{t}':\n{s}", .{ err, cmd });
5649 }5679 }
56505680
5651 if (!process.can_spawn) {5681 if (!process.can_spawn) {
5652 const cmd = try std.mem.join(arena, " ", child_argv.items);5682 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}", .{5683 fatal("the following command cannot be executed ({t} does not support spawning a child process):\n{s}", .{
5654 @tagName(native_os), cmd,5684 native_os, cmd,
5655 });5685 });
5656 }5686 }
56575687
5658 var child = std.process.Child.init(child_argv.items, gpa);5688 switch (t: {
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: {
5664 _ = try io.lockStderr(&.{}, .no_color);5689 _ = try io.lockStderr(&.{}, .no_color);
5665 defer io.unlockStderr();5690 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
5668 if (options.capture) |ptr| {5700 if (options.capture) |ptr| {
5669 var stdout_reader = child.stdout.?.readerStreaming(io, &.{});5701 var stdout_reader = child.stdout.?.readerStreaming(io, &.{});
...@@ -5671,9 +5703,8 @@ fn jitCmd(...@@ -5671,9 +5703,8 @@ fn jitCmd(
5671 }5703 }
56725704
5673 break :t try child.wait(io);5705 break :t try child.wait(io);
5674 };5706 }) {
5675 switch (term) {5707 .exited => |code| {
5676 .Exited => |code| {
5677 if (code == 0) {5708 if (code == 0) {
5678 if (options.capture != null) return;5709 if (options.capture != null) return;
5679 return cleanExit(io);5710 return cleanExit(io);
...@@ -5681,6 +5712,10 @@ fn jitCmd(...@@ -5681,6 +5712,10 @@ fn jitCmd(
5681 const cmd = try std.mem.join(arena, " ", child_argv.items);5712 const cmd = try std.mem.join(arena, " ", child_argv.items);
5682 fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });5713 fatal("the following build command failed with exit code {d}:\n{s}", .{ code, cmd });
5683 },5714 },
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 },
5684 else => {5719 else => {
5685 const cmd = try std.mem.join(arena, " ", child_argv.items);5720 const cmd = try std.mem.join(arena, " ", child_argv.items);
5686 fatal("the following build command crashed:\n{s}", .{cmd});5721 fatal("the following build command crashed:\n{s}", .{cmd});
...@@ -5796,7 +5831,7 @@ pub fn lldMain(...@@ -5796,7 +5831,7 @@ pub fn lldMain(
5796 return @intFromBool(!ok);5831 return @intFromBool(!ok);
5797}5832}
57985833
5799const ArgIteratorResponseFile = process.ArgIteratorGeneral(.{ .comments = true, .single_quotes = true });5834const ArgIteratorResponseFile = process.Args.IteratorGeneral(.{ .comments = true, .single_quotes = true });
58005835
5801/// Initialize the arguments from a Response File. "*.rsp"5836/// Initialize the arguments from a Response File. "*.rsp"
5802fn initArgIteratorResponseFile(allocator: Allocator, io: Io, resp_file_path: []const u8) !ArgIteratorResponseFile {5837fn initArgIteratorResponseFile(allocator: Allocator, io: Io, resp_file_path: []const u8) !ArgIteratorResponseFile {
...@@ -6872,14 +6907,15 @@ fn cmdFetch(...@@ -6872,14 +6907,15 @@ fn cmdFetch(
6872 arena: Allocator,6907 arena: Allocator,
6873 io: Io,6908 io: Io,
6874 args: []const []const u8,6909 args: []const []const u8,
6910 env_map: *process.Environ.Map,
6875) !void {6911) !void {
6876 dev.check(.fetch_command);6912 dev.check(.fetch_command);
68776913
6878 const color: Color = .auto;6914 const color: Color = .auto;
6879 const work_around_btrfs_bug = native_os == .linux and6915 const work_around_btrfs_bug = native_os == .linux and
6880 EnvVar.ZIG_BTRFS_WORKAROUND.isSet();6916 EnvVar.ZIG_BTRFS_WORKAROUND.isSet(env_map);
6881 var opt_path_or_url: ?[]const u8 = null;6917 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);
6883 var debug_hash: bool = false;6919 var debug_hash: bool = false;
6884 var save: union(enum) {6920 var save: union(enum) {
6885 no,6921 no,
...@@ -6925,7 +6961,7 @@ fn cmdFetch(...@@ -6925,7 +6961,7 @@ fn cmdFetch(
6925 var http_client: std.http.Client = .{ .allocator = gpa, .io = io };6961 var http_client: std.http.Client = .{ .allocator = gpa, .io = io };
6926 defer http_client.deinit();6962 defer http_client.deinit();
69276963
6928 try http_client.initDefaultProxies(arena);6964 try http_client.initDefaultProxies(arena, env_map);
69296965
6930 var root_prog_node = std.Progress.start(io, .{6966 var root_prog_node = std.Progress.start(io, .{
6931 .root_name = "Fetch",6967 .root_name = "Fetch",
...@@ -6933,7 +6969,7 @@ fn cmdFetch(...@@ -6933,7 +6969,7 @@ fn cmdFetch(
6933 defer root_prog_node.end();6969 defer root_prog_node.end();
69346970
6935 var global_cache_directory: Directory = l: {6971 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);
6937 break :l .{6973 break :l .{
6938 .handle = try Io.Dir.cwd().createDirPathOpen(io, p, .{}),6974 .handle = try Io.Dir.cwd().createDirPathOpen(io, p, .{}),
6939 .path = p,6975 .path = p,
src/print_env.zig+6-4
...@@ -19,9 +19,10 @@ pub fn cmdEnv(...@@ -19,9 +19,10 @@ pub fn cmdEnv(
19 else => void,19 else => void,
20 },20 },
21 host: *const std.Target,21 host: *const std.Target,
22 env_map: *std.process.Environ.Map,
22) !void {23) !void {
23 const override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);24 const override_lib_dir: ?[]const u8 = EnvVar.ZIG_LIB_DIR.get(env_map);
24 const override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);25 const override_global_cache_dir: ?[]const u8 = EnvVar.ZIG_GLOBAL_CACHE_DIR.get(env_map);
2526
26 const self_exe_path = switch (builtin.target.os.tag) {27 const self_exe_path = switch (builtin.target.os.tag) {
27 .wasi => args[0],28 .wasi => args[0],
...@@ -38,6 +39,7 @@ pub fn cmdEnv(...@@ -38,6 +39,7 @@ pub fn cmdEnv(
38 .global,39 .global,
39 if (builtin.target.os.tag == .wasi) wasi_preopens,40 if (builtin.target.os.tag == .wasi) wasi_preopens,
40 if (builtin.target.os.tag != .wasi) self_exe_path,41 if (builtin.target.os.tag != .wasi) self_exe_path,
42 env_map,
41 );43 );
42 defer dirs.deinit(io);44 defer dirs.deinit(io);
4345
...@@ -56,8 +58,8 @@ pub fn cmdEnv(...@@ -56,8 +58,8 @@ pub fn cmdEnv(
56 try root.field("version", build_options.version, .{});58 try root.field("version", build_options.version, .{});
57 try root.field("target", triple, .{});59 try root.field("target", triple, .{});
58 var env = try root.beginStructField("env", .{});60 var env = try root.beginStructField("env", .{});
59 inline for (@typeInfo(std.zig.EnvVar).@"enum".fields) |field| {61 inline for (@typeInfo(EnvVar).@"enum".fields) |field| {
60 try env.field(field.name, try @field(std.zig.EnvVar, field.name).get(arena), .{});62 try env.field(field.name, @field(EnvVar, field.name).get(env_map), .{});
61 }63 }
62 try env.end();64 try env.end();
63 try root.end();65 try root.end();