authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-30 15:32:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-02 13:16:17-07:00
log67e31807df73ad2da992293fcdf1f6ea7ca67d2a
tree89182e7bc11d3b661ba3697faa5f21e96ae050c6
parente3bed8d81dfd7198dd4c496f19a6791e27e41f26

stage2: CacheMode.whole fixes

* Logic to check whether a bin file is not emitted is more complicated in between `Compilation.create` and `Compilation.update`. Fixed the logic that decides whether to build compiler-rt and other support artifacts. * Basically, one cannot inspect the value of `comp.bin_file.emit` until after update() is called - fixed another instance of this happening in the CLI. * In the CLI, `runOrTest` is updated to properly use the result value of `comp.bin_file.options.emit` rather than guessing whether the output binary is. * Don't assume that the emit output has no directory components in sub_path. In other words, don't assume that the emit directory is the final directory; there may be sub-directories.

2 files changed, 26 insertions(+), 15 deletions(-)

src/Compilation.zig+10-1
......@@ -1662,7 +1662,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
16621662 comp.c_object_table.putAssumeCapacityNoClobber(c_object, {});
16631663 }
16641664
1665 if (comp.bin_file.options.emit != null and !comp.bin_file.options.skip_linker_dependencies) {
1665 const have_bin_emit = comp.bin_file.options.emit != null or comp.whole_bin_basename != null;
1666
1667 if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies) {
16661668 // If we need to build glibc for the target, add work items for it.
16671669 // We go through the work queue so that building can be done in parallel.
16681670 if (comp.wantBuildGLibCFromSource()) {
......@@ -1767,8 +1769,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
17671769
17681770 if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {
17691771 if (is_exe_or_dyn_lib) {
1772 log.debug("queuing a job to build compiler_rt_lib", .{});
17701773 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });
17711774 } else if (options.output_mode != .Obj) {
1775 log.debug("queuing a job to build compiler_rt_obj", .{});
17721776 // If build-obj with -fcompiler-rt is requested, that is handled specially
17731777 // elsewhere. In this case we are making a static library, so we ask
17741778 // for a compiler-rt object to put in it.
......@@ -1930,6 +1934,7 @@ pub fn update(comp: *Compilation) !void {
19301934 return err;
19311935 };
19321936 if (is_hit) {
1937 log.debug("CacheMode.whole cache hit for {s}", .{comp.bin_file.options.root_name});
19331938 const digest = man.final();
19341939
19351940 // Communicate the output binary location to parent Compilations.
......@@ -1952,6 +1957,8 @@ pub fn update(comp: *Compilation) !void {
19521957 comp.bin_file.lock = man.toOwnedLock();
19531958 return;
19541959 }
1960 log.debug("CacheMode.whole cache miss for {s}", .{comp.bin_file.options.root_name});
1961
19551962 comp.whole_cache_manifest = &man;
19561963
19571964 // Initialize `bin_file.emit` with a temporary Directory so that compilation can
......@@ -2187,6 +2194,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
21872194
21882195 try addPackageTableToCacheHash(&man.hash, &arena_allocator, mod.main_pkg.table, &seen_table, .{ .files = man });
21892196 }
2197
2198 man.hash.add(mod.emit_h != null);
21902199 }
21912200
21922201 try man.addOptionalFile(comp.bin_file.options.linker_script);
src/main.zig+16-14
......@@ -2564,9 +2564,7 @@ fn buildOutputType(
25642564
25652565 switch (emit_bin) {
25662566 .no => break :blk .none,
2567 .yes_default_path => break :blk .{
2568 .print = comp.bin_file.options.emit.?.directory.path orelse ".",
2569 },
2567 .yes_default_path => break :blk .print_emit_bin_dir_path,
25702568 .yes => |full_path| break :blk .{ .update = full_path },
25712569 .yes_a_out => break :blk .{ .update = a_out_basename },
25722570 }
......@@ -2598,7 +2596,6 @@ fn buildOutputType(
25982596 comp,
25992597 gpa,
26002598 arena,
2601 emit_bin_loc,
26022599 test_exec_args.items,
26032600 self_exe_path,
26042601 arg_mode,
......@@ -2671,7 +2668,6 @@ fn buildOutputType(
26712668 comp,
26722669 gpa,
26732670 arena,
2674 emit_bin_loc,
26752671 test_exec_args.items,
26762672 self_exe_path,
26772673 arg_mode,
......@@ -2697,7 +2693,6 @@ fn buildOutputType(
26972693 comp,
26982694 gpa,
26992695 arena,
2700 emit_bin_loc,
27012696 test_exec_args.items,
27022697 self_exe_path,
27032698 arg_mode,
......@@ -2762,7 +2757,6 @@ fn runOrTest(
27622757 comp: *Compilation,
27632758 gpa: Allocator,
27642759 arena: Allocator,
2765 emit_bin_loc: ?Compilation.EmitLoc,
27662760 test_exec_args: []const ?[]const u8,
27672761 self_exe_path: []const u8,
27682762 arg_mode: ArgMode,
......@@ -2773,10 +2767,11 @@ fn runOrTest(
27732767 runtime_args_start: ?usize,
27742768 link_libc: bool,
27752769) !void {
2776 const exe_loc = emit_bin_loc orelse return;
2777 const exe_directory = exe_loc.directory orelse comp.bin_file.options.emit.?.directory;
2770 const exe_emit = comp.bin_file.options.emit orelse return;
2771 // A naive `directory.join` here will indeed get the correct path to the binary,
2772 // however, in the case of cwd, we actually want `./foo` so that the path can be executed.
27782773 const exe_path = try fs.path.join(arena, &[_][]const u8{
2779 exe_directory.path orelse ".", exe_loc.basename,
2774 exe_emit.directory.path orelse ".", exe_emit.sub_path,
27802775 });
27812776
27822777 var argv = std.ArrayList([]const u8).init(gpa);
......@@ -2880,7 +2875,7 @@ fn runOrTest(
28802875
28812876const AfterUpdateHook = union(enum) {
28822877 none,
2883 print: []const u8,
2878 print_emit_bin_dir_path,
28842879 update: []const u8,
28852880};
28862881
......@@ -2906,7 +2901,13 @@ fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void
29062901 return error.SemanticAnalyzeFail;
29072902 } else switch (hook) {
29082903 .none => {},
2909 .print => |bin_path| try io.getStdOut().writer().print("{s}\n", .{bin_path}),
2904 .print_emit_bin_dir_path => {
2905 const emit = comp.bin_file.options.emit.?;
2906 const full_path = try emit.directory.join(gpa, &.{emit.sub_path});
2907 defer gpa.free(full_path);
2908 const dir_path = fs.path.dirname(full_path).?;
2909 try io.getStdOut().writer().print("{s}\n", .{dir_path});
2910 },
29102911 .update => |full_path| {
29112912 const bin_sub_path = comp.bin_file.options.emit.?.sub_path;
29122913 const cwd = fs.cwd();
......@@ -3469,9 +3470,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
34693470 };
34703471 try comp.makeBinFileExecutable();
34713472
3472 child_argv.items[argv_index_exe] = try comp.bin_file.options.emit.?.directory.join(
3473 const emit = comp.bin_file.options.emit.?;
3474 child_argv.items[argv_index_exe] = try emit.directory.join(
34733475 arena,
3474 &[_][]const u8{exe_basename},
3476 &[_][]const u8{emit.sub_path},
34753477 );
34763478
34773479 break :argv child_argv.items;