authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-17 18:57:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-17 18:57:34-07:00
loge26dda5308d5c853d195b65558454db4058ff218
treeb3af84ac22492e4b426068e3252a58f160fd93c4
parent044e3ca59222f26ae0a63be24510007c3e2cda82
parent4462c60639807502eca8a2db2bcf6adafea496ef

Merge branch 'Sergeeeek-master'

closes #5394 closes #4427

11 files changed, 165 insertions(+), 13 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")
lib/std/cache_hash.zig+1-1
...@@ -193,7 +193,7 @@ pub const CacheHash = struct {...@@ -193,7 +193,7 @@ pub const CacheHash = struct {
193 const digest_str = iter.next() orelse return error.InvalidFormat;193 const digest_str = iter.next() orelse return error.InvalidFormat;
194 const file_path = iter.rest();194 const file_path = iter.rest();
195195
196 cache_hash_file.stat.inode = fmt.parseInt(fs.File.INode, mtime_nsec_str, 10) catch return error.InvalidFormat;196 cache_hash_file.stat.inode = fmt.parseInt(fs.File.INode, inode, 10) catch return error.InvalidFormat;
197 cache_hash_file.stat.mtime = fmt.parseInt(i64, mtime_nsec_str, 10) catch return error.InvalidFormat;197 cache_hash_file.stat.mtime = fmt.parseInt(i64, mtime_nsec_str, 10) catch return error.InvalidFormat;
198 base64_decoder.decode(&cache_hash_file.bin_digest, digest_str) catch return error.InvalidFormat;198 base64_decoder.decode(&cache_hash_file.bin_digest, digest_str) catch return error.InvalidFormat;
199199
src-self-hosted/introspect.zig+62-6
...@@ -3,8 +3,7 @@...@@ -3,8 +3,7 @@
3const std = @import("std");3const std = @import("std");
4const mem = std.mem;4const mem = std.mem;
5const fs = std.fs;5const fs = std.fs;
66const CacheHash = std.cache_hash.CacheHash;
7const warn = std.debug.warn;
87
9/// Caller must free result8/// Caller must free result
10pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {9pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {
...@@ -63,7 +62,7 @@ pub fn findZigLibDir(allocator: *mem.Allocator) ![]u8 {...@@ -63,7 +62,7 @@ pub fn findZigLibDir(allocator: *mem.Allocator) ![]u8 {
6362
64pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 {63pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 {
65 return findZigLibDir(allocator) catch |err| {64 return findZigLibDir(allocator) catch |err| {
66 warn(65 std.debug.print(
67 \\Unable to find zig lib directory: {}.66 \\Unable to find zig lib directory: {}.
68 \\Reinstall Zig or use --zig-install-prefix.67 \\Reinstall Zig or use --zig-install-prefix.
69 \\68 \\
...@@ -73,7 +72,64 @@ pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 {...@@ -73,7 +72,64 @@ pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 {
73 };72 };
74}73}
7574
76/// Caller must free result75/// Caller owns returned memory.
77pub fn resolveZigCacheDir(allocator: *mem.Allocator) ![]u8 {76pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 {
78 return std.mem.dupe(allocator, u8, "zig-cache");77 const appname = "zig";
78
79 if (std.Target.current.os.tag != .windows) {
80 if (std.os.getenv("XDG_CACHE_HOME")) |cache_root| {
81 return fs.path.join(allocator, &[_][]const u8{ cache_root, appname });
82 } else if (std.os.getenv("HOME")) |home| {
83 return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname });
84 }
85 }
86
87 return fs.getAppDataDir(allocator, appname);
88}
89
90var compiler_id_mutex = std.Mutex{};
91var compiler_id: [16]u8 = undefined;
92var compiler_id_computed = false;
93
94pub fn resolveCompilerId(gpa: *mem.Allocator) ![16]u8 {
95 const held = compiler_id_mutex.acquire();
96 defer held.release();
97
98 if (compiler_id_computed)
99 return compiler_id;
100 compiler_id_computed = true;
101
102 const global_cache_dir = try resolveGlobalCacheDir(gpa);
103 defer gpa.free(global_cache_dir);
104
105 // TODO Introduce openGlobalCacheDir which returns a dir handle rather than a string.
106 var cache_dir = try fs.cwd().openDir(global_cache_dir, .{});
107 defer cache_dir.close();
108
109 var ch = try CacheHash.init(gpa, cache_dir, "exe");
110 defer ch.release();
111
112 const self_exe_path = try fs.selfExePathAlloc(gpa);
113 defer gpa.free(self_exe_path);
114
115 _ = try ch.addFile(self_exe_path, null);
116
117 if (try ch.hit()) |digest| {
118 compiler_id = digest[0..16].*;
119 return compiler_id;
120 }
121
122 const libs = try std.process.getSelfExeSharedLibPaths(gpa);
123 defer {
124 for (libs) |lib| gpa.free(lib);
125 gpa.free(libs);
126 }
127
128 for (libs) |lib| {
129 try ch.addFilePost(lib);
130 }
131
132 const digest = ch.final();
133 compiler_id = digest[0..16].*;
134 return compiler_id;
79}135}
src-self-hosted/main.zig+4-2
...@@ -30,6 +30,7 @@ const usage =...@@ -30,6 +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 \\ env Print lib path, std path, compiler id and version
33 \\ version Print version number and exit34 \\ version Print version number and exit
34 \\ zen Print zen of zig and exit35 \\ zen Print zen of zig and exit
35 \\36 \\
...@@ -95,8 +96,9 @@ pub fn main() !void {...@@ -95,8 +96,9 @@ pub fn main() !void {
95 const stdout = io.getStdOut().outStream();96 const stdout = io.getStdOut().outStream();
96 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);
97 } else if (mem.eql(u8, cmd, "version")) {98 } else if (mem.eql(u8, cmd, "version")) {
98 std.io.getStdOut().writeAll(build_options.version ++ "\n") catch process.exit(1);99 try std.io.getStdOut().writeAll(build_options.version ++ "\n");
99 return;100 } else if (mem.eql(u8, cmd, "env")) {
101 try @import("print_env.zig").cmdEnv(arena, cmd_args, io.getStdOut().outStream());
100 } else if (mem.eql(u8, cmd, "zen")) {102 } else if (mem.eql(u8, cmd, "zen")) {
101 try io.getStdOut().writeAll(info_zen);103 try io.getStdOut().writeAll(info_zen);
102 } else if (mem.eql(u8, cmd, "help")) {104 } else if (mem.eql(u8, cmd, "help")) {
src-self-hosted/print_env.zig created+47
...@@ -0,0 +1,47 @@
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 const global_cache_dir = try introspect.resolveGlobalCacheDir(gpa);
17 defer gpa.free(global_cache_dir);
18
19 const compiler_id_digest = try introspect.resolveCompilerId(gpa);
20 var compiler_id_buf: [compiler_id_digest.len * 2]u8 = undefined;
21 const compiler_id = std.fmt.bufPrint(&compiler_id_buf, "{x}", .{compiler_id_digest}) catch unreachable;
22
23 var bos = std.io.bufferedOutStream(stdout);
24 const bos_stream = bos.outStream();
25
26 var jws = std.json.WriteStream(@TypeOf(bos_stream), 6).init(bos_stream);
27 try jws.beginObject();
28
29 try jws.objectField("lib_dir");
30 try jws.emitString(zig_lib_dir);
31
32 try jws.objectField("std_dir");
33 try jws.emitString(zig_std_dir);
34
35 try jws.objectField("id");
36 try jws.emitString(compiler_id);
37
38 try jws.objectField("global_cache_dir");
39 try jws.emitString(global_cache_dir);
40
41 try jws.objectField("version");
42 try jws.emitString(build_options.version);
43
44 try jws.endObject();
45 try bos_stream.writeByte('\n');
46 try bos.flush();
47}
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+29-3
...@@ -179,8 +179,7 @@ export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int {...@@ -179,8 +179,7 @@ export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int {
179 return 0;179 return 0;
180}180}
181181
182fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {182fn argvToArrayList(allocator: *Allocator, argc: c_int, argv: [*]const [*:0]const u8) !ArrayList([]const u8) {
183 const allocator = std.heap.c_allocator;
184 var args_list = std.ArrayList([]const u8).init(allocator);183 var args_list = std.ArrayList([]const u8).init(allocator);
185 const argc_usize = @intCast(usize, argc);184 const argc_usize = @intCast(usize, argc);
186 var arg_i: usize = 0;185 var arg_i: usize = 0;
...@@ -188,8 +187,16 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {...@@ -188,8 +187,16 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
188 try args_list.append(mem.spanZ(argv[arg_i]));187 try args_list.append(mem.spanZ(argv[arg_i]));
189 }188 }
190189
191 const args = args_list.span()[2..];190 return args_list;
191}
192192
193fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
194 const allocator = std.heap.c_allocator;
195
196 var args_list = try argvToArrayList(allocator, argc, argv);
197 defer args_list.deinit();
198
199 const args = args_list.span()[2..];
193 return self_hosted_main.cmdFmt(allocator, args);200 return self_hosted_main.cmdFmt(allocator, args);
194}201}
195202
...@@ -387,6 +394,25 @@ fn detectNativeCpuWithLLVM(...@@ -387,6 +394,25 @@ fn detectNativeCpuWithLLVM(
387 return result;394 return result;
388}395}
389396
397export fn stage2_env(argc: c_int, argv: [*]const [*:0]const u8) c_int {
398 const allocator = std.heap.c_allocator;
399
400 var args_list = argvToArrayList(allocator, argc, argv) catch |err| {
401 std.debug.print("unable to parse arguments: {}\n", .{@errorName(err)});
402 return -1;
403 };
404 defer args_list.deinit();
405
406 const args = args_list.span()[2..];
407
408 @import("print_env.zig").cmdEnv(allocator, args, std.io.getStdOut().outStream()) catch |err| {
409 std.debug.print("unable to print info: {}\n", .{@errorName(err)});
410 return -1;
411 };
412
413 return 0;
414}
415
390// ABI warning416// ABI warning
391export fn stage2_cmd_targets(417export fn stage2_cmd_targets(
392 zig_triple: ?[*:0]const u8,418 zig_triple: ?[*:0]const u8,
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
...@@ -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"
...@@ -582,6 +583,8 @@ static int main0(int argc, char **argv) {...@@ -582,6 +583,8 @@ static int main0(int argc, char **argv) {
582 return (term.how == TerminationIdClean) ? term.code : -1;583 return (term.how == TerminationIdClean) ? term.code : -1;
583 } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {584 } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {
584 return stage2_fmt(argc, argv);585 return stage2_fmt(argc, argv);
586 } else if (argc >= 2 && strcmp(argv[1], "env") == 0) {
587 return stage2_env(argc, argv);
585 } 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)) {
586 emit_h = false;589 emit_h = false;
587 strip = true;590 strip = true;
src/stage2.cpp+5
...@@ -27,6 +27,11 @@ void stage2_zen(const char **ptr, size_t *len) {...@@ -27,6 +27,11 @@ 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_env(int argc, char** argv) {
31 const char *msg = "stage0 called stage2_env";
32 stage2_panic(msg, strlen(msg));
33}
34
30void stage2_attach_segfault_handler(void) { }35void stage2_attach_segfault_handler(void) { }
3136
32void stage2_panic(const char *ptr, size_t len) {37void stage2_panic(const char *ptr, size_t len) {
src/stage2.h+3
...@@ -141,6 +141,9 @@ ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);...@@ -141,6 +141,9 @@ ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
141// ABI warning141// ABI warning
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 warning
145ZIG_EXTERN_C int stage2_env(int argc, char **argv);
146
144// ABI warning147// ABI warning
145ZIG_EXTERN_C void stage2_attach_segfault_handler(void);148ZIG_EXTERN_C void stage2_attach_segfault_handler(void);
146149