aboutsummaryrefslogtreecommitdiff
path: root/src/libs
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2025-06-06 20:16:26 +0100
committermlugg <mlugg@mlugg.co.uk>2025-06-12 13:55:40 +0100
commitb5f73f8a7b90c5144b79692f142b5d91025dbe01 (patch)
tree3228d7f1afc8e7c48c2f686ef9643de8688f8370 /src/libs
parent808c15dd397f995d9bdf43664ee5644b39c9c863 (diff)
downloadzig-b5f73f8a7b90c5144b79692f142b5d91025dbe01.tar.gz
zig-b5f73f8a7b90c5144b79692f142b5d91025dbe01.zip
compiler: rework emit paths and cache modes
Previously, various doc comments heavily disagreed with the implementation on both what lives where on the filesystem at what time, and how that was represented in code. Notably, the combination of emit paths outside the cache and `disable_lld_caching` created a kind of ad-hoc "cache disable" mechanism -- which didn't actually *work* very well, 'most everything still ended up in this cache. There was also a long-standing issue where building using the LLVM backend would put a random object file in your cwd. This commit reworks how emit paths are specified in `Compilation.CreateOptions`, how they are represented internally, and how the cache usage is specified. There are now 3 options for `Compilation.CacheMode`: * `.none`: do not use the cache. The paths we have to emit to are relative to the compiler cwd (they're either user-specified, or defaults inferred from the root name). If we create any temporary files (e.g. the ZCU object when using the LLVM backend) they are emitted to a directory in `local_cache/tmp/`, which is deleted once the update finishes. * `.whole`: cache the compilation based on all inputs, including file contents. All emit paths are computed by the compiler (and will be stored as relative to the local cache directory); it is a CLI error to specify an explicit emit path. Artifacts (including temporary files) are written to a directory under `local_cache/tmp/`, which is later renamed to an appropriate `local_cache/o/`. The caller (who is using `--listen`; e.g. the build system) learns the name of this directory, and can get the artifacts from it. * `.incremental`: similar to `.whole`, but Zig source file contents, and anything else which incremental compilation can handle changes for, is not included in the cache manifest. We don't need to do the dance where the output directory is initially in `tmp/`, because our digest is computed entirely from CLI inputs. To be clear, the difference between `CacheMode.whole` and `CacheMode.incremental` is unchanged. `CacheMode.none` is new (previously it was sort of poorly imitated with `CacheMode.whole`). The defined behavior for temporary/intermediate files is new. `.none` is used for direct CLI invocations like `zig build-exe foo.zig`. The other cache modes are reserved for `--listen`, and the cache mode in use is currently just based on the presence of the `-fincremental` flag. There are two cases in which `CacheMode.whole` is used despite there being no `--listen` flag: `zig test` and `zig run`. Unless an explicit `-femit-bin=xxx` argument is passed on the CLI, these subcommands will use `CacheMode.whole`, so that they can put the output somewhere without polluting the cwd (plus, caching is potentially more useful for direct usage of these subcommands). Users of `--listen` (such as the build system) can now use `std.zig.EmitArtifact.cacheName` to find out what an output will be named. This avoids having to synchronize logic between the compiler and all users of `--listen`.
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/freebsd.zig7
-rw-r--r--src/libs/glibc.zig7
-rw-r--r--src/libs/libcxx.zig28
-rw-r--r--src/libs/libtsan.zig8
-rw-r--r--src/libs/libunwind.zig15
-rw-r--r--src/libs/musl.zig3
-rw-r--r--src/libs/netbsd.zig7
7 files changed, 9 insertions, 66 deletions
diff --git a/src/libs/freebsd.zig b/src/libs/freebsd.zig
index d90ba974fc..0d14b6fb47 100644
--- a/src/libs/freebsd.zig
+++ b/src/libs/freebsd.zig
@@ -1019,10 +1019,6 @@ fn buildSharedLib(
defer tracy.end();
const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });
- const emit_bin = Compilation.EmitLoc{
- .directory = bin_directory,
- .basename = basename,
- };
const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };
const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);
const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;
@@ -1082,8 +1078,7 @@ fn buildSharedLib(
.root_mod = root_mod,
.root_name = lib.name,
.libc_installation = comp.libc_installation,
- .emit_bin = emit_bin,
- .emit_h = null,
+ .emit_bin = .yes_cache,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.verbose_link,
.verbose_air = comp.verbose_air,
diff --git a/src/libs/glibc.zig b/src/libs/glibc.zig
index ed5eae377f..cb8dd4b460 100644
--- a/src/libs/glibc.zig
+++ b/src/libs/glibc.zig
@@ -1185,10 +1185,6 @@ fn buildSharedLib(
defer tracy.end();
const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });
- const emit_bin = Compilation.EmitLoc{
- .directory = bin_directory,
- .basename = basename,
- };
const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };
const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);
const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;
@@ -1248,8 +1244,7 @@ fn buildSharedLib(
.root_mod = root_mod,
.root_name = lib.name,
.libc_installation = comp.libc_installation,
- .emit_bin = emit_bin,
- .emit_h = null,
+ .emit_bin = .yes_cache,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.verbose_link,
.verbose_air = comp.verbose_air,
diff --git a/src/libs/libcxx.zig b/src/libs/libcxx.zig
index eb9f5df855..0009bfe120 100644
--- a/src/libs/libcxx.zig
+++ b/src/libs/libcxx.zig
@@ -122,17 +122,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
const output_mode = .Lib;
const link_mode = .static;
const target = comp.root_mod.resolved_target.result;
- const basename = try std.zig.binNameAlloc(arena, .{
- .root_name = root_name,
- .target = target,
- .output_mode = output_mode,
- .link_mode = link_mode,
- });
-
- const emit_bin = Compilation.EmitLoc{
- .directory = null, // Put it in the cache directory.
- .basename = basename,
- };
const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" });
const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" });
@@ -271,8 +260,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
.root_name = root_name,
.thread_pool = comp.thread_pool,
.libc_installation = comp.libc_installation,
- .emit_bin = emit_bin,
- .emit_h = null,
+ .emit_bin = .yes_cache,
.c_source_files = c_source_files.items,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.verbose_link,
@@ -327,17 +315,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
const output_mode = .Lib;
const link_mode = .static;
const target = comp.root_mod.resolved_target.result;
- const basename = try std.zig.binNameAlloc(arena, .{
- .root_name = root_name,
- .target = target,
- .output_mode = output_mode,
- .link_mode = link_mode,
- });
-
- const emit_bin = Compilation.EmitLoc{
- .directory = null, // Put it in the cache directory.
- .basename = basename,
- };
const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" });
const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" });
@@ -467,8 +444,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.root_name = root_name,
.thread_pool = comp.thread_pool,
.libc_installation = comp.libc_installation,
- .emit_bin = emit_bin,
- .emit_h = null,
+ .emit_bin = .yes_cache,
.c_source_files = c_source_files.items,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.verbose_link,
diff --git a/src/libs/libtsan.zig b/src/libs/libtsan.zig
index 0c59d85bc5..f2cd6831f7 100644
--- a/src/libs/libtsan.zig
+++ b/src/libs/libtsan.zig
@@ -45,11 +45,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
.link_mode = link_mode,
});
- const emit_bin = Compilation.EmitLoc{
- .directory = null, // Put it in the cache directory.
- .basename = basename,
- };
-
const optimize_mode = comp.compilerRtOptMode();
const strip = comp.compilerRtStrip();
const unwind_tables: std.builtin.UnwindTables =
@@ -287,8 +282,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo
.root_mod = root_mod,
.root_name = root_name,
.libc_installation = comp.libc_installation,
- .emit_bin = emit_bin,
- .emit_h = null,
+ .emit_bin = .yes_cache,
.c_source_files = c_source_files.items,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.verbose_link,
diff --git a/src/libs/libunwind.zig b/src/libs/libunwind.zig
index ccea649c17..711d63ebbc 100644
--- a/src/libs/libunwind.zig
+++ b/src/libs/libunwind.zig
@@ -31,7 +31,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
const unwind_tables: std.builtin.UnwindTables =
if (target.cpu.arch == .x86 and target.os.tag == .windows) .none else .@"async";
const config = Compilation.Config.resolve(.{
- .output_mode = .Lib,
+ .output_mode = output_mode,
.resolved_target = comp.root_mod.resolved_target,
.is_test = false,
.have_zcu = false,
@@ -85,17 +85,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
};
const root_name = "unwind";
- const link_mode = .static;
- const basename = try std.zig.binNameAlloc(arena, .{
- .root_name = root_name,
- .target = target,
- .output_mode = output_mode,
- .link_mode = link_mode,
- });
- const emit_bin = Compilation.EmitLoc{
- .directory = null, // Put it in the cache directory.
- .basename = basename,
- };
var c_source_files: [unwind_src_list.len]Compilation.CSourceFile = undefined;
for (unwind_src_list, 0..) |unwind_src, i| {
var cflags = std.ArrayList([]const u8).init(arena);
@@ -160,7 +149,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
.main_mod = null,
.thread_pool = comp.thread_pool,
.libc_installation = comp.libc_installation,
- .emit_bin = emit_bin,
+ .emit_bin = .yes_cache,
.function_sections = comp.function_sections,
.c_source_files = &c_source_files,
.verbose_cc = comp.verbose_cc,
diff --git a/src/libs/musl.zig b/src/libs/musl.zig
index 21aeee98b5..7c4e71c974 100644
--- a/src/libs/musl.zig
+++ b/src/libs/musl.zig
@@ -252,8 +252,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro
.thread_pool = comp.thread_pool,
.root_name = "c",
.libc_installation = comp.libc_installation,
- .emit_bin = .{ .directory = null, .basename = "libc.so" },
- .emit_h = null,
+ .emit_bin = .yes_cache,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.verbose_link,
.verbose_air = comp.verbose_air,
diff --git a/src/libs/netbsd.zig b/src/libs/netbsd.zig
index 7121c308f5..f19c528d5d 100644
--- a/src/libs/netbsd.zig
+++ b/src/libs/netbsd.zig
@@ -684,10 +684,6 @@ fn buildSharedLib(
defer tracy.end();
const basename = try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ lib.name, lib.sover });
- const emit_bin = Compilation.EmitLoc{
- .directory = bin_directory,
- .basename = basename,
- };
const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };
const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);
const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;
@@ -746,8 +742,7 @@ fn buildSharedLib(
.root_mod = root_mod,
.root_name = lib.name,
.libc_installation = comp.libc_installation,
- .emit_bin = emit_bin,
- .emit_h = null,
+ .emit_bin = .yes_cache,
.verbose_cc = comp.verbose_cc,
.verbose_link = comp.verbose_link,
.verbose_air = comp.verbose_air,