authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-17 17:06:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-17 17:06:43-07:00
log502d413621a8c2de3c6987e7d5a654392e2eab17
tree6cde743fbae8d90ddc823cc9796b6728251353c5
parent80e70735fb9a56279ec990bba17f044a770b339a

simplify `zig info` and rename it to `zig env`

also add version to it

10 files changed, 58 insertions(+), 206 deletions(-)

CMakeLists.txt+7
...@@ -326,10 +326,15 @@ set(LIBUNWIND_FILES_DEST "${ZIG_LIB_DIR}/libunwind")...@@ -326,10 +326,15 @@ set(LIBUNWIND_FILES_DEST "${ZIG_LIB_DIR}/libunwind")
326set(LIBCXX_FILES_DEST "${ZIG_LIB_DIR}/libcxx")326set(LIBCXX_FILES_DEST "${ZIG_LIB_DIR}/libcxx")
327set(ZIG_STD_DEST "${ZIG_LIB_DIR}/std")327set(ZIG_STD_DEST "${ZIG_LIB_DIR}/std")
328set(ZIG_CONFIG_H_OUT "${CMAKE_BINARY_DIR}/config.h")328set(ZIG_CONFIG_H_OUT "${CMAKE_BINARY_DIR}/config.h")
329set(ZIG_CONFIG_ZIG_OUT "${CMAKE_BINARY_DIR}/config.zig")
329configure_file (330configure_file (
330 "${CMAKE_SOURCE_DIR}/src/config.h.in"331 "${CMAKE_SOURCE_DIR}/src/config.h.in"
331 "${ZIG_CONFIG_H_OUT}"332 "${ZIG_CONFIG_H_OUT}"
332)333)
334configure_file (
335 "${CMAKE_SOURCE_DIR}/src/config.zig.in"
336 "${ZIG_CONFIG_ZIG_OUT}"
337)
333338
334include_directories(339include_directories(
335 ${CMAKE_SOURCE_DIR}340 ${CMAKE_SOURCE_DIR}
...@@ -472,6 +477,8 @@ set(BUILD_LIBSTAGE2_ARGS "build-lib"...@@ -472,6 +477,8 @@ set(BUILD_LIBSTAGE2_ARGS "build-lib"
472 --bundle-compiler-rt477 --bundle-compiler-rt
473 -fPIC478 -fPIC
474 -lc479 -lc
480 --pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}"
481 --pkg-end
475)482)
476483
477if("${ZIG_TARGET_TRIPLE}" STREQUAL "native")484if("${ZIG_TARGET_TRIPLE}" STREQUAL "native")
src-self-hosted/main.zig+3-3
...@@ -30,7 +30,7 @@ const usage =...@@ -30,7 +30,7 @@ const usage =
30 \\ build-obj [source] Create object from source or assembly30 \\ build-obj [source] Create object from source or assembly
31 \\ fmt [source] Parse file and render in canonical zig format31 \\ fmt [source] Parse file and render in canonical zig format
32 \\ targets List available compilation targets32 \\ targets List available compilation targets
33 \\ info Print lib path, std path, compiler id and version33 \\ env Print lib path, std path, compiler id and version
34 \\ version Print version number and exit34 \\ version Print version number and exit
35 \\ zen Print zen of zig and exit35 \\ zen Print zen of zig and exit
36 \\36 \\
...@@ -97,8 +97,8 @@ pub fn main() !void {...@@ -97,8 +97,8 @@ pub fn main() !void {
97 return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target);97 return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target);
98 } else if (mem.eql(u8, cmd, "version")) {98 } else if (mem.eql(u8, cmd, "version")) {
99 try std.io.getStdOut().writeAll(build_options.version ++ "\n");99 try std.io.getStdOut().writeAll(build_options.version ++ "\n");
100 } else if (mem.eql(u8, cmd, "info")) {100 } else if (mem.eql(u8, cmd, "env")) {
101 try @import("print_info.zig").cmdInfo(arena, cmd_args, .SelfHosted, io.getStdOut().outStream());101 try @import("print_env.zig").cmdEnv(arena, cmd_args, io.getStdOut().outStream());
102 } else if (mem.eql(u8, cmd, "zen")) {102 } else if (mem.eql(u8, cmd, "zen")) {
103 try io.getStdOut().writeAll(info_zen);103 try io.getStdOut().writeAll(info_zen);
104 } else if (mem.eql(u8, cmd, "help")) {104 } else if (mem.eql(u8, cmd, "help")) {
src-self-hosted/print_env.zig created+34
...@@ -0,0 +1,34 @@
1const std = @import("std");
2const build_options = @import("build_options");
3const introspect = @import("introspect.zig");
4const Allocator = std.mem.Allocator;
5
6pub fn cmdEnv(gpa: *Allocator, args: []const []const u8, stdout: anytype) !void {
7 const zig_lib_dir = introspect.resolveZigLibDir(gpa) catch |err| {
8 std.debug.print("unable to find zig installation directory: {}\n", .{@errorName(err)});
9 std.process.exit(1);
10 };
11 defer gpa.free(zig_lib_dir);
12
13 const zig_std_dir = try std.fs.path.join(gpa, &[_][]const u8{ zig_lib_dir, "std" });
14 defer gpa.free(zig_std_dir);
15
16 var bos = std.io.bufferedOutStream(stdout);
17 const bos_stream = bos.outStream();
18
19 var jws = std.json.WriteStream(@TypeOf(bos_stream), 6).init(bos_stream);
20 try jws.beginObject();
21
22 try jws.objectField("lib_dir");
23 try jws.emitString(zig_lib_dir);
24
25 try jws.objectField("std_dir");
26 try jws.emitString(zig_std_dir);
27
28 try jws.objectField("version");
29 try jws.emitString(build_options.version);
30
31 try jws.endObject();
32 try bos_stream.writeByte('\n');
33 try bos.flush();
34}
src-self-hosted/print_info.zig deleted-192
...@@ -1,192 +0,0 @@
1const builtin = @import("builtin");
2const std = @import("std");
3const process = std.process;
4const mem = std.mem;
5const unicode = std.unicode;
6const io = std.io;
7const fs = std.fs;
8const os = std.os;
9const json = std.json;
10const StringifyOptions = json.StringifyOptions;
11const Allocator = std.mem.Allocator;
12const introspect = @import("introspect.zig");
13
14const usage_info =
15 \\Usage: zig info [options]
16 \\
17 \\ Outputs path to zig lib dir, std dir and the global cache dir.
18 \\
19 \\Options:
20 \\ --help Print this help and exit
21 \\ --format [text|json] Choose output format (defaults to text)
22 \\
23;
24
25pub const CompilerInfo = struct {
26 // TODO: port compiler id hash from cpp
27 // /// Compiler id hash
28 // id: []const u8,
29
30 // /// Compiler version
31 // version: []const u8,
32 /// Path to lib/
33 lib_dir: []const u8,
34
35 /// Path to lib/zig/std
36 std_dir: []const u8,
37
38 /// Path to the global cache dir
39 global_cache_dir: []const u8,
40
41 const CompilerType = enum {
42 Stage1,
43 SelfHosted,
44 };
45
46 pub fn getVersionString() []const u8 {
47 // TODO: get this from build.zig somehow
48 return "0.6.0";
49 }
50
51 pub fn getCacheDir(allocator: *Allocator, compiler_type: CompilerType) ![]u8 {
52 const global_cache_dir = try getAppCacheDir(allocator, "zig");
53 defer allocator.free(global_cache_dir);
54
55 const postfix = switch (compiler_type) {
56 .SelfHosted => "self_hosted",
57 .Stage1 => "stage1",
58 };
59 return try fs.path.join(allocator, &[_][]const u8{ global_cache_dir, postfix }); // stage1 compiler uses $cache_dir/zig/stage1
60 }
61
62 // TODO: add CacheType argument here to make it return correct cache dir for stage1
63 pub fn init(allocator: *Allocator, compiler_type: CompilerType) !CompilerInfo {
64 const zig_lib_dir = try introspect.resolveZigLibDir(allocator);
65 errdefer allocator.free(zig_lib_dir);
66
67 const zig_std_dir = try fs.path.join(allocator, &[_][]const u8{ zig_lib_dir, "std" });
68 errdefer allocator.free(zig_std_dir);
69
70 const cache_dir = try CompilerInfo.getCacheDir(allocator, compiler_type);
71 errdefer allocator.free(cache_dir);
72
73 return CompilerInfo{
74 .lib_dir = zig_lib_dir,
75 .std_dir = zig_std_dir,
76 .global_cache_dir = cache_dir,
77 };
78 }
79
80 pub fn toString(self: *CompilerInfo, out_stream: var) !void {
81 inline for (@typeInfo(CompilerInfo).Struct.fields) |field| {
82 try std.fmt.format(out_stream, "{: <16}\t{: <}\n", .{ field.name, @field(self, field.name) });
83 }
84 }
85
86 pub fn deinit(self: *CompilerInfo, allocator: *Allocator) void {
87 allocator.free(self.lib_dir);
88 allocator.free(self.std_dir);
89 allocator.free(self.global_cache_dir);
90 }
91};
92
93pub fn cmdInfo(allocator: *Allocator, cmd_args: []const []const u8, compiler_type: CompilerInfo.CompilerType, stdout: var) !void {
94 var info = try CompilerInfo.init(allocator, compiler_type);
95 defer info.deinit(allocator);
96
97 var bos = io.bufferedOutStream(stdout);
98 const bos_stream = bos.outStream();
99
100 var json_format = false;
101
102 var i: usize = 0;
103 while (i < cmd_args.len) : (i += 1) {
104 const arg = cmd_args[i];
105 if (mem.eql(u8, arg, "--format")) {
106 if (cmd_args.len <= i + 1) {
107 std.debug.warn("expected [text|json] after --format\n", .{});
108 process.exit(1);
109 }
110 const format = cmd_args[i + 1];
111 i += 1;
112 if (mem.eql(u8, format, "text")) {
113 json_format = false;
114 } else if (mem.eql(u8, format, "json")) {
115 json_format = true;
116 } else {
117 std.debug.warn("expected [text|json] after --format, found '{}'\n", .{format});
118 process.exit(1);
119 }
120 } else if (mem.eql(u8, arg, "--help")) {
121 try stdout.writeAll(usage_info);
122 return;
123 } else {
124 std.debug.warn("unrecognized parameter: '{}'\n", .{arg});
125 process.exit(1);
126 }
127 }
128
129 if (json_format) {
130 try json.stringify(info, StringifyOptions{
131 .whitespace = StringifyOptions.Whitespace{ .indent = .{ .Space = 2 } },
132 }, bos_stream);
133 try bos_stream.writeByte('\n');
134 } else {
135 try info.toString(bos_stream);
136 }
137
138 try bos.flush();
139}
140
141pub const GetAppCacheDirError = error{
142 OutOfMemory,
143 AppCacheDirUnavailable,
144};
145
146// Copied from fs.getAppDataDir, but changed it to return .cache/ dir on linux.
147// This is the same behavior as the current zig compiler global cache resolution.
148fn getAppCacheDir(allocator: *Allocator, appname: []const u8) GetAppCacheDirError![]u8 {
149 switch (builtin.os.tag) {
150 .windows => {
151 var dir_path_ptr: [*:0]u16 = undefined;
152 switch (os.windows.shell32.SHGetKnownFolderPath(
153 &os.windows.FOLDERID_LocalAppData,
154 os.windows.KF_FLAG_CREATE,
155 null,
156 &dir_path_ptr,
157 )) {
158 os.windows.S_OK => {
159 defer os.windows.ole32.CoTaskMemFree(@ptrCast(*c_void, dir_path_ptr));
160 const global_dir = unicode.utf16leToUtf8Alloc(allocator, mem.spanZ(dir_path_ptr)) catch |err| switch (err) {
161 error.UnexpectedSecondSurrogateHalf => return error.AppCacheDirUnavailable,
162 error.ExpectedSecondSurrogateHalf => return error.AppCacheDirUnavailable,
163 error.DanglingSurrogateHalf => return error.AppCacheDirUnavailable,
164 error.OutOfMemory => return error.OutOfMemory,
165 };
166 defer allocator.free(global_dir);
167 return fs.path.join(allocator, &[_][]const u8{ global_dir, appname });
168 },
169 os.windows.E_OUTOFMEMORY => return error.OutOfMemory,
170 else => return error.AppCacheDirUnavailable,
171 }
172 },
173 .macosx => {
174 const home_dir = os.getenv("HOME") orelse {
175 // TODO look in /etc/passwd
176 return error.AppCacheDirUnavailable;
177 };
178 return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
179 },
180 .linux, .freebsd, .netbsd, .dragonfly => {
181 if (os.getenv("XDG_CACHE_HOME")) |cache_home| {
182 return fs.path.join(allocator, &[_][]const u8{ cache_home, appname });
183 }
184
185 const home_dir = os.getenv("HOME") orelse {
186 return error.AppCacheDirUnavailable;
187 };
188 return fs.path.join(allocator, &[_][]const u8{ home_dir, ".cache", appname });
189 },
190 else => @compileError("Unsupported OS"),
191 }
192}
src-self-hosted/print_targets.zig+1-1
...@@ -67,7 +67,7 @@ pub fn cmdTargets(...@@ -67,7 +67,7 @@ pub fn cmdTargets(
67) !void {67) !void {
68 const available_glibcs = blk: {68 const available_glibcs = blk: {
69 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch |err| {69 const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch |err| {
70 std.debug.warn("unable to find zig installation directory: {}\n", .{@errorName(err)});70 std.debug.print("unable to find zig installation directory: {}\n", .{@errorName(err)});
71 std.process.exit(1);71 std.process.exit(1);
72 };72 };
73 defer allocator.free(zig_lib_dir);73 defer allocator.free(zig_lib_dir);
src-self-hosted/stage2.zig+4-4
...@@ -394,19 +394,19 @@ fn detectNativeCpuWithLLVM(...@@ -394,19 +394,19 @@ fn detectNativeCpuWithLLVM(
394 return result;394 return result;
395}395}
396396
397export fn stage2_info(argc: c_int, argv: [*]const [*:0]const u8) c_int {397export fn stage2_env(argc: c_int, argv: [*]const [*:0]const u8) c_int {
398 const allocator = std.heap.c_allocator;398 const allocator = std.heap.c_allocator;
399399
400 var args_list = argvToArrayList(allocator, argc, argv) catch |err| {400 var args_list = argvToArrayList(allocator, argc, argv) catch |err| {
401 std.debug.warn("unable to parse arguments: {}\n", .{@errorName(err)});401 std.debug.print("unable to parse arguments: {}\n", .{@errorName(err)});
402 return -1;402 return -1;
403 };403 };
404 defer args_list.deinit();404 defer args_list.deinit();
405405
406 const args = args_list.span()[2..];406 const args = args_list.span()[2..];
407407
408 @import("print_info.zig").cmdInfo(allocator, args, .Stage1, std.io.getStdOut().outStream()) catch |err| {408 @import("print_env.zig").cmdEnv(allocator, args, std.io.getStdOut().outStream()) catch |err| {
409 std.debug.warn("unable to print info: {}\n", .{@errorName(err)});409 std.debug.print("unable to print info: {}\n", .{@errorName(err)});
410 return -1;410 return -1;
411 };411 };
412412
src/config.zig.in created+3
...@@ -0,0 +1,3 @@
1pub const version: []const u8 = "@ZIG_VERSION@";
2pub const log_scopes: []const []const u8 = &[_][]const u8{};
3pub const enable_tracy = false;
src/main.cpp+3-3
...@@ -38,6 +38,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -38,6 +38,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
38 " builtin show the source code of @import(\"builtin\")\n"38 " builtin show the source code of @import(\"builtin\")\n"
39 " cc use Zig as a drop-in C compiler\n"39 " cc use Zig as a drop-in C compiler\n"
40 " c++ use Zig as a drop-in C++ compiler\n"40 " c++ use Zig as a drop-in C++ compiler\n"
41 " env print lib path, std path, compiler id and version\n"
41 " fmt parse files and render in canonical zig format\n"42 " fmt parse files and render in canonical zig format\n"
42 " id print the base64-encoded compiler id\n"43 " id print the base64-encoded compiler id\n"
43 " init-exe initialize a `zig build` application in the cwd\n"44 " init-exe initialize a `zig build` application in the cwd\n"
...@@ -47,7 +48,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -47,7 +48,6 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
47 " translate-c [source] convert c code to zig code\n"48 " translate-c [source] convert c code to zig code\n"
48 " targets list available compilation targets\n"49 " targets list available compilation targets\n"
49 " test [source] create and run a test build\n"50 " test [source] create and run a test build\n"
50 " info print lib path, std path, compiler id and version\n"
51 " version print version number and exit\n"51 " version print version number and exit\n"
52 " zen print zen of zig and exit\n"52 " zen print zen of zig and exit\n"
53 "\n"53 "\n"
...@@ -583,8 +583,8 @@ static int main0(int argc, char **argv) {...@@ -583,8 +583,8 @@ static int main0(int argc, char **argv) {
583 return (term.how == TerminationIdClean) ? term.code : -1;583 return (term.how == TerminationIdClean) ? term.code : -1;
584 } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {584 } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {
585 return stage2_fmt(argc, argv);585 return stage2_fmt(argc, argv);
586 } else if (argc >= 2 && strcmp(argv[1], "info") == 0) {586 } else if (argc >= 2 && strcmp(argv[1], "env") == 0) {
587 return stage2_info(argc, argv);587 return stage2_env(argc, argv);
588 } else if (argc >= 2 && (strcmp(argv[1], "cc") == 0 || strcmp(argv[1], "c++") == 0)) {588 } else if (argc >= 2 && (strcmp(argv[1], "cc") == 0 || strcmp(argv[1], "c++") == 0)) {
589 emit_h = false;589 emit_h = false;
590 strip = true;590 strip = true;
src/stage2.cpp+2-2
...@@ -27,8 +27,8 @@ void stage2_zen(const char **ptr, size_t *len) {...@@ -27,8 +27,8 @@ void stage2_zen(const char **ptr, size_t *len) {
27 stage2_panic(msg, strlen(msg));27 stage2_panic(msg, strlen(msg));
28}28}
2929
30int stage2_info(int argc, char** argv) {30int stage2_env(int argc, char** argv) {
31 const char *msg = "stage0 called stage2_info";31 const char *msg = "stage0 called stage2_env";
32 stage2_panic(msg, strlen(msg));32 stage2_panic(msg, strlen(msg));
33}33}
3434
src/stage2.h+1-1
...@@ -142,7 +142,7 @@ ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);...@@ -142,7 +142,7 @@ ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
142ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);142ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
143143
144// ABI warning144// ABI warning
145ZIG_EXTERN_C int stage2_info(int argc, char **argv);145ZIG_EXTERN_C int stage2_env(int argc, char **argv);
146146
147// ABI warning147// ABI warning
148ZIG_EXTERN_C void stage2_attach_segfault_handler(void);148ZIG_EXTERN_C void stage2_attach_segfault_handler(void);