diff --git a/src/Compilation.zig b/src/Compilation.zig index e340cb57f8..71ca226cc2 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1549,7 +1549,8 @@ pub const SystemLib = link.SystemLib; pub const CacheMode = enum { /// The results of this compilation are not cached. The compilation is always performed, and the /// results are emitted directly to their output locations. Temporary files will be placed in a - /// temporary directory in the cache, but deleted after the compilation is done. + /// temporary directory in the cache, but deleted after the compilation is done, unless they are + /// needed for the output binary to work correctly. /// /// This mode is typically used for direct CLI invocations like `zig build-exe`, because such /// processes are typically low-level usages which would not make efficient use of the cache. @@ -1593,8 +1594,8 @@ const CacheUse = union(CacheMode) { const None = struct { /// User-requested artifacts are written directly to their output path in this cache mode. /// However, if we need to emit any temporary files, they are placed in this directory. - /// We will recursively delete this directory at the end of this update. This field is - /// non-`null` only inside `update`. + /// We will recursively delete this directory at the end of this update if possible. This + /// field is non-`null` only inside `update`. tmp_artifact_directory: ?Cache.Directory, }; @@ -2807,6 +2808,17 @@ fn cleanupAfterUpdate(comp: *Compilation, tmp_dir_rand_int: u64) void { // temporary directories; it doesn't have a real cache directory anyway. return; } + // Usually, we want to delete the temporary directory. However, if we are emitting + // an unstripped Mach-O binary with the LLVM backend, then the temporary directory + // contains the ZCU object file emitted by LLVM, which contains debug symbols not + // replicated in the output binary (the output instead contains a reference to that + // file which debug tooling can look through). So, in that particular case, we need + // to keep this directory around so that the output binary can be debugged. + if (comp.bin_file != null and comp.getTarget().ofmt == .macho and comp.config.debug_format != .strip) { + // We are emitting an unstripped Mach-O binary with the LLVM backend: the ZCU + // object file must remain on-disk for its debug info. + return; + } const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(tmp_dir_rand_int); comp.dirs.local_cache.handle.deleteTree(tmp_dir_sub_path) catch |err| { log.warn("failed to delete temporary directory '{s}{c}{s}': {s}", .{