diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2025-06-06 20:16:26 +0100 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2025-06-12 13:55:40 +0100 |
| commit | b5f73f8a7b90c5144b79692f142b5d91025dbe01 (patch) | |
| tree | 3228d7f1afc8e7c48c2f686ef9643de8688f8370 /src/libs | |
| parent | 808c15dd397f995d9bdf43664ee5644b39c9c863 (diff) | |
| download | zig-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.zig | 7 | ||||
| -rw-r--r-- | src/libs/glibc.zig | 7 | ||||
| -rw-r--r-- | src/libs/libcxx.zig | 28 | ||||
| -rw-r--r-- | src/libs/libtsan.zig | 8 | ||||
| -rw-r--r-- | src/libs/libunwind.zig | 15 | ||||
| -rw-r--r-- | src/libs/musl.zig | 3 | ||||
| -rw-r--r-- | src/libs/netbsd.zig | 7 |
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, |
