authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-22 14:06:57-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-09-22 14:08:08-07:00
logdacd36ca9b193444e9e2ca3f132fccf3e08fb4f9
tree6dd4760054aeb789c1179dfd635d7b54acd74693
parentbf9a16a037e88d56bec3740698e3fcd34e9ad543

stage2: implement using the global cache dir


8 files changed, 93 insertions(+), 54 deletions(-)

BRANCH_TODO+5-8
...@@ -14,26 +14,23 @@...@@ -14,26 +14,23 @@
14 * -fno-emit-asm (default) do not output .s (assembly code)\n"14 * -fno-emit-asm (default) do not output .s (assembly code)\n"
15 * -femit-llvm-ir produce a .ll file with LLVM IR\n"15 * -femit-llvm-ir produce a .ll file with LLVM IR\n"
16 * -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"16 * -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"
17 * --cache-dir [path] override the local cache directory
18 * --global-cache-dir [path] override the global cache directory
19 * implement proper parsing of LLD stderr/stdout and exposing compile errors
20 * implement proper parsing of clang stderr/stdout and exposing compile errors
21 * support rpaths in ELF linker code17 * support rpaths in ELF linker code
22 * add CLI support for a way to pass extra flags to c source files18 * add CLI support for a way to pass extra flags to c source files
23 * musl19 * musl
24 * mingw-w6420 * mingw-w64
25 * use global zig-cache dir for crt files
26 * use global zig-cache dir for `zig run` executables but not `zig test`
27 * MachO LLD linking21 * MachO LLD linking
28 * COFF LLD linking22 * COFF LLD linking
29 * WASM LLD linking23 * WASM LLD linking
30 * support cross compiling stage2 with `zig build`
31 * --main-pkg-path24 * --main-pkg-path
32 * audit the CLI options for stage225 * audit the CLI options for stage2
33 * restore error messages for stage2_add_link_lib
34 * audit the base cache hash26 * audit the base cache hash
27 * implement proper parsing of LLD stderr/stdout and exposing compile errors
28 * implement proper parsing of clang stderr/stdout and exposing compile errors
35 * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.29 * On operating systems that support it, do an execve for `zig test` and `zig run` rather than child process.
30 * restore error messages for stage2_add_link_lib
31 * update zig build to use new CLI
3632
33 * support cross compiling stage2 with `zig build`
37 * implement proper compile errors for failing to build glibc crt files and shared libs34 * implement proper compile errors for failing to build glibc crt files and shared libs
38 * implement -fno-emit-bin35 * implement -fno-emit-bin
39 * improve the stage2 tests to support testing with LLVM extensions enabled36 * improve the stage2 tests to support testing with LLVM extensions enabled
src/Compilation.zig+17-14
...@@ -64,7 +64,8 @@ cache_parent: *Cache,...@@ -64,7 +64,8 @@ cache_parent: *Cache,
64/// Path to own executable for invoking `zig clang`.64/// Path to own executable for invoking `zig clang`.
65self_exe_path: ?[]const u8,65self_exe_path: ?[]const u8,
66zig_lib_directory: Directory,66zig_lib_directory: Directory,
67zig_cache_directory: Directory,67local_cache_directory: Directory,
68global_cache_directory: Directory,
68libc_include_dir_list: []const []const u8,69libc_include_dir_list: []const []const u8,
69rand: *std.rand.Random,70rand: *std.rand.Random,
7071
...@@ -267,7 +268,8 @@ pub const EmitLoc = struct {...@@ -267,7 +268,8 @@ pub const EmitLoc = struct {
267268
268pub const InitOptions = struct {269pub const InitOptions = struct {
269 zig_lib_directory: Directory,270 zig_lib_directory: Directory,
270 zig_cache_directory: Directory,271 local_cache_directory: Directory,
272 global_cache_directory: Directory,
271 target: Target,273 target: Target,
272 root_name: []const u8,274 root_name: []const u8,
273 root_pkg: ?*Package,275 root_pkg: ?*Package,
...@@ -523,7 +525,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -523,7 +525,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
523 const cache = try arena.create(Cache);525 const cache = try arena.create(Cache);
524 cache.* = .{526 cache.* = .{
525 .gpa = gpa,527 .gpa = gpa,
526 .manifest_dir = try options.zig_cache_directory.handle.makeOpenPath("h", .{}),528 .manifest_dir = try options.local_cache_directory.handle.makeOpenPath("h", .{}),
527 };529 };
528 errdefer cache.manifest_dir.close();530 errdefer cache.manifest_dir.close();
529531
...@@ -569,11 +571,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -569,11 +571,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
569571
570 const digest = hash.final();572 const digest = hash.final();
571 const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });573 const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
572 var artifact_dir = try options.zig_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});574 var artifact_dir = try options.local_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});
573 errdefer artifact_dir.close();575 errdefer artifact_dir.close();
574 const zig_cache_artifact_directory: Directory = .{576 const zig_cache_artifact_directory: Directory = .{
575 .handle = artifact_dir,577 .handle = artifact_dir,
576 .path = if (options.zig_cache_directory.path) |p|578 .path = if (options.local_cache_directory.path) |p|
577 try std.fs.path.join(arena, &[_][]const u8{ p, artifact_sub_dir })579 try std.fs.path.join(arena, &[_][]const u8{ p, artifact_sub_dir })
578 else580 else
579 artifact_sub_dir,581 artifact_sub_dir,
...@@ -647,11 +649,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -647,11 +649,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
647649
648 const digest = hash.final();650 const digest = hash.final();
649 const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });651 const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
650 var artifact_dir = try options.zig_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});652 var artifact_dir = try options.local_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});
651 owned_link_dir = artifact_dir;653 owned_link_dir = artifact_dir;
652 const link_artifact_directory: Directory = .{654 const link_artifact_directory: Directory = .{
653 .handle = artifact_dir,655 .handle = artifact_dir,
654 .path = try options.zig_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}),656 .path = try options.local_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}),
655 };657 };
656 break :blk link_artifact_directory;658 break :blk link_artifact_directory;
657 };659 };
...@@ -715,7 +717,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -715,7 +717,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
715 .gpa = gpa,717 .gpa = gpa,
716 .arena_state = arena_allocator.state,718 .arena_state = arena_allocator.state,
717 .zig_lib_directory = options.zig_lib_directory,719 .zig_lib_directory = options.zig_lib_directory,
718 .zig_cache_directory = options.zig_cache_directory,720 .local_cache_directory = options.local_cache_directory,
721 .global_cache_directory = options.global_cache_directory,
719 .bin_file = bin_file,722 .bin_file = bin_file,
720 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),723 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
721 .keep_source_files_loaded = options.keep_source_files_loaded,724 .keep_source_files_loaded = options.keep_source_files_loaded,
...@@ -1230,7 +1233,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {...@@ -1230,7 +1233,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
12301233
1231 // We can't know the digest until we do the C compiler invocation, so we need a temporary filename.1234 // We can't know the digest until we do the C compiler invocation, so we need a temporary filename.
1232 const out_obj_path = try comp.tmpFilePath(arena, o_basename);1235 const out_obj_path = try comp.tmpFilePath(arena, o_basename);
1233 var zig_cache_tmp_dir = try comp.zig_cache_directory.handle.makeOpenPath("tmp", .{});1236 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{});
1234 defer zig_cache_tmp_dir.close();1237 defer zig_cache_tmp_dir.close();
12351238
1236 try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang", "-c" });1239 try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang", "-c" });
...@@ -1319,7 +1322,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {...@@ -1319,7 +1322,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
1319 // Rename into place.1322 // Rename into place.
1320 const digest = ch.final();1323 const digest = ch.final();
1321 const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });1324 const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
1322 var o_dir = try comp.zig_cache_directory.handle.makeOpenPath(o_sub_path, .{});1325 var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{});
1323 defer o_dir.close();1326 defer o_dir.close();
1324 // TODO https://github.com/ziglang/zig/issues/63441327 // TODO https://github.com/ziglang/zig/issues/6344
1325 const tmp_basename = std.fs.path.basename(out_obj_path);1328 const tmp_basename = std.fs.path.basename(out_obj_path);
...@@ -1331,7 +1334,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {...@@ -1331,7 +1334,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
1331 break :blk digest;1334 break :blk digest;
1332 };1335 };
13331336
1334 const components = if (comp.zig_cache_directory.path) |p|1337 const components = if (comp.local_cache_directory.path) |p|
1335 &[_][]const u8{ p, "o", &digest, o_basename }1338 &[_][]const u8{ p, "o", &digest, o_basename }
1336 else1339 else
1337 &[_][]const u8{ "o", &digest, o_basename };1340 &[_][]const u8{ "o", &digest, o_basename };
...@@ -1347,7 +1350,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {...@@ -1347,7 +1350,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
1347fn tmpFilePath(comp: *Compilation, arena: *Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 {1350fn tmpFilePath(comp: *Compilation, arena: *Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 {
1348 const s = std.fs.path.sep_str;1351 const s = std.fs.path.sep_str;
1349 const rand_int = comp.rand.int(u64);1352 const rand_int = comp.rand.int(u64);
1350 if (comp.zig_cache_directory.path) |p| {1353 if (comp.local_cache_directory.path) |p| {
1351 return std.fmt.allocPrint(arena, "{}" ++ s ++ "tmp" ++ s ++ "{x}-{s}", .{ p, rand_int, suffix });1354 return std.fmt.allocPrint(arena, "{}" ++ s ++ "tmp" ++ s ++ "{x}-{s}", .{ p, rand_int, suffix });
1352 } else {1355 } else {
1353 return std.fmt.allocPrint(arena, "tmp" ++ s ++ "{x}-{s}", .{ rand_int, suffix });1356 return std.fmt.allocPrint(arena, "tmp" ++ s ++ "{x}-{s}", .{ rand_int, suffix });
...@@ -2116,8 +2119,8 @@ fn buildStaticLibFromZig(comp: *Compilation, basename: []const u8, out: *?CRTFil...@@ -2116,8 +2119,8 @@ fn buildStaticLibFromZig(comp: *Compilation, basename: []const u8, out: *?CRTFil
2116 }2119 }
2117 };2120 };
2118 const sub_compilation = try Compilation.create(comp.gpa, .{2121 const sub_compilation = try Compilation.create(comp.gpa, .{
2119 // TODO use the global cache directory here2122 .global_cache_directory = comp.global_cache_directory,
2120 .zig_cache_directory = comp.zig_cache_directory,2123 .local_cache_directory = comp.global_cache_directory,
2121 .zig_lib_directory = comp.zig_lib_directory,2124 .zig_lib_directory = comp.zig_lib_directory,
2122 .target = comp.getTarget(),2125 .target = comp.getTarget(),
2123 .root_name = mem.split(basename, ".").next().?,2126 .root_name = mem.split(basename, ".").next().?,
src/glibc.zig+12-9
...@@ -691,8 +691,8 @@ fn build_crt_file(...@@ -691,8 +691,8 @@ fn build_crt_file(
691 .basename = basename,691 .basename = basename,
692 };692 };
693 const sub_compilation = try Compilation.create(comp.gpa, .{693 const sub_compilation = try Compilation.create(comp.gpa, .{
694 // TODO use the global cache directory here694 .local_cache_directory = comp.global_cache_directory,
695 .zig_cache_directory = comp.zig_cache_directory,695 .global_cache_directory = comp.global_cache_directory,
696 .zig_lib_directory = comp.zig_lib_directory,696 .zig_lib_directory = comp.zig_lib_directory,
697 .target = comp.getTarget(),697 .target = comp.getTarget(),
698 .root_name = mem.split(basename, ".").next().?,698 .root_name = mem.split(basename, ".").next().?,
...@@ -769,11 +769,13 @@ pub fn buildSharedObjects(comp: *Compilation) !void {...@@ -769,11 +769,13 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
769 const target = comp.getTarget();769 const target = comp.getTarget();
770 const target_version = target.os.version_range.linux.glibc;770 const target_version = target.os.version_range.linux.glibc;
771771
772 // TODO use the global cache directory here772 // Use the global cache directory.
773 var cache_parent: Cache = .{773 var cache_parent: Cache = .{
774 .gpa = comp.gpa,774 .gpa = comp.gpa,
775 .manifest_dir = comp.cache_parent.manifest_dir,775 .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
776 };776 };
777 defer cache_parent.manifest_dir.close();
778
777 var cache = cache_parent.obtain();779 var cache = cache_parent.obtain();
778 defer cache.deinit();780 defer cache.deinit();
779 cache.hash.addBytes(build_options.version);781 cache.hash.addBytes(build_options.version);
...@@ -790,8 +792,8 @@ pub fn buildSharedObjects(comp: *Compilation) !void {...@@ -790,8 +792,8 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
790 // We use the presence of an "ok" file to determine if it is a true hit.792 // We use the presence of an "ok" file to determine if it is a true hit.
791793
792 var o_directory: Compilation.Directory = .{794 var o_directory: Compilation.Directory = .{
793 .handle = try comp.zig_cache_directory.handle.makeOpenPath(o_sub_path, .{}),795 .handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}),
794 .path = try path.join(arena, &[_][]const u8{ comp.zig_cache_directory.path.?, o_sub_path }),796 .path = try path.join(arena, &[_][]const u8{ comp.global_cache_directory.path.?, o_sub_path }),
795 };797 };
796 defer o_directory.handle.close();798 defer o_directory.handle.close();
797799
...@@ -931,7 +933,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {...@@ -931,7 +933,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
931 const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable;933 const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable;
932 try o_directory.handle.writeFile(asm_file_basename, zig_body.items);934 try o_directory.handle.writeFile(asm_file_basename, zig_body.items);
933935
934 try buildSharedLib(comp, arena, comp.zig_cache_directory, o_directory, asm_file_basename, lib);936 try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib);
935 }937 }
936 // No need to write the manifest because there are no file inputs associated with this cache hash.938 // No need to write the manifest because there are no file inputs associated with this cache hash.
937 // However we do need to write the ok file now.939 // However we do need to write the ok file now.
...@@ -945,7 +947,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {...@@ -945,7 +947,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
945 assert(comp.glibc_so_files == null);947 assert(comp.glibc_so_files == null);
946 comp.glibc_so_files = BuiltSharedObjects{948 comp.glibc_so_files = BuiltSharedObjects{
947 .lock = cache.toOwnedLock(),949 .lock = cache.toOwnedLock(),
948 .dir_path = try path.join(comp.gpa, &[_][]const u8{ comp.zig_cache_directory.path.?, o_sub_path }),950 .dir_path = try path.join(comp.gpa, &[_][]const u8{ comp.global_cache_directory.path.?, o_sub_path }),
949 };951 };
950}952}
951953
...@@ -976,7 +978,8 @@ fn buildSharedLib(...@@ -976,7 +978,8 @@ fn buildSharedLib(
976 },978 },
977 };979 };
978 const sub_compilation = try Compilation.create(comp.gpa, .{980 const sub_compilation = try Compilation.create(comp.gpa, .{
979 .zig_cache_directory = zig_cache_directory,981 .local_cache_directory = zig_cache_directory,
982 .global_cache_directory = comp.global_cache_directory,
980 .zig_lib_directory = comp.zig_lib_directory,983 .zig_lib_directory = comp.zig_lib_directory,
981 .target = comp.getTarget(),984 .target = comp.getTarget(),
982 .root_name = lib.name,985 .root_name = lib.name,
src/introspect.zig-7
...@@ -73,10 +73,3 @@ pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 {...@@ -73,10 +73,3 @@ pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 {
7373
74 return fs.getAppDataDir(allocator, appname);74 return fs.getAppDataDir(allocator, appname);
75}75}
76
77pub fn openGlobalCacheDir() !fs.Dir {
78 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
79 var fba = std.heap.FixedBufferAllocator.init(&buf);
80 const path_name = try resolveGlobalCacheDir(&fba.allocator);
81 return fs.cwd().makeOpenPath(path_name, .{});
82}
src/libcxx.zig+4-4
...@@ -146,8 +146,8 @@ pub fn buildLibCXX(comp: *Compilation) !void {...@@ -146,8 +146,8 @@ pub fn buildLibCXX(comp: *Compilation) !void {
146 }146 }
147147
148 const sub_compilation = try Compilation.create(comp.gpa, .{148 const sub_compilation = try Compilation.create(comp.gpa, .{
149 // TODO use the global cache directory here149 .local_cache_directory = comp.global_cache_directory,
150 .zig_cache_directory = comp.zig_cache_directory,150 .global_cache_directory = comp.global_cache_directory,
151 .zig_lib_directory = comp.zig_lib_directory,151 .zig_lib_directory = comp.zig_lib_directory,
152 .target = target,152 .target = target,
153 .root_name = root_name,153 .root_name = root_name,
...@@ -255,8 +255,8 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {...@@ -255,8 +255,8 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
255 }255 }
256256
257 const sub_compilation = try Compilation.create(comp.gpa, .{257 const sub_compilation = try Compilation.create(comp.gpa, .{
258 // TODO use the global cache directory here258 .local_cache_directory = comp.global_cache_directory,
259 .zig_cache_directory = comp.zig_cache_directory,259 .global_cache_directory = comp.global_cache_directory,
260 .zig_lib_directory = comp.zig_lib_directory,260 .zig_lib_directory = comp.zig_lib_directory,
261 .target = target,261 .target = target,
262 .root_name = root_name,262 .root_name = root_name,
src/libunwind.zig+2-2
...@@ -86,8 +86,8 @@ pub fn buildStaticLib(comp: *Compilation) !void {...@@ -86,8 +86,8 @@ pub fn buildStaticLib(comp: *Compilation) !void {
86 };86 };
87 }87 }
88 const sub_compilation = try Compilation.create(comp.gpa, .{88 const sub_compilation = try Compilation.create(comp.gpa, .{
89 // TODO use the global cache directory here89 .local_cache_directory = comp.global_cache_directory,
90 .zig_cache_directory = comp.zig_cache_directory,90 .global_cache_directory = comp.global_cache_directory,
91 .zig_lib_directory = comp.zig_lib_directory,91 .zig_lib_directory = comp.zig_lib_directory,
92 .target = target,92 .target = target,
93 .root_name = root_name,93 .root_name = root_name,
src/main.zig+51-9
...@@ -193,6 +193,8 @@ const usage_build_generic =...@@ -193,6 +193,8 @@ const usage_build_generic =
193 \\ -femit-bin[=path] (default) output machine code193 \\ -femit-bin[=path] (default) output machine code
194 \\ -fno-emit-bin Do not output machine code194 \\ -fno-emit-bin Do not output machine code
195 \\ --show-builtin Output the source of @import("builtin") then exit195 \\ --show-builtin Output the source of @import("builtin") then exit
196 \\ --cache-dir [path] Override the local cache directory
197 \\ --global-cache-dir [path] Override the global cache directory
196 \\198 \\
197 \\Compile Options:199 \\Compile Options:
198 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command200 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command
...@@ -353,6 +355,8 @@ pub fn buildOutputType(...@@ -353,6 +355,8 @@ pub fn buildOutputType(
353 var runtime_args_start: ?usize = null;355 var runtime_args_start: ?usize = null;
354 var test_filter: ?[]const u8 = null;356 var test_filter: ?[]const u8 = null;
355 var test_name_prefix: ?[]const u8 = null;357 var test_name_prefix: ?[]const u8 = null;
358 var override_local_cache_dir: ?[]const u8 = null;
359 var override_global_cache_dir: ?[]const u8 = null;
356360
357 var system_libs = std.ArrayList([]const u8).init(gpa);361 var system_libs = std.ArrayList([]const u8).init(gpa);
358 defer system_libs.deinit();362 defer system_libs.deinit();
...@@ -535,6 +539,14 @@ pub fn buildOutputType(...@@ -535,6 +539,14 @@ pub fn buildOutputType(
535 if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});539 if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
536 i += 1;540 i += 1;
537 try test_exec_args.append(args[i]);541 try test_exec_args.append(args[i]);
542 } else if (mem.eql(u8, arg, "--cache-dir")) {
543 if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
544 i += 1;
545 override_local_cache_dir = args[i];
546 } else if (mem.eql(u8, arg, "--global-cache-dir")) {
547 if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
548 i += 1;
549 override_global_cache_dir = args[i];
538 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {550 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {
539 try test_exec_args.append(null);551 try test_exec_args.append(null);
540 } else if (mem.eql(u8, arg, "--test-evented-io")) {552 } else if (mem.eql(u8, arg, "--test-evented-io")) {
...@@ -1093,7 +1105,10 @@ pub fn buildOutputType(...@@ -1093,7 +1105,10 @@ pub fn buildOutputType(
1093 const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) {1105 const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) {
1094 .no => null,1106 .no => null,
1095 .yes_default_path => Compilation.EmitLoc{1107 .yes_default_path => Compilation.EmitLoc{
1096 .directory = .{ .path = null, .handle = fs.cwd() },1108 .directory = switch (arg_mode) {
1109 .run, .zig_test => null,
1110 else => .{ .path = null, .handle = fs.cwd() },
1111 },
1097 .basename = try std.zig.binNameAlloc(1112 .basename = try std.zig.binNameAlloc(
1098 arena,1113 arena,
1099 root_name,1114 root_name,
...@@ -1198,26 +1213,53 @@ pub fn buildOutputType(...@@ -1198,26 +1213,53 @@ pub fn buildOutputType(
1198 };1213 };
1199 }1214 }
12001215
1201 const cache_parent_dir = if (root_pkg) |pkg| pkg.root_src_directory.handle else fs.cwd();1216 var global_cache_directory: Compilation.Directory = l: {
1202 var cache_dir = try cache_parent_dir.makeOpenPath("zig-cache", .{});1217 const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena);
1203 defer cache_dir.close();1218 break :l .{
1204 const zig_cache_directory: Compilation.Directory = .{1219 .handle = try fs.cwd().makeOpenPath(p, .{}),
1205 .handle = cache_dir,1220 .path = p,
1206 .path = blk: {1221 };
1222 };
1223 defer global_cache_directory.handle.close();
1224
1225 var cleanup_local_cache_dir: ?fs.Dir = null;
1226 defer if (cleanup_local_cache_dir) |*dir| dir.close();
1227
1228 var local_cache_directory: Compilation.Directory = l: {
1229 if (override_local_cache_dir) |local_cache_dir_path| {
1230 const dir = try fs.cwd().makeOpenPath(local_cache_dir_path, .{});
1231 cleanup_local_cache_dir = dir;
1232 break :l .{
1233 .handle = dir,
1234 .path = local_cache_dir_path,
1235 };
1236 }
1237 if (arg_mode == .run) {
1238 break :l global_cache_directory;
1239 }
1240 const cache_dir_path = blk: {
1207 if (root_pkg) |pkg| {1241 if (root_pkg) |pkg| {
1208 if (pkg.root_src_directory.path) |p| {1242 if (pkg.root_src_directory.path) |p| {
1209 break :blk try fs.path.join(arena, &[_][]const u8{ p, "zig-cache" });1243 break :blk try fs.path.join(arena, &[_][]const u8{ p, "zig-cache" });
1210 }1244 }
1211 }1245 }
1212 break :blk "zig-cache";1246 break :blk "zig-cache";
1213 },1247 };
1248 const cache_parent_dir = if (root_pkg) |pkg| pkg.root_src_directory.handle else fs.cwd();
1249 const dir = try cache_parent_dir.makeOpenPath("zig-cache", .{});
1250 cleanup_local_cache_dir = dir;
1251 break :l .{
1252 .handle = dir,
1253 .path = cache_dir_path,
1254 };
1214 };1255 };
12151256
1216 gimmeMoreOfThoseSweetSweetFileDescriptors();1257 gimmeMoreOfThoseSweetSweetFileDescriptors();
12171258
1218 const comp = Compilation.create(gpa, .{1259 const comp = Compilation.create(gpa, .{
1219 .zig_lib_directory = zig_lib_directory,1260 .zig_lib_directory = zig_lib_directory,
1220 .zig_cache_directory = zig_cache_directory,1261 .local_cache_directory = local_cache_directory,
1262 .global_cache_directory = global_cache_directory,
1221 .root_name = root_name,1263 .root_name = root_name,
1222 .target = target_info.target,1264 .target = target_info.target,
1223 .is_native_os = cross_target.isNativeOs(),1265 .is_native_os = cross_target.isNativeOs(),
src/test.zig+2-1
...@@ -480,7 +480,8 @@ pub const TestContext = struct {...@@ -480,7 +480,8 @@ pub const TestContext = struct {
480 .basename = bin_name,480 .basename = bin_name,
481 };481 };
482 const comp = try Compilation.create(allocator, .{482 const comp = try Compilation.create(allocator, .{
483 .zig_cache_directory = zig_cache_directory,483 .local_cache_directory = zig_cache_directory,
484 .global_cache_directory = zig_cache_directory,
484 .zig_lib_directory = zig_lib_directory,485 .zig_lib_directory = zig_lib_directory,
485 .rand = rand,486 .rand = rand,
486 .root_name = "test_case",487 .root_name = "test_case",