authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-18 17:32:59-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-10-18 17:32:59-04:00
log39652331c9060d24d4030317d6d99855763a21e1
treebe278e4d671eea587e518019c4bca74d8df20657
parentd8f7c792986d6b9367f49d914689fc2744fdb73a
parent09dea957ed74f87b7f5f88bc2c760f3f93d0165a
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #14428 from perillo/improve-zig-env

zig env: add support for line based output

6 files changed, 109 insertions(+), 86 deletions(-)

src/introspect.zig+45-11
...@@ -4,6 +4,7 @@ const mem = std.mem;...@@ -4,6 +4,7 @@ const mem = std.mem;
4const os = std.os;4const os = std.os;
5const fs = std.fs;5const fs = std.fs;
6const Compilation = @import("Compilation.zig");6const Compilation = @import("Compilation.zig");
7const build_options = @import("build_options");
78
8/// Returns the sub_path that worked, or `null` if none did.9/// Returns the sub_path that worked, or `null` if none did.
9/// The path of the returned Directory is relative to `base`.10/// The path of the returned Directory is relative to `base`.
...@@ -80,23 +81,17 @@ pub fn findZigLibDirFromSelfExe(...@@ -80,23 +81,17 @@ pub fn findZigLibDirFromSelfExe(
8081
81/// Caller owns returned memory.82/// Caller owns returned memory.
82pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 {83pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 {
83 if (builtin.os.tag == .wasi) {84 if (builtin.os.tag == .wasi)
84 @compileError("on WASI the global cache dir must be resolved with preopens");85 @compileError("on WASI the global cache dir must be resolved with preopens");
85 }86
86 if (std.process.getEnvVarOwned(allocator, "ZIG_GLOBAL_CACHE_DIR")) |value| {87 if (try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(allocator)) |value| return value;
87 if (value.len > 0) {
88 return value;
89 } else {
90 allocator.free(value);
91 }
92 } else |_| {}
9388
94 const appname = "zig";89 const appname = "zig";
9590
96 if (builtin.os.tag != .windows) {91 if (builtin.os.tag != .windows) {
97 if (std.os.getenv("XDG_CACHE_HOME")) |cache_root| {92 if (EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| {
98 return fs.path.join(allocator, &[_][]const u8{ cache_root, appname });93 return fs.path.join(allocator, &[_][]const u8{ cache_root, appname });
99 } else if (std.os.getenv("HOME")) |home| {94 } else if (EnvVar.HOME.getPosix()) |home| {
100 return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname });95 return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname });
101 }96 }
102 }97 }
...@@ -146,3 +141,42 @@ pub fn resolvePath(...@@ -146,3 +141,42 @@ pub fn resolvePath(
146pub fn isUpDir(p: []const u8) bool {141pub fn isUpDir(p: []const u8) bool {
147 return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == fs.path.sep);142 return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == fs.path.sep);
148}143}
144
145/// Collects all the environment variables that Zig could possibly inspect, so
146/// that we can do reflection on this and print them with `zig env`.
147pub const EnvVar = enum {
148 ZIG_GLOBAL_CACHE_DIR,
149 ZIG_LOCAL_CACHE_DIR,
150 ZIG_LIB_DIR,
151 ZIG_LIBC,
152 ZIG_BUILD_RUNNER,
153 ZIG_VERBOSE_LINK,
154 ZIG_VERBOSE_CC,
155 ZIG_BTRFS_WORKAROUND,
156 CC,
157 NO_COLOR,
158 XDG_CACHE_HOME,
159 HOME,
160 /// https://github.com/ziglang/zig/issues/17585
161 INCLUDE,
162
163 pub fn isSet(comptime ev: EnvVar) bool {
164 return std.process.hasEnvVarConstant(@tagName(ev));
165 }
166
167 pub fn get(ev: EnvVar, arena: mem.Allocator) !?[]u8 {
168 // Env vars aren't used in the bootstrap stage.
169 if (build_options.only_c) return null;
170
171 if (std.process.getEnvVarOwned(arena, @tagName(ev))) |value| {
172 return value;
173 } else |err| switch (err) {
174 error.EnvironmentVariableNotFound => return null,
175 else => |e| return e,
176 }
177 }
178
179 pub fn getPosix(comptime ev: EnvVar) ?[:0]const u8 {
180 return std.os.getenvZ(@tagName(ev));
181 }
182};
src/libc_installation.zig+2-1
...@@ -11,6 +11,7 @@ const is_haiku = builtin.target.os.tag == .haiku;...@@ -11,6 +11,7 @@ const is_haiku = builtin.target.os.tag == .haiku;
11const log = std.log.scoped(.libc_installation);11const log = std.log.scoped(.libc_installation);
1212
13const ZigWindowsSDK = @import("windows_sdk.zig").ZigWindowsSDK;13const ZigWindowsSDK = @import("windows_sdk.zig").ZigWindowsSDK;
14const EnvVar = @import("introspect.zig").EnvVar;
1415
15/// See the render function implementation for documentation of the fields.16/// See the render function implementation for documentation of the fields.
16pub const LibCInstallation = struct {17pub const LibCInstallation = struct {
...@@ -694,7 +695,7 @@ fn appendCcExe(args: *std.ArrayList([]const u8), skip_cc_env_var: bool) !void {...@@ -694,7 +695,7 @@ fn appendCcExe(args: *std.ArrayList([]const u8), skip_cc_env_var: bool) !void {
694 args.appendAssumeCapacity(default_cc_exe);695 args.appendAssumeCapacity(default_cc_exe);
695 return;696 return;
696 }697 }
697 const cc_env_var = std.os.getenvZ("CC") orelse {698 const cc_env_var = EnvVar.CC.getPosix() orelse {
698 args.appendAssumeCapacity(default_cc_exe);699 args.appendAssumeCapacity(default_cc_exe);
699 return;700 return;
700 };701 };
src/main.zig+27-37
...@@ -18,6 +18,7 @@ const link = @import("link.zig");...@@ -18,6 +18,7 @@ const link = @import("link.zig");
18const Package = @import("Package.zig");18const Package = @import("Package.zig");
19const build_options = @import("build_options");19const build_options = @import("build_options");
20const introspect = @import("introspect.zig");20const introspect = @import("introspect.zig");
21const EnvVar = introspect.EnvVar;
21const LibCInstallation = @import("libc_installation.zig").LibCInstallation;22const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
22const wasi_libc = @import("wasi_libc.zig");23const wasi_libc = @import("wasi_libc.zig");
23const BuildId = std.Build.CompileStep.BuildId;24const BuildId = std.Build.CompileStep.BuildId;
...@@ -231,14 +232,14 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi...@@ -231,14 +232,14 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
231 fatal("expected command argument", .{});232 fatal("expected command argument", .{});
232 }233 }
233234
234 if (std.process.can_execv and std.os.getenvZ("ZIG_IS_DETECTING_LIBC_PATHS") != null) {235 if (process.can_execv and std.os.getenvZ("ZIG_IS_DETECTING_LIBC_PATHS") != null) {
235 // In this case we have accidentally invoked ourselves as "the system C compiler"236 // In this case we have accidentally invoked ourselves as "the system C compiler"
236 // to figure out where libc is installed. This is essentially infinite recursion237 // to figure out where libc is installed. This is essentially infinite recursion
237 // via child process execution due to the CC environment variable pointing to Zig.238 // via child process execution due to the CC environment variable pointing to Zig.
238 // Here we ignore the CC environment variable and exec `cc` as a child process.239 // Here we ignore the CC environment variable and exec `cc` as a child process.
239 // However it's possible Zig is installed as *that* C compiler as well, which is240 // However it's possible Zig is installed as *that* C compiler as well, which is
240 // why we have this additional environment variable here to check.241 // why we have this additional environment variable here to check.
241 var env_map = try std.process.getEnvMap(arena);242 var env_map = try process.getEnvMap(arena);
242243
243 const inf_loop_env_key = "ZIG_IS_TRYING_TO_NOT_CALL_ITSELF";244 const inf_loop_env_key = "ZIG_IS_TRYING_TO_NOT_CALL_ITSELF";
244 if (env_map.get(inf_loop_env_key) != null) {245 if (env_map.get(inf_loop_env_key) != null) {
...@@ -254,11 +255,11 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi...@@ -254,11 +255,11 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
254 // CC environment variable. We detect and support this scenario here because of255 // CC environment variable. We detect and support this scenario here because of
255 // the ZIG_IS_DETECTING_LIBC_PATHS environment variable.256 // the ZIG_IS_DETECTING_LIBC_PATHS environment variable.
256 if (mem.eql(u8, args[1], "cc")) {257 if (mem.eql(u8, args[1], "cc")) {
257 return std.process.execve(arena, args[1..], &env_map);258 return process.execve(arena, args[1..], &env_map);
258 } else {259 } else {
259 const modified_args = try arena.dupe([]const u8, args);260 const modified_args = try arena.dupe([]const u8, args);
260 modified_args[0] = "cc";261 modified_args[0] = "cc";
261 return std.process.execve(arena, modified_args, &env_map);262 return process.execve(arena, modified_args, &env_map);
262 }263 }
263 }264 }
264265
...@@ -686,19 +687,6 @@ const Emit = union(enum) {...@@ -686,19 +687,6 @@ const Emit = union(enum) {
686 }687 }
687};688};
688689
689fn optionalStringEnvVar(arena: Allocator, name: []const u8) !?[]const u8 {
690 // Env vars aren't used in the bootstrap stage.
691 if (build_options.only_c) {
692 return null;
693 }
694 if (std.process.getEnvVarOwned(arena, name)) |value| {
695 return value;
696 } else |err| switch (err) {
697 error.EnvironmentVariableNotFound => return null,
698 else => |e| return e,
699 }
700}
701
702const ArgMode = union(enum) {690const ArgMode = union(enum) {
703 build: std.builtin.OutputMode,691 build: std.builtin.OutputMode,
704 cc,692 cc,
...@@ -797,8 +785,10 @@ fn buildOutputType(...@@ -797,8 +785,10 @@ fn buildOutputType(
797 var no_builtin = false;785 var no_builtin = false;
798 var listen: Listen = .none;786 var listen: Listen = .none;
799 var debug_compile_errors = false;787 var debug_compile_errors = false;
800 var verbose_link = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_LINK");788 var verbose_link = (builtin.os.tag != .wasi or builtin.link_libc) and
801 var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_CC");789 EnvVar.ZIG_VERBOSE_LINK.isSet();
790 var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and
791 EnvVar.ZIG_VERBOSE_CC.isSet();
802 var verbose_air = false;792 var verbose_air = false;
803 var verbose_intern_pool = false;793 var verbose_intern_pool = false;
804 var verbose_generic_instances = false;794 var verbose_generic_instances = false;
...@@ -892,15 +882,15 @@ fn buildOutputType(...@@ -892,15 +882,15 @@ fn buildOutputType(
892 var each_lib_rpath: ?bool = null;882 var each_lib_rpath: ?bool = null;
893 var build_id: ?BuildId = null;883 var build_id: ?BuildId = null;
894 var sysroot: ?[]const u8 = null;884 var sysroot: ?[]const u8 = null;
895 var libc_paths_file: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LIBC");885 var libc_paths_file: ?[]const u8 = try EnvVar.ZIG_LIBC.get(arena);
896 var machine_code_model: std.builtin.CodeModel = .default;886 var machine_code_model: std.builtin.CodeModel = .default;
897 var runtime_args_start: ?usize = null;887 var runtime_args_start: ?usize = null;
898 var test_filter: ?[]const u8 = null;888 var test_filter: ?[]const u8 = null;
899 var test_name_prefix: ?[]const u8 = null;889 var test_name_prefix: ?[]const u8 = null;
900 var test_runner_path: ?[]const u8 = null;890 var test_runner_path: ?[]const u8 = null;
901 var override_local_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LOCAL_CACHE_DIR");891 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);
902 var override_global_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_GLOBAL_CACHE_DIR");892 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
903 var override_lib_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LIB_DIR");893 var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);
904 var main_mod_path: ?[]const u8 = null;894 var main_mod_path: ?[]const u8 = null;
905 var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;895 var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;
906 var subsystem: ?std.Target.SubSystem = null;896 var subsystem: ?std.Target.SubSystem = null;
...@@ -960,7 +950,7 @@ fn buildOutputType(...@@ -960,7 +950,7 @@ fn buildOutputType(
960 // if it exists, default the color setting to .off950 // if it exists, default the color setting to .off
961 // explicit --color arguments will still override this setting.951 // explicit --color arguments will still override this setting.
962 // Disable color on WASI per https://github.com/WebAssembly/WASI/issues/162952 // Disable color on WASI per https://github.com/WebAssembly/WASI/issues/162
963 color = if (builtin.os.tag == .wasi or std.process.hasEnvVarConstant("NO_COLOR")) .off else .auto;953 color = if (builtin.os.tag == .wasi or EnvVar.NO_COLOR.isSet()) .off else .auto;
964954
965 switch (arg_mode) {955 switch (arg_mode) {
966 .build, .translate_c, .zig_test, .run => {956 .build, .translate_c, .zig_test, .run => {
...@@ -4059,18 +4049,18 @@ fn runOrTest(...@@ -4059,18 +4049,18 @@ fn runOrTest(
4059 if (runtime_args_start) |i| {4049 if (runtime_args_start) |i| {
4060 try argv.appendSlice(all_args[i..]);4050 try argv.appendSlice(all_args[i..]);
4061 }4051 }
4062 var env_map = try std.process.getEnvMap(arena);4052 var env_map = try process.getEnvMap(arena);
4063 try env_map.put("ZIG_EXE", self_exe_path);4053 try env_map.put("ZIG_EXE", self_exe_path);
40644054
4065 // We do not execve for tests because if the test fails we want to print4055 // We do not execve for tests because if the test fails we want to print
4066 // the error message and invocation below.4056 // the error message and invocation below.
4067 if (std.process.can_execv and arg_mode == .run) {4057 if (process.can_execv and arg_mode == .run) {
4068 // execv releases the locks; no need to destroy the Compilation here.4058 // execv releases the locks; no need to destroy the Compilation here.
4069 const err = std.process.execve(gpa, argv.items, &env_map);4059 const err = process.execve(gpa, argv.items, &env_map);
4070 try warnAboutForeignBinaries(arena, arg_mode, target_info, link_libc);4060 try warnAboutForeignBinaries(arena, arg_mode, target_info, link_libc);
4071 const cmd = try std.mem.join(arena, " ", argv.items);4061 const cmd = try std.mem.join(arena, " ", argv.items);
4072 fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });4062 fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
4073 } else if (std.process.can_spawn) {4063 } else if (process.can_spawn) {
4074 var child = std.ChildProcess.init(argv.items, gpa);4064 var child = std.ChildProcess.init(argv.items, gpa);
4075 child.env_map = &env_map;4065 child.env_map = &env_map;
4076 child.stdin_behavior = .Inherit;4066 child.stdin_behavior = .Inherit;
...@@ -4490,7 +4480,7 @@ fn cmdRc(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4490,7 +4480,7 @@ fn cmdRc(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4490 try stdout_writer.print("{s}\n\n", .{argv.items[argv.items.len - 1]});4480 try stdout_writer.print("{s}\n\n", .{argv.items[argv.items.len - 1]});
4491 }4481 }
44924482
4493 if (std.process.can_spawn) {4483 if (process.can_spawn) {
4494 var result = std.ChildProcess.exec(.{4484 var result = std.ChildProcess.exec(.{
4495 .allocator = gpa,4485 .allocator = gpa,
4496 .argv = argv.items,4486 .argv = argv.items,
...@@ -4923,7 +4913,7 @@ pub const usage_build =...@@ -4923,7 +4913,7 @@ pub const usage_build =
49234913
4924pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {4914pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4925 const work_around_btrfs_bug = builtin.os.tag == .linux and4915 const work_around_btrfs_bug = builtin.os.tag == .linux and
4926 std.process.hasEnvVarConstant("ZIG_BTRFS_WORKAROUND");4916 EnvVar.ZIG_BTRFS_WORKAROUND.isSet();
4927 var color: Color = .auto;4917 var color: Color = .auto;
49284918
4929 // We want to release all the locks before executing the child process, so we make a nice4919 // We want to release all the locks before executing the child process, so we make a nice
...@@ -4932,10 +4922,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi...@@ -4932,10 +4922,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
4932 const self_exe_path = try introspect.findZigExePath(arena);4922 const self_exe_path = try introspect.findZigExePath(arena);
49334923
4934 var build_file: ?[]const u8 = null;4924 var build_file: ?[]const u8 = null;
4935 var override_lib_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LIB_DIR");4925 var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);
4936 var override_global_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_GLOBAL_CACHE_DIR");4926 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
4937 var override_local_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_LOCAL_CACHE_DIR");4927 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);
4938 var override_build_runner: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_BUILD_RUNNER");4928 var override_build_runner: ?[]const u8 = try EnvVar.ZIG_BUILD_RUNNER.get(arena);
4939 var child_argv = std.ArrayList([]const u8).init(arena);4929 var child_argv = std.ArrayList([]const u8).init(arena);
4940 var reference_trace: ?u32 = null;4930 var reference_trace: ?u32 = null;
4941 var debug_compile_errors = false;4931 var debug_compile_errors = false;
...@@ -5293,7 +5283,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi...@@ -5293,7 +5283,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
5293 break :argv child_argv.items;5283 break :argv child_argv.items;
5294 };5284 };
52955285
5296 if (std.process.can_spawn) {5286 if (process.can_spawn) {
5297 var child = std.ChildProcess.init(child_argv, gpa);5287 var child = std.ChildProcess.init(child_argv, gpa);
5298 child.stdin_behavior = .Inherit;5288 child.stdin_behavior = .Inherit;
5299 child.stdout_behavior = .Inherit;5289 child.stdout_behavior = .Inherit;
...@@ -7004,9 +6994,9 @@ fn cmdFetch(...@@ -7004,9 +6994,9 @@ fn cmdFetch(
7004) !void {6994) !void {
7005 const color: Color = .auto;6995 const color: Color = .auto;
7006 const work_around_btrfs_bug = builtin.os.tag == .linux and6996 const work_around_btrfs_bug = builtin.os.tag == .linux and
7007 std.process.hasEnvVarConstant("ZIG_BTRFS_WORKAROUND");6997 EnvVar.ZIG_BTRFS_WORKAROUND.isSet();
7008 var opt_path_or_url: ?[]const u8 = null;6998 var opt_path_or_url: ?[]const u8 = null;
7009 var override_global_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_GLOBAL_CACHE_DIR");6999 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
7010 var debug_hash: bool = false;7000 var debug_hash: bool = false;
70117001
7012 {7002 {
src/print_env.zig+30-34
...@@ -4,53 +4,49 @@ const introspect = @import("introspect.zig");...@@ -4,53 +4,49 @@ const introspect = @import("introspect.zig");
4const Allocator = std.mem.Allocator;4const Allocator = std.mem.Allocator;
5const fatal = @import("main.zig").fatal;5const fatal = @import("main.zig").fatal;
66
7pub fn cmdEnv(gpa: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void {7pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void {
8 _ = args;8 _ = args;
9 const self_exe_path = try introspect.findZigExePath(gpa);9 const self_exe_path = try introspect.findZigExePath(arena);
10 defer gpa.free(self_exe_path);
1110
12 var zig_lib_directory = introspect.findZigLibDirFromSelfExe(gpa, self_exe_path) catch |err| {11 var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| {
13 fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)});12 fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)});
14 };13 };
15 defer gpa.free(zig_lib_directory.path.?);
16 defer zig_lib_directory.handle.close();14 defer zig_lib_directory.handle.close();
1715
18 const zig_std_dir = try std.fs.path.join(gpa, &[_][]const u8{ zig_lib_directory.path.?, "std" });16 const zig_std_dir = try std.fs.path.join(arena, &[_][]const u8{ zig_lib_directory.path.?, "std" });
19 defer gpa.free(zig_std_dir);
2017
21 const global_cache_dir = try introspect.resolveGlobalCacheDir(gpa);18 const global_cache_dir = try introspect.resolveGlobalCacheDir(arena);
22 defer gpa.free(global_cache_dir);
2319
24 const info = try std.zig.system.NativeTargetInfo.detect(.{});20 const info = try std.zig.system.NativeTargetInfo.detect(.{});
25 const triple = try info.target.zigTriple(gpa);21 const triple = try info.target.zigTriple(arena);
26 defer gpa.free(triple);
2722
28 var bw = std.io.bufferedWriter(stdout);23 var bw = std.io.bufferedWriter(stdout);
29 const w = bw.writer();24 const w = bw.writer();
3025
31 var jws = std.json.writeStream(w, .{ .whitespace = .indent_1 });26 try w.print(
27 \\zig_exe={s}
28 \\lib_dir={s}
29 \\std_dir={s}
30 \\global_cache_dir={s}
31 \\version={s}
32 \\target={s}
33 \\
34 , .{
35 self_exe_path,
36 zig_lib_directory.path.?,
37 zig_std_dir,
38 global_cache_dir,
39 build_options.version,
40 triple,
41 });
42
43 inline for (@typeInfo(introspect.EnvVar).Enum.fields) |field| {
44 if (try @field(introspect.EnvVar, field.name).get(arena)) |value| {
45 try w.print("{s}={s}\n", .{ field.name, value });
46 } else {
47 try w.print("{s}\n", .{field.name});
48 }
49 }
3250
33 try jws.beginObject();
34
35 try jws.objectField("zig_exe");
36 try jws.write(self_exe_path);
37
38 try jws.objectField("lib_dir");
39 try jws.write(zig_lib_directory.path.?);
40
41 try jws.objectField("std_dir");
42 try jws.write(zig_std_dir);
43
44 try jws.objectField("global_cache_dir");
45 try jws.write(global_cache_dir);
46
47 try jws.objectField("version");
48 try jws.write(build_options.version);
49
50 try jws.objectField("target");
51 try jws.write(triple);
52
53 try jws.endObject();
54 try w.writeByte('\n');
55 try bw.flush();51 try bw.flush();
56}52}
src/resinator/compile.zig+3-2
...@@ -28,6 +28,7 @@ const windows1252 = @import("windows1252.zig");...@@ -28,6 +28,7 @@ const windows1252 = @import("windows1252.zig");
28const lang = @import("lang.zig");28const lang = @import("lang.zig");
29const code_pages = @import("code_pages.zig");29const code_pages = @import("code_pages.zig");
30const errors = @import("errors.zig");30const errors = @import("errors.zig");
31const introspect = @import("../introspect.zig");
3132
32pub const CompileOptions = struct {33pub const CompileOptions = struct {
33 cwd: std.fs.Dir,34 cwd: std.fs.Dir,
...@@ -91,7 +92,7 @@ pub fn compile(allocator: Allocator, source: []const u8, writer: anytype, option...@@ -91,7 +92,7 @@ pub fn compile(allocator: Allocator, source: []const u8, writer: anytype, option
91 // `catch unreachable` since `options.cwd` is expected to be a valid dir handle, so opening92 // `catch unreachable` since `options.cwd` is expected to be a valid dir handle, so opening
92 // a new handle to it should be fine as well.93 // a new handle to it should be fine as well.
93 // TODO: Maybe catch and return an error instead94 // TODO: Maybe catch and return an error instead
94 const cwd_dir = options.cwd.openDir(".", .{}) catch unreachable;95 const cwd_dir = options.cwd.openDir(".", .{}) catch @panic("unable to open dir");
95 try search_dirs.append(.{ .dir = cwd_dir, .path = null });96 try search_dirs.append(.{ .dir = cwd_dir, .path = null });
96 for (options.extra_include_paths) |extra_include_path| {97 for (options.extra_include_paths) |extra_include_path| {
97 var dir = openSearchPathDir(options.cwd, extra_include_path) catch {98 var dir = openSearchPathDir(options.cwd, extra_include_path) catch {
...@@ -110,7 +111,7 @@ pub fn compile(allocator: Allocator, source: []const u8, writer: anytype, option...@@ -110,7 +111,7 @@ pub fn compile(allocator: Allocator, source: []const u8, writer: anytype, option
110 try search_dirs.append(.{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) });111 try search_dirs.append(.{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) });
111 }112 }
112 if (!options.ignore_include_env_var) {113 if (!options.ignore_include_env_var) {
113 const INCLUDE = std.process.getEnvVarOwned(allocator, "INCLUDE") catch "";114 const INCLUDE = (introspect.EnvVar.INCLUDE.get(allocator) catch @panic("OOM")) orelse "";
114 defer allocator.free(INCLUDE);115 defer allocator.free(INCLUDE);
115116
116 // TODO: Should this be platform-specific? How does windres/llvm-rc handle this (if at all)?117 // TODO: Should this be platform-specific? How does windres/llvm-rc handle this (if at all)?
src/resinator/preprocess.zig+2-1
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const Allocator = std.mem.Allocator;2const Allocator = std.mem.Allocator;
3const cli = @import("cli.zig");3const cli = @import("cli.zig");
4const introspect = @import("../introspect.zig");
45
5pub const IncludeArgs = struct {6pub const IncludeArgs = struct {
6 clang_target: ?[]const u8 = null,7 clang_target: ?[]const u8 = null,
...@@ -67,7 +68,7 @@ pub fn appendClangArgs(arena: Allocator, argv: *std.ArrayList([]const u8), optio...@@ -67,7 +68,7 @@ pub fn appendClangArgs(arena: Allocator, argv: *std.ArrayList([]const u8), optio
67 }68 }
6869
69 if (!options.ignore_include_env_var) {70 if (!options.ignore_include_env_var) {
70 const INCLUDE = std.process.getEnvVarOwned(arena, "INCLUDE") catch "";71 const INCLUDE = (introspect.EnvVar.INCLUDE.get(arena) catch @panic("OOM")) orelse "";
7172
72 // TODO: Should this be platform-specific? How does windres/llvm-rc handle this (if at all)?73 // TODO: Should this be platform-specific? How does windres/llvm-rc handle this (if at all)?
73 var it = std.mem.tokenize(u8, INCLUDE, ";");74 var it = std.mem.tokenize(u8, INCLUDE, ";");