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 @@
1414 * -fno-emit-asm (default) do not output .s (assembly code)\n"
1515 * -femit-llvm-ir produce a .ll file with LLVM IR\n"
1616 * -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
2117 * support rpaths in ELF linker code
2218 * add CLI support for a way to pass extra flags to c source files
2319 * musl
2420 * 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`
2721 * MachO LLD linking
2822 * COFF LLD linking
2923 * WASM LLD linking
30 * support cross compiling stage2 with `zig build`
3124 * --main-pkg-path
3225 * audit the CLI options for stage2
33 * restore error messages for stage2_add_link_lib
3426 * 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
3529 * 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`
3734 * implement proper compile errors for failing to build glibc crt files and shared libs
3835 * implement -fno-emit-bin
3936 * improve the stage2 tests to support testing with LLVM extensions enabled
src/Compilation.zig+17-14
......@@ -64,7 +64,8 @@ cache_parent: *Cache,
6464/// Path to own executable for invoking `zig clang`.
6565self_exe_path: ?[]const u8,
6666zig_lib_directory: Directory,
67zig_cache_directory: Directory,
67local_cache_directory: Directory,
68global_cache_directory: Directory,
6869libc_include_dir_list: []const []const u8,
6970rand: *std.rand.Random,
7071
......@@ -267,7 +268,8 @@ pub const EmitLoc = struct {
267268
268269pub const InitOptions = struct {
269270 zig_lib_directory: Directory,
270 zig_cache_directory: Directory,
271 local_cache_directory: Directory,
272 global_cache_directory: Directory,
271273 target: Target,
272274 root_name: []const u8,
273275 root_pkg: ?*Package,
......@@ -523,7 +525,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
523525 const cache = try arena.create(Cache);
524526 cache.* = .{
525527 .gpa = gpa,
526 .manifest_dir = try options.zig_cache_directory.handle.makeOpenPath("h", .{}),
528 .manifest_dir = try options.local_cache_directory.handle.makeOpenPath("h", .{}),
527529 };
528530 errdefer cache.manifest_dir.close();
529531
......@@ -569,11 +571,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
569571
570572 const digest = hash.final();
571573 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, .{});
573575 errdefer artifact_dir.close();
574576 const zig_cache_artifact_directory: Directory = .{
575577 .handle = artifact_dir,
576 .path = if (options.zig_cache_directory.path) |p|
578 .path = if (options.local_cache_directory.path) |p|
577579 try std.fs.path.join(arena, &[_][]const u8{ p, artifact_sub_dir })
578580 else
579581 artifact_sub_dir,
......@@ -647,11 +649,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
647649
648650 const digest = hash.final();
649651 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, .{});
651653 owned_link_dir = artifact_dir;
652654 const link_artifact_directory: Directory = .{
653655 .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}),
655657 };
656658 break :blk link_artifact_directory;
657659 };
......@@ -715,7 +717,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
715717 .gpa = gpa,
716718 .arena_state = arena_allocator.state,
717719 .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,
719722 .bin_file = bin_file,
720723 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
721724 .keep_source_files_loaded = options.keep_source_files_loaded,
......@@ -1230,7 +1233,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
12301233
12311234 // We can't know the digest until we do the C compiler invocation, so we need a temporary filename.
12321235 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", .{});
12341237 defer zig_cache_tmp_dir.close();
12351238
12361239 try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang", "-c" });
......@@ -1319,7 +1322,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
13191322 // Rename into place.
13201323 const digest = ch.final();
13211324 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, .{});
13231326 defer o_dir.close();
13241327 // TODO https://github.com/ziglang/zig/issues/6344
13251328 const tmp_basename = std.fs.path.basename(out_obj_path);
......@@ -1331,7 +1334,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
13311334 break :blk digest;
13321335 };
13331336
1334 const components = if (comp.zig_cache_directory.path) |p|
1337 const components = if (comp.local_cache_directory.path) |p|
13351338 &[_][]const u8{ p, "o", &digest, o_basename }
13361339 else
13371340 &[_][]const u8{ "o", &digest, o_basename };
......@@ -1347,7 +1350,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject) !void {
13471350fn tmpFilePath(comp: *Compilation, arena: *Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 {
13481351 const s = std.fs.path.sep_str;
13491352 const rand_int = comp.rand.int(u64);
1350 if (comp.zig_cache_directory.path) |p| {
1353 if (comp.local_cache_directory.path) |p| {
13511354 return std.fmt.allocPrint(arena, "{}" ++ s ++ "tmp" ++ s ++ "{x}-{s}", .{ p, rand_int, suffix });
13521355 } else {
13531356 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
21162119 }
21172120 };
21182121 const sub_compilation = try Compilation.create(comp.gpa, .{
2119 // TODO use the global cache directory here
2120 .zig_cache_directory = comp.zig_cache_directory,
2122 .global_cache_directory = comp.global_cache_directory,
2123 .local_cache_directory = comp.global_cache_directory,
21212124 .zig_lib_directory = comp.zig_lib_directory,
21222125 .target = comp.getTarget(),
21232126 .root_name = mem.split(basename, ".").next().?,
src/glibc.zig+12-9
......@@ -691,8 +691,8 @@ fn build_crt_file(
691691 .basename = basename,
692692 };
693693 const sub_compilation = try Compilation.create(comp.gpa, .{
694 // TODO use the global cache directory here
695 .zig_cache_directory = comp.zig_cache_directory,
694 .local_cache_directory = comp.global_cache_directory,
695 .global_cache_directory = comp.global_cache_directory,
696696 .zig_lib_directory = comp.zig_lib_directory,
697697 .target = comp.getTarget(),
698698 .root_name = mem.split(basename, ".").next().?,
......@@ -769,11 +769,13 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
769769 const target = comp.getTarget();
770770 const target_version = target.os.version_range.linux.glibc;
771771
772 // TODO use the global cache directory here
772 // Use the global cache directory.
773773 var cache_parent: Cache = .{
774774 .gpa = comp.gpa,
775 .manifest_dir = comp.cache_parent.manifest_dir,
775 .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}),
776776 };
777 defer cache_parent.manifest_dir.close();
778
777779 var cache = cache_parent.obtain();
778780 defer cache.deinit();
779781 cache.hash.addBytes(build_options.version);
......@@ -790,8 +792,8 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
790792 // We use the presence of an "ok" file to determine if it is a true hit.
791793
792794 var o_directory: Compilation.Directory = .{
793 .handle = try comp.zig_cache_directory.handle.makeOpenPath(o_sub_path, .{}),
794 .path = try path.join(arena, &[_][]const u8{ comp.zig_cache_directory.path.?, o_sub_path }),
795 .handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}),
796 .path = try path.join(arena, &[_][]const u8{ comp.global_cache_directory.path.?, o_sub_path }),
795797 };
796798 defer o_directory.handle.close();
797799
......@@ -931,7 +933,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
931933 const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable;
932934 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);
935937 }
936938 // No need to write the manifest because there are no file inputs associated with this cache hash.
937939 // However we do need to write the ok file now.
......@@ -945,7 +947,7 @@ pub fn buildSharedObjects(comp: *Compilation) !void {
945947 assert(comp.glibc_so_files == null);
946948 comp.glibc_so_files = BuiltSharedObjects{
947949 .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 }),
949951 };
950952}
951953
......@@ -976,7 +978,8 @@ fn buildSharedLib(
976978 },
977979 };
978980 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,
980983 .zig_lib_directory = comp.zig_lib_directory,
981984 .target = comp.getTarget(),
982985 .root_name = lib.name,
src/introspect.zig-7
......@@ -73,10 +73,3 @@ pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 {
7373
7474 return fs.getAppDataDir(allocator, appname);
7575}
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 {
146146 }
147147
148148 const sub_compilation = try Compilation.create(comp.gpa, .{
149 // TODO use the global cache directory here
150 .zig_cache_directory = comp.zig_cache_directory,
149 .local_cache_directory = comp.global_cache_directory,
150 .global_cache_directory = comp.global_cache_directory,
151151 .zig_lib_directory = comp.zig_lib_directory,
152152 .target = target,
153153 .root_name = root_name,
......@@ -255,8 +255,8 @@ pub fn buildLibCXXABI(comp: *Compilation) !void {
255255 }
256256
257257 const sub_compilation = try Compilation.create(comp.gpa, .{
258 // TODO use the global cache directory here
259 .zig_cache_directory = comp.zig_cache_directory,
258 .local_cache_directory = comp.global_cache_directory,
259 .global_cache_directory = comp.global_cache_directory,
260260 .zig_lib_directory = comp.zig_lib_directory,
261261 .target = target,
262262 .root_name = root_name,
src/libunwind.zig+2-2
......@@ -86,8 +86,8 @@ pub fn buildStaticLib(comp: *Compilation) !void {
8686 };
8787 }
8888 const sub_compilation = try Compilation.create(comp.gpa, .{
89 // TODO use the global cache directory here
90 .zig_cache_directory = comp.zig_cache_directory,
89 .local_cache_directory = comp.global_cache_directory,
90 .global_cache_directory = comp.global_cache_directory,
9191 .zig_lib_directory = comp.zig_lib_directory,
9292 .target = target,
9393 .root_name = root_name,
src/main.zig+51-9
......@@ -193,6 +193,8 @@ const usage_build_generic =
193193 \\ -femit-bin[=path] (default) output machine code
194194 \\ -fno-emit-bin Do not output machine code
195195 \\ --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
196198 \\
197199 \\Compile Options:
198200 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command
......@@ -353,6 +355,8 @@ pub fn buildOutputType(
353355 var runtime_args_start: ?usize = null;
354356 var test_filter: ?[]const u8 = null;
355357 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
357361 var system_libs = std.ArrayList([]const u8).init(gpa);
358362 defer system_libs.deinit();
......@@ -535,6 +539,14 @@ pub fn buildOutputType(
535539 if (i + 1 >= args.len) fatal("expected parameter after {}", .{arg});
536540 i += 1;
537541 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];
538550 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {
539551 try test_exec_args.append(null);
540552 } else if (mem.eql(u8, arg, "--test-evented-io")) {
......@@ -1093,7 +1105,10 @@ pub fn buildOutputType(
10931105 const emit_bin_loc: ?Compilation.EmitLoc = switch (emit_bin) {
10941106 .no => null,
10951107 .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 },
10971112 .basename = try std.zig.binNameAlloc(
10981113 arena,
10991114 root_name,
......@@ -1198,26 +1213,53 @@ pub fn buildOutputType(
11981213 };
11991214 }
12001215
1201 const cache_parent_dir = if (root_pkg) |pkg| pkg.root_src_directory.handle else fs.cwd();
1202 var cache_dir = try cache_parent_dir.makeOpenPath("zig-cache", .{});
1203 defer cache_dir.close();
1204 const zig_cache_directory: Compilation.Directory = .{
1205 .handle = cache_dir,
1206 .path = blk: {
1216 var global_cache_directory: Compilation.Directory = l: {
1217 const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena);
1218 break :l .{
1219 .handle = try fs.cwd().makeOpenPath(p, .{}),
1220 .path = p,
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: {
12071241 if (root_pkg) |pkg| {
12081242 if (pkg.root_src_directory.path) |p| {
12091243 break :blk try fs.path.join(arena, &[_][]const u8{ p, "zig-cache" });
12101244 }
12111245 }
12121246 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 };
12141255 };
12151256
12161257 gimmeMoreOfThoseSweetSweetFileDescriptors();
12171258
12181259 const comp = Compilation.create(gpa, .{
12191260 .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,
12211263 .root_name = root_name,
12221264 .target = target_info.target,
12231265 .is_native_os = cross_target.isNativeOs(),
src/test.zig+2-1
......@@ -480,7 +480,8 @@ pub const TestContext = struct {
480480 .basename = bin_name,
481481 };
482482 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,
484485 .zig_lib_directory = zig_lib_directory,
485486 .rand = rand,
486487 .root_name = "test_case",