Merge branch 'Sergeeeek-master'

closes #5394
closes #4427
This commit is contained in:
Andrew Kelley
2020-08-17 18:57:34 -07:00
11 changed files with 165 additions and 13 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

@@ -193,7 +193,7 @@ pub const CacheHash = struct {
const digest_str = iter.next() orelse return error.InvalidFormat;
const file_path = iter.rest();
cache_hash_file.stat.inode = fmt.parseInt(fs.File.INode, mtime_nsec_str, 10) catch return error.InvalidFormat;
cache_hash_file.stat.inode = fmt.parseInt(fs.File.INode, inode, 10) catch return error.InvalidFormat;
cache_hash_file.stat.mtime = fmt.parseInt(i64, mtime_nsec_str, 10) catch return error.InvalidFormat;
base64_decoder.decode(&cache_hash_file.bin_digest, digest_str) catch return error.InvalidFormat;

View File

@@ -3,8 +3,7 @@
const std = @import("std");
const mem = std.mem;
const fs = std.fs;
const warn = std.debug.warn;
const CacheHash = std.cache_hash.CacheHash;
/// Caller must free result
pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {
@@ -63,7 +62,7 @@ pub fn findZigLibDir(allocator: *mem.Allocator) ![]u8 {
pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 {
return findZigLibDir(allocator) catch |err| {
warn(
std.debug.print(
\\Unable to find zig lib directory: {}.
\\Reinstall Zig or use --zig-install-prefix.
\\
@@ -73,7 +72,64 @@ pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 {
};
}
/// Caller must free result
pub fn resolveZigCacheDir(allocator: *mem.Allocator) ![]u8 {
return std.mem.dupe(allocator, u8, "zig-cache");
/// Caller owns returned memory.
pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 {
const appname = "zig";
if (std.Target.current.os.tag != .windows) {
if (std.os.getenv("XDG_CACHE_HOME")) |cache_root| {
return fs.path.join(allocator, &[_][]const u8{ cache_root, appname });
} else if (std.os.getenv("HOME")) |home| {
return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname });
}
}
return fs.getAppDataDir(allocator, appname);
}
var compiler_id_mutex = std.Mutex{};
var compiler_id: [16]u8 = undefined;
var compiler_id_computed = false;
pub fn resolveCompilerId(gpa: *mem.Allocator) ![16]u8 {
const held = compiler_id_mutex.acquire();
defer held.release();
if (compiler_id_computed)
return compiler_id;
compiler_id_computed = true;
const global_cache_dir = try resolveGlobalCacheDir(gpa);
defer gpa.free(global_cache_dir);
// TODO Introduce openGlobalCacheDir which returns a dir handle rather than a string.
var cache_dir = try fs.cwd().openDir(global_cache_dir, .{});
defer cache_dir.close();
var ch = try CacheHash.init(gpa, cache_dir, "exe");
defer ch.release();
const self_exe_path = try fs.selfExePathAlloc(gpa);
defer gpa.free(self_exe_path);
_ = try ch.addFile(self_exe_path, null);
if (try ch.hit()) |digest| {
compiler_id = digest[0..16].*;
return compiler_id;
}
const libs = try std.process.getSelfExeSharedLibPaths(gpa);
defer {
for (libs) |lib| gpa.free(lib);
gpa.free(libs);
}
for (libs) |lib| {
try ch.addFilePost(lib);
}
const digest = ch.final();
compiler_id = digest[0..16].*;
return compiler_id;
}

View File

@@ -30,6 +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
\\ env Print lib path, std path, compiler id and version
\\ version Print version number and exit
\\ zen Print zen of zig and exit
\\
@@ -95,8 +96,9 @@ pub fn main() !void {
const stdout = io.getStdOut().outStream();
return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target);
} else if (mem.eql(u8, cmd, "version")) {
std.io.getStdOut().writeAll(build_options.version ++ "\n") catch process.exit(1);
return;
try std.io.getStdOut().writeAll(build_options.version ++ "\n");
} 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,47 @@
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);
const global_cache_dir = try introspect.resolveGlobalCacheDir(gpa);
defer gpa.free(global_cache_dir);
const compiler_id_digest = try introspect.resolveCompilerId(gpa);
var compiler_id_buf: [compiler_id_digest.len * 2]u8 = undefined;
const compiler_id = std.fmt.bufPrint(&compiler_id_buf, "{x}", .{compiler_id_digest}) catch unreachable;
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("id");
try jws.emitString(compiler_id);
try jws.objectField("global_cache_dir");
try jws.emitString(global_cache_dir);
try jws.objectField("version");
try jws.emitString(build_options.version);
try jws.endObject();
try bos_stream.writeByte('\n');
try bos.flush();
}

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

@@ -179,8 +179,7 @@ export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int {
return 0;
}
fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
const allocator = std.heap.c_allocator;
fn argvToArrayList(allocator: *Allocator, argc: c_int, argv: [*]const [*:0]const u8) !ArrayList([]const u8) {
var args_list = std.ArrayList([]const u8).init(allocator);
const argc_usize = @intCast(usize, argc);
var arg_i: usize = 0;
@@ -188,8 +187,16 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
try args_list.append(mem.spanZ(argv[arg_i]));
}
const args = args_list.span()[2..];
return args_list;
}
fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
const allocator = std.heap.c_allocator;
var args_list = try argvToArrayList(allocator, argc, argv);
defer args_list.deinit();
const args = args_list.span()[2..];
return self_hosted_main.cmdFmt(allocator, args);
}
@@ -387,6 +394,25 @@ fn detectNativeCpuWithLLVM(
return result;
}
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.print("unable to parse arguments: {}\n", .{@errorName(err)});
return -1;
};
defer args_list.deinit();
const args = args_list.span()[2..];
@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;
};
return 0;
}
// ABI warning
export fn stage2_cmd_targets(
zig_triple: ?[*:0]const u8,

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"
@@ -582,6 +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], "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,6 +27,11 @@ void stage2_zen(const char **ptr, size_t *len) {
stage2_panic(msg, strlen(msg));
}
int stage2_env(int argc, char** argv) {
const char *msg = "stage0 called stage2_env";
stage2_panic(msg, strlen(msg));
}
void stage2_attach_segfault_handler(void) { }
void stage2_panic(const char *ptr, size_t len) {

View File

@@ -141,6 +141,9 @@ ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
// ABI warning
ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
// ABI warning
ZIG_EXTERN_C int stage2_env(int argc, char **argv);
// ABI warning
ZIG_EXTERN_C void stage2_attach_segfault_handler(void);