authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-12-30 22:04:18-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-02 13:16:17-07:00
log55243cfb31e40f09503fbc5b4bb63e7a5d3d87eb
treeacd8fb3d987e7ee00e9e0130905df3cb05a044ab
parent013c286e432eacbd55a9f842cd277be11f72cc49

stage2: fix implibs

Broken by the introduction of `CacheMode.whole`, they are now working again by using the same mechanism as emitted binary files.

1 files changed, 43 insertions(+), 14 deletions(-)

src/Compilation.zig+43-14
......@@ -103,6 +103,8 @@ self_exe_path: ?[]const u8,
103103/// of exactly the correct size for "o/[digest]/[basename]".
104104/// The basename is of the outputted binary file in case we don't know the directory yet.
105105whole_bin_sub_path: ?[]u8,
106/// Same as `whole_bin_sub_path` but for implibs.
107whole_implib_sub_path: ?[]u8,
106108zig_lib_directory: Directory,
107109local_cache_directory: Directory,
108110global_cache_directory: Directory,
......@@ -1477,6 +1479,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
14771479 };
14781480 }
14791481
1482 // This is here for the same reason as in `bin_file_emit` above.
1483 switch (cache_mode) {
1484 .whole => break :blk null,
1485 .incremental => {},
1486 }
1487
14801488 // Use the same directory as the bin. The CLI already emits an
14811489 // error if -fno-emit-bin is combined with -femit-implib.
14821490 break :blk link.Emit{
......@@ -1491,14 +1499,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
14911499 // for `CacheMode.whole`.
14921500 // This memory will be overwritten with the real digest in update() but
14931501 // the basename will be preserved.
1494 const whole_bin_sub_path: ?[]u8 = if (options.emit_bin) |x|
1495 if (x.directory == null)
1496 try std.fmt.allocPrint(arena, "o" ++ std.fs.path.sep_str ++
1497 ("x" ** Cache.hex_digest_len) ++ std.fs.path.sep_str ++ "{s}", .{x.basename})
1498 else
1499 null
1500 else
1501 null;
1502 const whole_bin_sub_path: ?[]u8 = try prepareWholeEmitSubPath(arena, options.emit_bin);
1503 // Same thing but for implibs.
1504 const whole_implib_sub_path: ?[]u8 = try prepareWholeEmitSubPath(arena, options.emit_implib);
15021505
15031506 var system_libs: std.StringArrayHashMapUnmanaged(SystemLib) = .{};
15041507 errdefer system_libs.deinit(gpa);
......@@ -1606,6 +1609,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
16061609 .global_cache_directory = options.global_cache_directory,
16071610 .bin_file = bin_file,
16081611 .whole_bin_sub_path = whole_bin_sub_path,
1612 .whole_implib_sub_path = whole_implib_sub_path,
16091613 .emit_asm = options.emit_asm,
16101614 .emit_llvm_ir = options.emit_llvm_ir,
16111615 .emit_llvm_bc = options.emit_llvm_bc,
......@@ -1988,6 +1992,12 @@ pub fn update(comp: *Compilation) !void {
19881992 .sub_path = std.fs.path.basename(sub_path),
19891993 };
19901994 }
1995 if (comp.whole_implib_sub_path) |sub_path| {
1996 options.implib_emit = .{
1997 .directory = tmp_artifact_directory.?,
1998 .sub_path = std.fs.path.basename(sub_path),
1999 };
2000 }
19912001 comp.bin_file.destroy();
19922002 comp.bin_file = try link.File.openPath(comp.gpa, options);
19932003 }
......@@ -2149,14 +2159,33 @@ pub fn update(comp: *Compilation) !void {
21492159
21502160/// Communicate the output binary location to parent Compilations.
21512161fn wholeCacheModeSetBinFilePath(comp: *Compilation, digest: *const [Cache.hex_digest_len]u8) void {
2152 const sub_path = comp.whole_bin_sub_path orelse return;
21532162 const digest_start = 2; // "o/[digest]/[basename]"
2154 mem.copy(u8, sub_path[digest_start..], digest);
21552163
2156 comp.bin_file.options.emit = .{
2157 .directory = comp.local_cache_directory,
2158 .sub_path = sub_path,
2159 };
2164 if (comp.whole_bin_sub_path) |sub_path| {
2165 mem.copy(u8, sub_path[digest_start..], digest);
2166
2167 comp.bin_file.options.emit = .{
2168 .directory = comp.local_cache_directory,
2169 .sub_path = sub_path,
2170 };
2171 }
2172
2173 if (comp.whole_implib_sub_path) |sub_path| {
2174 mem.copy(u8, sub_path[digest_start..], digest);
2175
2176 comp.bin_file.options.implib_emit = .{
2177 .directory = comp.local_cache_directory,
2178 .sub_path = sub_path,
2179 };
2180 }
2181}
2182
2183fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemory}!?[]u8 {
2184 const emit = opt_emit orelse return null;
2185 if (emit.directory != null) return null;
2186 const s = std.fs.path.sep_str;
2187 const format = "o" ++ s ++ ("x" ** Cache.hex_digest_len) ++ s ++ "{s}";
2188 return try std.fmt.allocPrint(arena, format, .{emit.basename});
21602189}
21612190
21622191/// This is only observed at compile-time and used to emit a compile error