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

also add version to it
master
Andrew Kelley 2020-08-17 17:06:23 -07:00
parent 80e70735fb
commit 502d413621
10 changed files with 58 additions and 206 deletions

View File

@ -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")

View File

@ -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")) {

View File

@ -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();
}

View File

@ -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"),
}
}

View File

@ -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);

View File

@ -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;
};

3
src/config.zig.in Normal file
View File

@ -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;

View File

@ -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;

View File

@ -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));
}

View File

@ -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);