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 {...@@ -1662,7 +1662,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1662 comp.c_object_table.putAssumeCapacityNoClobber(c_object, {});1662 comp.c_object_table.putAssumeCapacityNoClobber(c_object, {});
1663 }1663 }
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) {
1666 // If we need to build glibc for the target, add work items for it.1668 // If we need to build glibc for the target, add work items for it.
1667 // We go through the work queue so that building can be done in parallel.1669 // We go through the work queue so that building can be done in parallel.
1668 if (comp.wantBuildGLibCFromSource()) {1670 if (comp.wantBuildGLibCFromSource()) {
...@@ -1767,8 +1769,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1767,8 +1769,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
17671769
1768 if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {1770 if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {
1769 if (is_exe_or_dyn_lib) {1771 if (is_exe_or_dyn_lib) {
1772 log.debug("queuing a job to build compiler_rt_lib", .{});
1770 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });1773 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });
1771 } else if (options.output_mode != .Obj) {1774 } else if (options.output_mode != .Obj) {
1775 log.debug("queuing a job to build compiler_rt_obj", .{});
1772 // If build-obj with -fcompiler-rt is requested, that is handled specially1776 // If build-obj with -fcompiler-rt is requested, that is handled specially
1773 // elsewhere. In this case we are making a static library, so we ask1777 // elsewhere. In this case we are making a static library, so we ask
1774 // for a compiler-rt object to put in it.1778 // for a compiler-rt object to put in it.
...@@ -1930,6 +1934,7 @@ pub fn update(comp: *Compilation) !void {...@@ -1930,6 +1934,7 @@ pub fn update(comp: *Compilation) !void {
1930 return err;1934 return err;
1931 };1935 };
1932 if (is_hit) {1936 if (is_hit) {
1937 log.debug("CacheMode.whole cache hit for {s}", .{comp.bin_file.options.root_name});
1933 const digest = man.final();1938 const digest = man.final();
19341939
1935 // Communicate the output binary location to parent Compilations.1940 // Communicate the output binary location to parent Compilations.
...@@ -1952,6 +1957,8 @@ pub fn update(comp: *Compilation) !void {...@@ -1952,6 +1957,8 @@ pub fn update(comp: *Compilation) !void {
1952 comp.bin_file.lock = man.toOwnedLock();1957 comp.bin_file.lock = man.toOwnedLock();
1953 return;1958 return;
1954 }1959 }
1960 log.debug("CacheMode.whole cache miss for {s}", .{comp.bin_file.options.root_name});
1961
1955 comp.whole_cache_manifest = &man;1962 comp.whole_cache_manifest = &man;
19561963
1957 // Initialize `bin_file.emit` with a temporary Directory so that compilation can1964 // Initialize `bin_file.emit` with a temporary Directory so that compilation can
...@@ -2187,6 +2194,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2187,6 +2194,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
21872194
2188 try addPackageTableToCacheHash(&man.hash, &arena_allocator, mod.main_pkg.table, &seen_table, .{ .files = man });2195 try addPackageTableToCacheHash(&man.hash, &arena_allocator, mod.main_pkg.table, &seen_table, .{ .files = man });
2189 }2196 }
2197
2198 man.hash.add(mod.emit_h != null);
2190 }2199 }
21912200
2192 try man.addOptionalFile(comp.bin_file.options.linker_script);2201 try man.addOptionalFile(comp.bin_file.options.linker_script);
src/main.zig+16-14
...@@ -2564,9 +2564,7 @@ fn buildOutputType(...@@ -2564,9 +2564,7 @@ fn buildOutputType(
25642564
2565 switch (emit_bin) {2565 switch (emit_bin) {
2566 .no => break :blk .none,2566 .no => break :blk .none,
2567 .yes_default_path => break :blk .{2567 .yes_default_path => break :blk .print_emit_bin_dir_path,
2568 .print = comp.bin_file.options.emit.?.directory.path orelse ".",
2569 },
2570 .yes => |full_path| break :blk .{ .update = full_path },2568 .yes => |full_path| break :blk .{ .update = full_path },
2571 .yes_a_out => break :blk .{ .update = a_out_basename },2569 .yes_a_out => break :blk .{ .update = a_out_basename },
2572 }2570 }
...@@ -2598,7 +2596,6 @@ fn buildOutputType(...@@ -2598,7 +2596,6 @@ fn buildOutputType(
2598 comp,2596 comp,
2599 gpa,2597 gpa,
2600 arena,2598 arena,
2601 emit_bin_loc,
2602 test_exec_args.items,2599 test_exec_args.items,
2603 self_exe_path,2600 self_exe_path,
2604 arg_mode,2601 arg_mode,
...@@ -2671,7 +2668,6 @@ fn buildOutputType(...@@ -2671,7 +2668,6 @@ fn buildOutputType(
2671 comp,2668 comp,
2672 gpa,2669 gpa,
2673 arena,2670 arena,
2674 emit_bin_loc,
2675 test_exec_args.items,2671 test_exec_args.items,
2676 self_exe_path,2672 self_exe_path,
2677 arg_mode,2673 arg_mode,
...@@ -2697,7 +2693,6 @@ fn buildOutputType(...@@ -2697,7 +2693,6 @@ fn buildOutputType(
2697 comp,2693 comp,
2698 gpa,2694 gpa,
2699 arena,2695 arena,
2700 emit_bin_loc,
2701 test_exec_args.items,2696 test_exec_args.items,
2702 self_exe_path,2697 self_exe_path,
2703 arg_mode,2698 arg_mode,
...@@ -2762,7 +2757,6 @@ fn runOrTest(...@@ -2762,7 +2757,6 @@ fn runOrTest(
2762 comp: *Compilation,2757 comp: *Compilation,
2763 gpa: Allocator,2758 gpa: Allocator,
2764 arena: Allocator,2759 arena: Allocator,
2765 emit_bin_loc: ?Compilation.EmitLoc,
2766 test_exec_args: []const ?[]const u8,2760 test_exec_args: []const ?[]const u8,
2767 self_exe_path: []const u8,2761 self_exe_path: []const u8,
2768 arg_mode: ArgMode,2762 arg_mode: ArgMode,
...@@ -2773,10 +2767,11 @@ fn runOrTest(...@@ -2773,10 +2767,11 @@ fn runOrTest(
2773 runtime_args_start: ?usize,2767 runtime_args_start: ?usize,
2774 link_libc: bool,2768 link_libc: bool,
2775) !void {2769) !void {
2776 const exe_loc = emit_bin_loc orelse return;2770 const exe_emit = comp.bin_file.options.emit orelse return;
2777 const exe_directory = exe_loc.directory orelse comp.bin_file.options.emit.?.directory;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.
2778 const exe_path = try fs.path.join(arena, &[_][]const u8{2773 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,
2780 });2775 });
27812776
2782 var argv = std.ArrayList([]const u8).init(gpa);2777 var argv = std.ArrayList([]const u8).init(gpa);
...@@ -2880,7 +2875,7 @@ fn runOrTest(...@@ -2880,7 +2875,7 @@ fn runOrTest(
28802875
2881const AfterUpdateHook = union(enum) {2876const AfterUpdateHook = union(enum) {
2882 none,2877 none,
2883 print: []const u8,2878 print_emit_bin_dir_path,
2884 update: []const u8,2879 update: []const u8,
2885};2880};
28862881
...@@ -2906,7 +2901,13 @@ fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void...@@ -2906,7 +2901,13 @@ fn updateModule(gpa: Allocator, comp: *Compilation, hook: AfterUpdateHook) !void
2906 return error.SemanticAnalyzeFail;2901 return error.SemanticAnalyzeFail;
2907 } else switch (hook) {2902 } else switch (hook) {
2908 .none => {},2903 .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 },
2910 .update => |full_path| {2911 .update => |full_path| {
2911 const bin_sub_path = comp.bin_file.options.emit.?.sub_path;2912 const bin_sub_path = comp.bin_file.options.emit.?.sub_path;
2912 const cwd = fs.cwd();2913 const cwd = fs.cwd();
...@@ -3469,9 +3470,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi...@@ -3469,9 +3470,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
3469 };3470 };
3470 try comp.makeBinFileExecutable();3471 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(
3473 arena,3475 arena,
3474 &[_][]const u8{exe_basename},3476 &[_][]const u8{emit.sub_path},
3475 );3477 );
34763478
3477 break :argv child_argv.items;3479 break :argv child_argv.items;