From 502d413621a8c2de3c6987e7d5a654392e2eab17 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 17 Aug 2020 17:06:23 -0700 Subject: [PATCH] simplify `zig info` and rename it to `zig env` also add version to it --- CMakeLists.txt | 7 ++ src-self-hosted/main.zig | 6 +- src-self-hosted/print_env.zig | 34 ++++++ src-self-hosted/print_info.zig | 192 ------------------------------ src-self-hosted/print_targets.zig | 2 +- src-self-hosted/stage2.zig | 8 +- src/config.zig.in | 3 + src/main.cpp | 6 +- src/stage2.cpp | 4 +- src/stage2.h | 2 +- 10 files changed, 58 insertions(+), 206 deletions(-) create mode 100644 src-self-hosted/print_env.zig delete mode 100644 src-self-hosted/print_info.zig create mode 100644 src/config.zig.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 467918557..ceaecf555 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -326,10 +326,15 @@ set(LIBUNWIND_FILES_DEST "${ZIG_LIB_DIR}/libunwind") set(LIBCXX_FILES_DEST "${ZIG_LIB_DIR}/libcxx") set(ZIG_STD_DEST "${ZIG_LIB_DIR}/std") set(ZIG_CONFIG_H_OUT "${CMAKE_BINARY_DIR}/config.h") +set(ZIG_CONFIG_ZIG_OUT "${CMAKE_BINARY_DIR}/config.zig") configure_file ( "${CMAKE_SOURCE_DIR}/src/config.h.in" "${ZIG_CONFIG_H_OUT}" ) +configure_file ( + "${CMAKE_SOURCE_DIR}/src/config.zig.in" + "${ZIG_CONFIG_ZIG_OUT}" +) include_directories( ${CMAKE_SOURCE_DIR} @@ -472,6 +477,8 @@ set(BUILD_LIBSTAGE2_ARGS "build-lib" --bundle-compiler-rt -fPIC -lc + --pkg-begin build_options "${ZIG_CONFIG_ZIG_OUT}" + --pkg-end ) if("${ZIG_TARGET_TRIPLE}" STREQUAL "native") diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index 8e4764f82..d44a7f530 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -30,7 +30,7 @@ const usage = \\ build-obj [source] Create object from source or assembly \\ fmt [source] Parse file and render in canonical zig format \\ targets List available compilation targets - \\ info Print lib path, std path, compiler id and version + \\ env Print lib path, std path, compiler id and version \\ version Print version number and exit \\ zen Print zen of zig and exit \\ @@ -97,8 +97,8 @@ pub fn main() !void { return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target); } else if (mem.eql(u8, cmd, "version")) { try std.io.getStdOut().writeAll(build_options.version ++ "\n"); - } else if (mem.eql(u8, cmd, "info")) { - try @import("print_info.zig").cmdInfo(arena, cmd_args, .SelfHosted, io.getStdOut().outStream()); + } else if (mem.eql(u8, cmd, "env")) { + try @import("print_env.zig").cmdEnv(arena, cmd_args, io.getStdOut().outStream()); } else if (mem.eql(u8, cmd, "zen")) { try io.getStdOut().writeAll(info_zen); } else if (mem.eql(u8, cmd, "help")) { diff --git a/src-self-hosted/print_env.zig b/src-self-hosted/print_env.zig new file mode 100644 index 000000000..444462789 --- /dev/null +++ b/src-self-hosted/print_env.zig @@ -0,0 +1,34 @@ +const std = @import("std"); +const build_options = @import("build_options"); +const introspect = @import("introspect.zig"); +const Allocator = std.mem.Allocator; + +pub fn cmdEnv(gpa: *Allocator, args: []const []const u8, stdout: anytype) !void { + const zig_lib_dir = introspect.resolveZigLibDir(gpa) catch |err| { + std.debug.print("unable to find zig installation directory: {}\n", .{@errorName(err)}); + std.process.exit(1); + }; + defer gpa.free(zig_lib_dir); + + const zig_std_dir = try std.fs.path.join(gpa, &[_][]const u8{ zig_lib_dir, "std" }); + defer gpa.free(zig_std_dir); + + var bos = std.io.bufferedOutStream(stdout); + const bos_stream = bos.outStream(); + + var jws = std.json.WriteStream(@TypeOf(bos_stream), 6).init(bos_stream); + try jws.beginObject(); + + try jws.objectField("lib_dir"); + try jws.emitString(zig_lib_dir); + + try jws.objectField("std_dir"); + try jws.emitString(zig_std_dir); + + try jws.objectField("version"); + try jws.emitString(build_options.version); + + try jws.endObject(); + try bos_stream.writeByte('\n'); + try bos.flush(); +} diff --git a/src-self-hosted/print_info.zig b/src-self-hosted/print_info.zig deleted file mode 100644 index dadf7efbf..000000000 --- a/src-self-hosted/print_info.zig +++ /dev/null @@ -1,192 +0,0 @@ -const builtin = @import("builtin"); -const std = @import("std"); -const process = std.process; -const mem = std.mem; -const unicode = std.unicode; -const io = std.io; -const fs = std.fs; -const os = std.os; -const json = std.json; -const StringifyOptions = json.StringifyOptions; -const Allocator = std.mem.Allocator; -const introspect = @import("introspect.zig"); - -const usage_info = - \\Usage: zig info [options] - \\ - \\ Outputs path to zig lib dir, std dir and the global cache dir. - \\ - \\Options: - \\ --help Print this help and exit - \\ --format [text|json] Choose output format (defaults to text) - \\ -; - -pub const CompilerInfo = struct { - // TODO: port compiler id hash from cpp - // /// Compiler id hash - // id: []const u8, - - // /// Compiler version - // version: []const u8, - /// Path to lib/ - lib_dir: []const u8, - - /// Path to lib/zig/std - std_dir: []const u8, - - /// Path to the global cache dir - global_cache_dir: []const u8, - - const CompilerType = enum { - Stage1, - SelfHosted, - }; - - pub fn getVersionString() []const u8 { - // TODO: get this from build.zig somehow - return "0.6.0"; - } - - pub fn getCacheDir(allocator: *Allocator, compiler_type: CompilerType) ![]u8 { - const global_cache_dir = try getAppCacheDir(allocator, "zig"); - defer allocator.free(global_cache_dir); - - const postfix = switch (compiler_type) { - .SelfHosted => "self_hosted", - .Stage1 => "stage1", - }; - return try fs.path.join(allocator, &[_][]const u8{ global_cache_dir, postfix }); // stage1 compiler uses $cache_dir/zig/stage1 - } - - // TODO: add CacheType argument here to make it return correct cache dir for stage1 - pub fn init(allocator: *Allocator, compiler_type: CompilerType) !CompilerInfo { - const zig_lib_dir = try introspect.resolveZigLibDir(allocator); - errdefer allocator.free(zig_lib_dir); - - const zig_std_dir = try fs.path.join(allocator, &[_][]const u8{ zig_lib_dir, "std" }); - errdefer allocator.free(zig_std_dir); - - const cache_dir = try CompilerInfo.getCacheDir(allocator, compiler_type); - errdefer allocator.free(cache_dir); - - return CompilerInfo{ - .lib_dir = zig_lib_dir, - .std_dir = zig_std_dir, - .global_cache_dir = cache_dir, - }; - } - - pub fn toString(self: *CompilerInfo, out_stream: var) !void { - inline for (@typeInfo(CompilerInfo).Struct.fields) |field| { - try std.fmt.format(out_stream, "{: <16}\t{: <}\n", .{ field.name, @field(self, field.name) }); - } - } - - pub fn deinit(self: *CompilerInfo, allocator: *Allocator) void { - allocator.free(self.lib_dir); - allocator.free(self.std_dir); - allocator.free(self.global_cache_dir); - } -}; - -pub fn cmdInfo(allocator: *Allocator, cmd_args: []const []const u8, compiler_type: CompilerInfo.CompilerType, stdout: var) !void { - var info = try CompilerInfo.init(allocator, compiler_type); - defer info.deinit(allocator); - - var bos = io.bufferedOutStream(stdout); - const bos_stream = bos.outStream(); - - var json_format = false; - - var i: usize = 0; - while (i < cmd_args.len) : (i += 1) { - const arg = cmd_args[i]; - if (mem.eql(u8, arg, "--format")) { - if (cmd_args.len <= i + 1) { - std.debug.warn("expected [text|json] after --format\n", .{}); - process.exit(1); - } - const format = cmd_args[i + 1]; - i += 1; - if (mem.eql(u8, format, "text")) { - json_format = false; - } else if (mem.eql(u8, format, "json")) { - json_format = true; - } else { - std.debug.warn("expected [text|json] after --format, found '{}'\n", .{format}); - process.exit(1); - } - } else if (mem.eql(u8, arg, "--help")) { - try stdout.writeAll(usage_info); - return; - } else { - std.debug.warn("unrecognized parameter: '{}'\n", .{arg}); - process.exit(1); - } - } - - if (json_format) { - try json.stringify(info, StringifyOptions{ - .whitespace = StringifyOptions.Whitespace{ .indent = .{ .Space = 2 } }, - }, bos_stream); - try bos_stream.writeByte('\n'); - } else { - try info.toString(bos_stream); - } - - try bos.flush(); -} - -pub const GetAppCacheDirError = error{ - OutOfMemory, - AppCacheDirUnavailable, -}; - -// Copied from fs.getAppDataDir, but changed it to return .cache/ dir on linux. -// This is the same behavior as the current zig compiler global cache resolution. -fn getAppCacheDir(allocator: *Allocator, appname: []const u8) GetAppCacheDirError![]u8 { - switch (builtin.os.tag) { - .windows => { - var dir_path_ptr: [*:0]u16 = undefined; - switch (os.windows.shell32.SHGetKnownFolderPath( - &os.windows.FOLDERID_LocalAppData, - os.windows.KF_FLAG_CREATE, - null, - &dir_path_ptr, - )) { - os.windows.S_OK => { - defer os.windows.ole32.CoTaskMemFree(@ptrCast(*c_void, dir_path_ptr)); - const global_dir = unicode.utf16leToUtf8Alloc(allocator, mem.spanZ(dir_path_ptr)) catch |err| switch (err) { - error.UnexpectedSecondSurrogateHalf => return error.AppCacheDirUnavailable, - error.ExpectedSecondSurrogateHalf => return error.AppCacheDirUnavailable, - error.DanglingSurrogateHalf => return error.AppCacheDirUnavailable, - error.OutOfMemory => return error.OutOfMemory, - }; - defer allocator.free(global_dir); - return fs.path.join(allocator, &[_][]const u8{ global_dir, appname }); - }, - os.windows.E_OUTOFMEMORY => return error.OutOfMemory, - else => return error.AppCacheDirUnavailable, - } - }, - .macosx => { - const home_dir = os.getenv("HOME") orelse { - // TODO look in /etc/passwd - return error.AppCacheDirUnavailable; - }; - return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname }); - }, - .linux, .freebsd, .netbsd, .dragonfly => { - if (os.getenv("XDG_CACHE_HOME")) |cache_home| { - return fs.path.join(allocator, &[_][]const u8{ cache_home, appname }); - } - - const home_dir = os.getenv("HOME") orelse { - return error.AppCacheDirUnavailable; - }; - return fs.path.join(allocator, &[_][]const u8{ home_dir, ".cache", appname }); - }, - else => @compileError("Unsupported OS"), - } -} diff --git a/src-self-hosted/print_targets.zig b/src-self-hosted/print_targets.zig index 34eda71cc..0fe755ffb 100644 --- a/src-self-hosted/print_targets.zig +++ b/src-self-hosted/print_targets.zig @@ -67,7 +67,7 @@ pub fn cmdTargets( ) !void { const available_glibcs = blk: { const zig_lib_dir = introspect.resolveZigLibDir(allocator) catch |err| { - std.debug.warn("unable to find zig installation directory: {}\n", .{@errorName(err)}); + std.debug.print("unable to find zig installation directory: {}\n", .{@errorName(err)}); std.process.exit(1); }; defer allocator.free(zig_lib_dir); diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index c73fc9790..3e1e80892 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -394,19 +394,19 @@ fn detectNativeCpuWithLLVM( return result; } -export fn stage2_info(argc: c_int, argv: [*]const [*:0]const u8) c_int { +export fn stage2_env(argc: c_int, argv: [*]const [*:0]const u8) c_int { const allocator = std.heap.c_allocator; var args_list = argvToArrayList(allocator, argc, argv) catch |err| { - std.debug.warn("unable to parse arguments: {}\n", .{@errorName(err)}); + std.debug.print("unable to parse arguments: {}\n", .{@errorName(err)}); return -1; }; defer args_list.deinit(); const args = args_list.span()[2..]; - @import("print_info.zig").cmdInfo(allocator, args, .Stage1, std.io.getStdOut().outStream()) catch |err| { - std.debug.warn("unable to print info: {}\n", .{@errorName(err)}); + @import("print_env.zig").cmdEnv(allocator, args, std.io.getStdOut().outStream()) catch |err| { + std.debug.print("unable to print info: {}\n", .{@errorName(err)}); return -1; }; diff --git a/src/config.zig.in b/src/config.zig.in new file mode 100644 index 000000000..ccb618df2 --- /dev/null +++ b/src/config.zig.in @@ -0,0 +1,3 @@ +pub const version: []const u8 = "@ZIG_VERSION@"; +pub const log_scopes: []const []const u8 = &[_][]const u8{}; +pub const enable_tracy = false; diff --git a/src/main.cpp b/src/main.cpp index 23c5bcd02..e2f6a82a1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,6 +38,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " builtin show the source code of @import(\"builtin\")\n" " cc use Zig as a drop-in C compiler\n" " c++ use Zig as a drop-in C++ compiler\n" + " env print lib path, std path, compiler id and version\n" " fmt parse files and render in canonical zig format\n" " id print the base64-encoded compiler id\n" " 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) { " translate-c [source] convert c code to zig code\n" " targets list available compilation targets\n" " test [source] create and run a test build\n" - " info print lib path, std path, compiler id and version\n" " version print version number and exit\n" " zen print zen of zig and exit\n" "\n" @@ -583,8 +583,8 @@ static int main0(int argc, char **argv) { return (term.how == TerminationIdClean) ? term.code : -1; } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) { return stage2_fmt(argc, argv); - } else if (argc >= 2 && strcmp(argv[1], "info") == 0) { - return stage2_info(argc, argv); + } else if (argc >= 2 && strcmp(argv[1], "env") == 0) { + return stage2_env(argc, argv); } else if (argc >= 2 && (strcmp(argv[1], "cc") == 0 || strcmp(argv[1], "c++") == 0)) { emit_h = false; strip = true; diff --git a/src/stage2.cpp b/src/stage2.cpp index ef2b2348e..6c010de84 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -27,8 +27,8 @@ void stage2_zen(const char **ptr, size_t *len) { stage2_panic(msg, strlen(msg)); } -int stage2_info(int argc, char** argv) { - const char *msg = "stage0 called stage2_info"; +int stage2_env(int argc, char** argv) { + const char *msg = "stage0 called stage2_env"; stage2_panic(msg, strlen(msg)); } diff --git a/src/stage2.h b/src/stage2.h index 9ec67ea3f..38a1f77d4 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -142,7 +142,7 @@ ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file); ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len); // ABI warning -ZIG_EXTERN_C int stage2_info(int argc, char **argv); +ZIG_EXTERN_C int stage2_env(int argc, char **argv); // ABI warning ZIG_EXTERN_C void stage2_attach_segfault_handler(void);