diff --git a/lib/build_runner.zig b/lib/build_runner.zig index 2fd8ecd034..c6e8e52e9f 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -202,6 +202,11 @@ pub fn main() !void { builder.debug_pkg_config = true; } else if (mem.eql(u8, arg, "--debug-compile-errors")) { builder.debug_compile_errors = true; + } else if (mem.eql(u8, arg, "--system")) { + // The usage text shows another argument after this parameter + // but it is handled by the parent process. The build runner + // only sees this flag. + graph.system_package_mode = true; } else if (mem.eql(u8, arg, "--glibc-runtimes")) { builder.glibc_runtimes_dir = nextArgOrFatal(args, &arg_idx); } else if (mem.eql(u8, arg, "--verbose-link")) { @@ -1053,18 +1058,14 @@ fn usage(b: *std.Build, out_stream: anytype) !void { try out_stream.writeAll( \\ \\General Options: - \\ -p, --prefix [path] Where to put installed files (default: zig-out) - \\ --prefix-lib-dir [path] Where to put installed libraries - \\ --prefix-exe-dir [path] Where to put installed executables - \\ --prefix-include-dir [path] Where to put installed C header files + \\ -p, --prefix [path] Where to install files (default: zig-out) + \\ --prefix-lib-dir [path] Where to install libraries + \\ --prefix-exe-dir [path] Where to install executables + \\ --prefix-include-dir [path] Where to install C header files \\ \\ --release[=mode] Request release mode, optionally specifying a \\ preferred optimization mode: fast, safe, small \\ - \\ --sysroot [path] Set the system root directory (usually /) - \\ --search-prefix [path] Add a path to look for binaries, libraries, headers - \\ --libc [file] Provide a file which specifies libc paths - \\ \\ -fdarling, -fno-darling Integration with system-installed Darling to \\ execute macOS programs on Linux hosts \\ (default: no) @@ -1122,13 +1123,18 @@ fn usage(b: *std.Build, out_stream: anytype) !void { try out_stream.writeAll( \\ \\System Integration Options: - \\ --system [dir] System Package Mode. Disable fetching; prefer system libs - \\ -fsys=[name] Enable a system integration - \\ -fno-sys=[name] Disable a system integration + \\ --search-prefix [path] Add a path to look for binaries, libraries, headers + \\ --sysroot [path] Set the system root directory (usually /) + \\ --libc [file] Provide a file which specifies libc paths + \\ \\ --host-target [triple] Use the provided target as the host \\ --host-cpu [cpu] Use the provided CPU as the host \\ --host-dynamic-linker [path] Use the provided dynamic linker as the host \\ + \\ --system [pkgdir] Disable package fetching; enable all integrations + \\ -fsys=[name] Enable a system integration + \\ -fno-sys=[name] Disable a system integration + \\ \\ Available System Integrations: Enabled: \\ ); diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 6bdd391430..e2d31b84d6 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1254,7 +1254,7 @@ pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions) if (b.option( std.builtin.OptimizeMode, "optimize", - "Prioritize performance, safety, or binary size (-O flag)", + "Prioritize performance, safety, or binary size", )) |mode| { return mode; } diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index 58fdb68278..f8f153d07d 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -80,6 +80,15 @@ pub const JobQueue = struct { thread_pool: *ThreadPool, wait_group: WaitGroup = .{}, global_cache: Cache.Directory, + /// If true then, no fetching occurs, and: + /// * The `global_cache` directory is assumed to be the direct parent + /// directory of on-disk packages rather than having the "p/" directory + /// prefix inside of it. + /// * An error occurs if any non-lazy packages are not already present in + /// the package cache directory. + /// * Missing hash field causes an error, and no fetching occurs so it does + /// not print the correct hash like usual. + read_only: bool, recursive: bool, /// Dumps hash information to stdout which can be used to troubleshoot why /// two hashes of the same package do not match. @@ -270,7 +279,8 @@ pub fn run(f: *Fetch) RunError!void { // We want to fail unless the resolved relative path has a // prefix of "p/$hash/". const digest_len = @typeInfo(Manifest.MultiHashHexDigest).Array.len; - const expected_prefix = f.parent_package_root.sub_path[0 .. "p/".len + digest_len]; + const prefix_len: usize = if (f.job_queue.read_only) 0 else "p/".len; + const expected_prefix = f.parent_package_root.sub_path[0 .. prefix_len + digest_len]; if (!std.mem.startsWith(u8, pkg_root.sub_path, expected_prefix)) { return f.fail( f.location_tok, @@ -311,7 +321,9 @@ pub fn run(f: *Fetch) RunError!void { const s = fs.path.sep_str; if (remote.hash) |expected_hash| { - const pkg_sub_path = "p" ++ s ++ expected_hash; + const prefixed_pkg_sub_path = "p" ++ s ++ expected_hash; + const prefix_len: usize = if (f.job_queue.read_only) "p/".len else 0; + const pkg_sub_path = prefixed_pkg_sub_path[prefix_len..]; if (cache_root.handle.access(pkg_sub_path, .{})) |_| { f.package_root = .{ .root_dir = cache_root, @@ -322,7 +334,14 @@ pub fn run(f: *Fetch) RunError!void { if (!f.job_queue.recursive) return; return queueJobsForDeps(f); } else |err| switch (err) { - error.FileNotFound => {}, + error.FileNotFound => { + if (f.job_queue.read_only) return f.fail( + f.location_tok, + try eb.printString("package not found at '{}{s}'", .{ + cache_root, pkg_sub_path, + }), + ); + }, else => |e| { try eb.addRootErrorMessage(.{ .msg = try eb.printString("unable to open global package cache directory '{}{s}': {s}", .{ @@ -332,6 +351,12 @@ pub fn run(f: *Fetch) RunError!void { return error.FetchFailed; }, } + } else { + try eb.addRootErrorMessage(.{ + .msg = try eb.addString("dependency is missing hash field"), + .src_loc = try f.srcLoc(f.location_tok), + }); + return error.FetchFailed; } // Fetch and unpack the remote into a temporary directory. diff --git a/src/main.zig b/src/main.zig index a13e7b1fab..7e2827bc69 100644 --- a/src/main.zig +++ b/src/main.zig @@ -5179,6 +5179,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi var verbose_cimport = false; var verbose_llvm_cpu_features = false; var fetch_only = false; + var system_pkg_dir_path: ?[]const u8 = null; const argv_index_exe = child_argv.items.len; _ = try child_argv.addOne(); @@ -5235,6 +5236,12 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi reference_trace = 256; } else if (mem.eql(u8, arg, "--fetch")) { fetch_only = true; + } else if (mem.eql(u8, arg, "--system")) { + if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg}); + i += 1; + system_pkg_dir_path = args[i]; + try child_argv.append("--system"); + continue; } else if (mem.startsWith(u8, arg, "-freference-trace=")) { const num = arg["-freference-trace=".len..]; reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| { @@ -5419,8 +5426,6 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi var http_client: std.http.Client = .{ .allocator = gpa }; defer http_client.deinit(); - try http_client.loadDefaultProxies(); - var progress: std.Progress = .{ .dont_print_on_dumb = true }; const root_prog_node = progress.start("Fetch Packages", 0); defer root_prog_node.end(); @@ -5429,12 +5434,28 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi .http_client = &http_client, .thread_pool = &thread_pool, .global_cache = global_cache_directory, + .read_only = false, .recursive = true, .debug_hash = false, .work_around_btrfs_bug = work_around_btrfs_bug, }; defer job_queue.deinit(); + if (system_pkg_dir_path) |p| { + job_queue.global_cache = .{ + .path = p, + .handle = fs.cwd().openDir(p, .{}) catch |err| { + fatal("unable to open system package directory '{s}': {s}", .{ + p, @errorName(err), + }); + }, + }; + job_queue.read_only = true; + cleanup_build_dir = job_queue.global_cache.handle; + } else { + try http_client.loadDefaultProxies(); + } + try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1); try job_queue.table.ensureUnusedCapacity(gpa, 1); @@ -7363,6 +7384,7 @@ fn cmdFetch( .thread_pool = &thread_pool, .global_cache = global_cache_directory, .recursive = false, + .read_only = false, .debug_hash = debug_hash, .work_around_btrfs_bug = work_around_btrfs_bug, };