| author | |
| committer | |
| log | 67e31807df73ad2da992293fcdf1f6ea7ca67d2a |
| tree | 89182e7bc11d3b661ba3697faa5f21e96ae050c6 |
| parent | e3bed8d81dfd7198dd4c496f19a6791e27e41f26 |
* 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 | } |
| 1664 | 1664 | ||
| 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 { |
| 1767 | 1769 | ||
| 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 specially | 1776 | // 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 ask | 1777 | // 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(); |
| 1934 | 1939 | ||
| 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; |
| 1956 | 1963 | ||
| 1957 | // Initialize `bin_file.emit` with a temporary Directory so that compilation can | 1964 | // 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 |
| 2187 | 2194 | ||
| 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 | } |
| 2191 | 2200 | ||
| 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( |
| 2564 | 2564 | ||
| 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 | }); |
| 2781 | 2776 | ||
| 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( |
| 2880 | 2875 | ||
| 2881 | const AfterUpdateHook = union(enum) { | 2876 | const 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 | }; |
| 2886 | 2881 | ||
| ... | @@ -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(); |
| 3471 | 3472 | ||
| 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 | ); |
| 3476 | 3478 | ||
| 3477 | break :argv child_argv.items; | 3479 | break :argv child_argv.items; |