diff options
| author | Loris Cro <kappaloris@gmail.com> | 2022-08-23 23:43:16 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-08-24 16:33:01 -0400 |
| commit | eb3f7d2f37cab1d3df7c4493b8239e802b83e521 (patch) | |
| tree | 75765ba947f0b4a1dbf7636c7b7b9b72627fac10 /src/Compilation.zig | |
| parent | 7a881435ed54b0cf59f48679c3912600b3bd0d58 (diff) | |
| download | zig-eb3f7d2f37cab1d3df7c4493b8239e802b83e521.tar.gz zig-eb3f7d2f37cab1d3df7c4493b8239e802b83e521.zip | |
compilation: avoid pointless caching
When the entire purpose of this compilation is to perform a single zig
cc operation we could "tail call" clang by doing an execve, and any use
of the caching system would actually be problematic since the user is
presumably doing their own caching by using dep file flags.
Fixes #12317
Diffstat (limited to 'src/Compilation.zig')
| -rw-r--r-- | src/Compilation.zig | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 1bc9719e1b..1b424a4001 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3753,22 +3753,64 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P }; const o_basename = try std.fmt.allocPrint(arena, "{s}{s}", .{ o_basename_noext, out_ext }); + try argv.appendSlice(&[_][]const u8{ + self_exe_path, + "clang", + c_object.src.src_path, + }); + try argv.appendSlice(c_object.src.extra_flags); + + const ext = classifyFileExt(c_object.src.src_path); + + // When all these flags are true, it means that the entire purpose of + // this compilation is to perform a single zig cc operation. This means + // that we could "tail call" clang by doing an execve, and any use of + // the caching system would actually be problematic since the user is + // presumably doing their own caching by using dep file flags. + if (comp.disable_c_depfile and comp.clang_passthrough_mode and std.process.can_execv and direct_o) { + try comp.addCCArgs(arena, &argv, ext, null); + + const out_obj_path = if (comp.bin_file.options.emit) |emit| + try emit.directory.join(arena, &.{emit.sub_path}) + else + "/dev/null"; + + try argv.ensureUnusedCapacity(5); + switch (comp.clang_preprocessor_mode) { + .no => argv.appendSliceAssumeCapacity(&[_][]const u8{ "-c", "-o", out_obj_path }), + .yes => argv.appendSliceAssumeCapacity(&[_][]const u8{ "-E", "-o", out_obj_path }), + .stdout => argv.appendAssumeCapacity("-E"), + } + + if (comp.emit_asm != null) { + argv.appendAssumeCapacity("-S"); + } else if (comp.emit_llvm_ir != null) { + argv.appendSliceAssumeCapacity(&[_][]const u8{ "-emit-llvm", "-S" }); + } else if (comp.emit_llvm_bc != null) { + argv.appendAssumeCapacity("-emit-llvm"); + } + + if (comp.verbose_cc) { + dump_argv(argv.items); + } + + const err = std.process.execv(arena, argv.items); + fatal("unable to execv clang: {s}", .{@errorName(err)}); + } + // We can't know the digest until we do the C compiler invocation, // so we need a temporary filename. const out_obj_path = try comp.tmpFilePath(arena, o_basename); var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); defer zig_cache_tmp_dir.close(); - try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang" }); - - const ext = classifyFileExt(c_object.src.src_path); const out_dep_path: ?[]const u8 = if (comp.disable_c_depfile or !ext.clangSupportsDepFile()) null else try std.fmt.allocPrint(arena, "{s}.d", .{out_obj_path}); try comp.addCCArgs(arena, &argv, ext, out_dep_path); - try argv.ensureUnusedCapacity(6 + c_object.src.extra_flags.len); + try argv.ensureUnusedCapacity(5); switch (comp.clang_preprocessor_mode) { .no => argv.appendSliceAssumeCapacity(&[_][]const u8{ "-c", "-o", out_obj_path }), .yes => argv.appendSliceAssumeCapacity(&[_][]const u8{ "-E", "-o", out_obj_path }), @@ -3783,8 +3825,6 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P argv.appendAssumeCapacity("-emit-llvm"); } } - argv.appendAssumeCapacity(c_object.src.src_path); - argv.appendSliceAssumeCapacity(c_object.src.extra_flags); if (comp.verbose_cc) { dump_argv(argv.items); |
