authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-08 11:15:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-09 09:28:05-07:00
logc99e34a00e1e839effbc8b257a400eb3b643fa12
tree6104ce4ebeb2b4caa371b8478b5497a97295dbf7
parent35f334ae0fe0f7eef7f8610103e860527df37f42

stage2: eliminate the "compiler id" concept

Instead, append a "dirty suffix" to the version string when there are dirty git changes and use the version string as the compiler id. This avoids a dependency on the cache hash system, and saves time on first invocation of the compiler since it does not have to compute its compiler id. It also saves time by not having to check the cache for a saved compiler id.

5 files changed, 87 insertions(+), 80 deletions(-)

build.zig+86-63
......@@ -56,69 +56,6 @@ pub fn build(b: *Builder) !void {
5656 const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse false;
5757 const config_h_path_option = b.option([]const u8, "config_h", "Path to the generated config.h");
5858
59 if (!only_install_lib_files) {
60 var exe = b.addExecutable("zig", "src-self-hosted/main.zig");
61 exe.install();
62 exe.setBuildMode(mode);
63 exe.setTarget(target);
64 test_step.dependOn(&exe.step);
65 b.default_step.dependOn(&exe.step);
66
67 exe.addBuildOption(bool, "have_llvm", enable_llvm);
68 if (enable_llvm) {
69 const config_h_text = if (config_h_path_option) |config_h_path|
70 try std.fs.cwd().readFileAlloc(b.allocator, toNativePathSep(b, config_h_path), max_config_h_bytes)
71 else
72 try findAndReadConfigH(b);
73
74 var ctx = parseConfigH(b, config_h_text);
75 ctx.llvm = try findLLVM(b, ctx.llvm_config_exe);
76
77 try configureStage2(b, exe, ctx);
78 }
79 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
80 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
81 if (link_libc) {
82 exe.linkLibC();
83 test_stage2.linkLibC();
84 }
85
86 const log_scopes = b.option([]const []const u8, "log", "Which log scopes to enable") orelse &[0][]const u8{};
87 const zir_dumps = b.option([]const []const u8, "dump-zir", "Which functions to dump ZIR for before codegen") orelse &[0][]const u8{};
88
89 const opt_version_string = b.option([]const u8, "version-string", "Override Zig version string. Default is to find out with git.");
90 const version = if (opt_version_string) |version| version else v: {
91 var code: u8 = undefined;
92 const version_untrimmed = b.execAllowFail(&[_][]const u8{
93 "git", "-C", b.build_root, "name-rev", "HEAD",
94 "--tags", "--name-only", "--no-undefined", "--always",
95 }, &code, .Ignore) catch |err| {
96 std.debug.print(
97 \\Unable to determine zig version string: {}
98 \\Provide the zig version string explicitly using the `version-string` build option.
99 , .{err});
100 std.process.exit(1);
101 };
102 const trimmed = mem.trim(u8, version_untrimmed, " \n\r");
103 break :v b.fmt("{}.{}.{}+{}", .{ zig_version.major, zig_version.minor, zig_version.patch, trimmed });
104 };
105 exe.addBuildOption([]const u8, "version", version);
106
107 exe.addBuildOption([]const []const u8, "log_scopes", log_scopes);
108 exe.addBuildOption([]const []const u8, "zir_dumps", zir_dumps);
109 exe.addBuildOption(bool, "enable_tracy", tracy != null);
110 if (tracy) |tracy_path| {
111 const client_cpp = fs.path.join(
112 b.allocator,
113 &[_][]const u8{ tracy_path, "TracyClient.cpp" },
114 ) catch unreachable;
115 exe.addIncludeDir(tracy_path);
116 exe.addCSourceFile(client_cpp, &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" });
117 exe.linkSystemLibraryName("c++");
118 exe.linkLibC();
119 }
120 }
121
12259 b.installDirectory(InstallDirectoryOptions{
12360 .source_dir = "lib",
12461 .install_dir = .Lib,
......@@ -132,6 +69,91 @@ pub fn build(b: *Builder) !void {
13269 },
13370 });
13471
72 if (only_install_lib_files)
73 return;
74
75 var exe = b.addExecutable("zig", "src-self-hosted/main.zig");
76 exe.install();
77 exe.setBuildMode(mode);
78 exe.setTarget(target);
79 test_step.dependOn(&exe.step);
80 b.default_step.dependOn(&exe.step);
81
82 exe.addBuildOption(bool, "have_llvm", enable_llvm);
83 if (enable_llvm) {
84 const config_h_text = if (config_h_path_option) |config_h_path|
85 try std.fs.cwd().readFileAlloc(b.allocator, toNativePathSep(b, config_h_path), max_config_h_bytes)
86 else
87 try findAndReadConfigH(b);
88
89 var ctx = parseConfigH(b, config_h_text);
90 ctx.llvm = try findLLVM(b, ctx.llvm_config_exe);
91
92 try configureStage2(b, exe, ctx);
93 }
94 const tracy = b.option([]const u8, "tracy", "Enable Tracy integration. Supply path to Tracy source");
95 const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse enable_llvm;
96 if (link_libc) {
97 exe.linkLibC();
98 test_stage2.linkLibC();
99 }
100
101 const log_scopes = b.option([]const []const u8, "log", "Which log scopes to enable") orelse &[0][]const u8{};
102 const zir_dumps = b.option([]const []const u8, "dump-zir", "Which functions to dump ZIR for before codegen") orelse &[0][]const u8{};
103
104 const opt_version_string = b.option([]const u8, "version-string", "Override Zig version string. Default is to find out with git.");
105 const version = if (opt_version_string) |version| version else v: {
106 const version_string = b.fmt("{}.{}.{}", .{ zig_version.major, zig_version.minor, zig_version.patch });
107
108 var code: u8 = undefined;
109 const git_sha_untrimmed = b.execAllowFail(&[_][]const u8{
110 "git", "-C", b.build_root, "name-rev", "HEAD",
111 "--tags", "--name-only", "--no-undefined", "--always",
112 }, &code, .Ignore) catch {
113 break :v version_string;
114 };
115 const git_sha_trimmed = mem.trim(u8, git_sha_untrimmed, " \n\r");
116 // Detect dirty changes.
117 const diff_untrimmed = b.execAllowFail(&[_][]const u8{
118 "git", "-C", b.build_root, "diff", "HEAD",
119 }, &code, .Ignore) catch |err| {
120 std.debug.print("Error executing git diff: {}", .{err});
121 std.process.exit(1);
122 };
123 const trimmed_diff = mem.trim(u8, diff_untrimmed, " \n\r");
124 const dirty_suffix = if (trimmed_diff.len == 0) "" else s: {
125 const dirty_hash = std.hash.Wyhash.hash(0, trimmed_diff);
126 break :s b.fmt("dirty{x}", .{@truncate(u32, dirty_hash)});
127 };
128
129 // This will look like e.g. "0.6.0^0" for a tag commit.
130 if (mem.endsWith(u8, git_sha_trimmed, "^0")) {
131 const git_ver_string = git_sha_trimmed[0 .. git_sha_trimmed.len - 2];
132 if (!mem.eql(u8, git_ver_string, version_string)) {
133 std.debug.print("Expected git tag '{}', found '{}'", .{ version_string, git_ver_string });
134 std.process.exit(1);
135 }
136 break :v b.fmt("{}{}", .{ version_string, dirty_suffix });
137 } else {
138 break :v b.fmt("{}+{}{}", .{ version_string, git_sha_trimmed, dirty_suffix });
139 }
140 };
141 exe.addBuildOption([]const u8, "version", version);
142
143 exe.addBuildOption([]const []const u8, "log_scopes", log_scopes);
144 exe.addBuildOption([]const []const u8, "zir_dumps", zir_dumps);
145 exe.addBuildOption(bool, "enable_tracy", tracy != null);
146 if (tracy) |tracy_path| {
147 const client_cpp = fs.path.join(
148 b.allocator,
149 &[_][]const u8{ tracy_path, "TracyClient.cpp" },
150 ) catch unreachable;
151 exe.addIncludeDir(tracy_path);
152 exe.addCSourceFile(client_cpp, &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" });
153 exe.linkSystemLibraryName("c++");
154 exe.linkLibC();
155 }
156
135157 const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
136158
137159 const is_wine_enabled = b.option(bool, "enable-wine", "Use Wine to run cross compiled Windows tests") orelse false;
......@@ -144,6 +166,7 @@ pub fn build(b: *Builder) !void {
144166 test_stage2.addBuildOption(bool, "enable_wine", is_wine_enabled);
145167 test_stage2.addBuildOption(bool, "enable_wasmtime", is_wasmtime_enabled);
146168 test_stage2.addBuildOption(?[]const u8, "glibc_multi_install_dir", glibc_multi_dir);
169 test_stage2.addBuildOption([]const u8, "version", version);
147170
148171 const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");
149172 test_stage2_step.dependOn(&test_stage2.step);
src-self-hosted/Module.zig+1-2
......@@ -952,7 +952,6 @@ pub const InitOptions = struct {
952952 linker_z_nodelete: bool = false,
953953 linker_z_defs: bool = false,
954954 stack_size_override: u64 = 0,
955 compiler_id: [16]u8,
956955};
957956
958957pub fn init(gpa: *Allocator, options: InitOptions) !Module {
......@@ -1056,7 +1055,7 @@ pub fn init(gpa: *Allocator, options: InitOptions) !Module {
10561055
10571056 // Now we will prepare hash state initializations to avoid redundantly computing hashes.
10581057 // First we add common things between things that apply to zig source and all c source files.
1059 cache.add(options.compiler_id);
1058 cache.addBytes(build_options.version);
10601059 cache.add(options.optimize_mode);
10611060 cache.add(options.target.cpu.arch);
10621061 cache.addBytes(options.target.cpu.model.name);
src-self-hosted/main.zig-4
......@@ -960,9 +960,6 @@ pub fn buildOutputType(
960960 .yes_default_path => try std.fmt.allocPrint(arena, "{}.h", .{root_name}),
961961 };
962962
963 // TODO look into implementing compiler_id at build time so we don't have to compute it at runtime.
964 const compiler_id = try introspect.resolveCompilerId(gpa);
965
966963 var module = Module.init(gpa, .{
967964 .root_name = root_name,
968965 .target = target_info.target,
......@@ -1002,7 +999,6 @@ pub fn buildOutputType(
1002999 .linker_z_nodelete = linker_z_nodelete,
10031000 .linker_z_defs = linker_z_defs,
10041001 .stack_size_override = stack_size_override,
1005 .compiler_id = compiler_id,
10061002 .strip = strip,
10071003 }) catch |err| {
10081004 fatal("unable to initialize module: {}", .{@errorName(err)});
src-self-hosted/print_env.zig-7
......@@ -16,10 +16,6 @@ pub fn cmdEnv(gpa: *Allocator, args: []const []const u8, stdout: anytype) !void
1616 const global_cache_dir = try introspect.resolveGlobalCacheDir(gpa);
1717 defer gpa.free(global_cache_dir);
1818
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
2319 var bos = std.io.bufferedOutStream(stdout);
2420 const bos_stream = bos.outStream();
2521
......@@ -32,9 +28,6 @@ pub fn cmdEnv(gpa: *Allocator, args: []const []const u8, stdout: anytype) !void
3228 try jws.objectField("std_dir");
3329 try jws.emitString(zig_std_dir);
3430
35 try jws.objectField("id");
36 try jws.emitString(compiler_id);
37
3831 try jws.objectField("global_cache_dir");
3932 try jws.emitString(global_cache_dir);
4033
src-self-hosted/test.zig-4
......@@ -9,7 +9,6 @@ const enable_qemu: bool = build_options.enable_qemu;
99const enable_wine: bool = build_options.enable_wine;
1010const enable_wasmtime: bool = build_options.enable_wasmtime;
1111const glibc_multi_install_dir: ?[]const u8 = build_options.glibc_multi_install_dir;
12const introspect = @import("introspect.zig");
1312
1413const cheader = @embedFile("link/cbe.h");
1514
......@@ -439,8 +438,6 @@ pub const TestContext = struct {
439438 const ofmt: ?std.builtin.ObjectFormat = if (case.cbe) .c else null;
440439 const bin_name = try std.zig.binNameAlloc(arena, "test_case", target, case.output_mode, null, ofmt);
441440
442 const compiler_id = try introspect.resolveCompilerId(arena);
443
444441 var module = try Module.init(allocator, .{
445442 .root_name = "test_case",
446443 .target = target,
......@@ -455,7 +452,6 @@ pub const TestContext = struct {
455452 .root_pkg = root_pkg,
456453 .keep_source_files_loaded = true,
457454 .object_format = ofmt,
458 .compiler_id = compiler_id,
459455 });
460456 defer module.deinit();
461457