authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-01 22:43:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-02 20:43:01-07:00
loged4ccea7bae99c1baa634716941f308d9f922985
treef2bbf9997f911b68cca67bc0c297e8324ced4180
parent22537873f4e80fa1caca6b7b8a4b14c8d7284de2

build system: implement --system [dir]

This prevents package fetching and enables system_package_mode in the build system which flips the defaults for system integrations.

4 files changed, 70 insertions(+), 17 deletions(-)

lib/build_runner.zig+17-11
......@@ -202,6 +202,11 @@ pub fn main() !void {
202202 builder.debug_pkg_config = true;
203203 } else if (mem.eql(u8, arg, "--debug-compile-errors")) {
204204 builder.debug_compile_errors = true;
205 } else if (mem.eql(u8, arg, "--system")) {
206 // The usage text shows another argument after this parameter
207 // but it is handled by the parent process. The build runner
208 // only sees this flag.
209 graph.system_package_mode = true;
205210 } else if (mem.eql(u8, arg, "--glibc-runtimes")) {
206211 builder.glibc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
207212 } else if (mem.eql(u8, arg, "--verbose-link")) {
......@@ -1053,18 +1058,14 @@ fn usage(b: *std.Build, out_stream: anytype) !void {
10531058 try out_stream.writeAll(
10541059 \\
10551060 \\General Options:
1056 \\ -p, --prefix [path] Where to put installed files (default: zig-out)
1057 \\ --prefix-lib-dir [path] Where to put installed libraries
1058 \\ --prefix-exe-dir [path] Where to put installed executables
1059 \\ --prefix-include-dir [path] Where to put installed C header files
1061 \\ -p, --prefix [path] Where to install files (default: zig-out)
1062 \\ --prefix-lib-dir [path] Where to install libraries
1063 \\ --prefix-exe-dir [path] Where to install executables
1064 \\ --prefix-include-dir [path] Where to install C header files
10601065 \\
10611066 \\ --release[=mode] Request release mode, optionally specifying a
10621067 \\ preferred optimization mode: fast, safe, small
10631068 \\
1064 \\ --sysroot [path] Set the system root directory (usually /)
1065 \\ --search-prefix [path] Add a path to look for binaries, libraries, headers
1066 \\ --libc [file] Provide a file which specifies libc paths
1067 \\
10681069 \\ -fdarling, -fno-darling Integration with system-installed Darling to
10691070 \\ execute macOS programs on Linux hosts
10701071 \\ (default: no)
......@@ -1122,13 +1123,18 @@ fn usage(b: *std.Build, out_stream: anytype) !void {
11221123 try out_stream.writeAll(
11231124 \\
11241125 \\System Integration Options:
1125 \\ --system [dir] System Package Mode. Disable fetching; prefer system libs
1126 \\ -fsys=[name] Enable a system integration
1127 \\ -fno-sys=[name] Disable a system integration
1126 \\ --search-prefix [path] Add a path to look for binaries, libraries, headers
1127 \\ --sysroot [path] Set the system root directory (usually /)
1128 \\ --libc [file] Provide a file which specifies libc paths
1129 \\
11281130 \\ --host-target [triple] Use the provided target as the host
11291131 \\ --host-cpu [cpu] Use the provided CPU as the host
11301132 \\ --host-dynamic-linker [path] Use the provided dynamic linker as the host
11311133 \\
1134 \\ --system [pkgdir] Disable package fetching; enable all integrations
1135 \\ -fsys=[name] Enable a system integration
1136 \\ -fno-sys=[name] Disable a system integration
1137 \\
11321138 \\ Available System Integrations: Enabled:
11331139 \\
11341140 );
lib/std/Build.zig+1-1
......@@ -1254,7 +1254,7 @@ pub fn standardOptimizeOption(b: *Build, options: StandardOptimizeOptionOptions)
12541254 if (b.option(
12551255 std.builtin.OptimizeMode,
12561256 "optimize",
1257 "Prioritize performance, safety, or binary size (-O flag)",
1257 "Prioritize performance, safety, or binary size",
12581258 )) |mode| {
12591259 return mode;
12601260 }
src/Package/Fetch.zig+28-3
......@@ -80,6 +80,15 @@ pub const JobQueue = struct {
8080 thread_pool: *ThreadPool,
8181 wait_group: WaitGroup = .{},
8282 global_cache: Cache.Directory,
83 /// If true then, no fetching occurs, and:
84 /// * The `global_cache` directory is assumed to be the direct parent
85 /// directory of on-disk packages rather than having the "p/" directory
86 /// prefix inside of it.
87 /// * An error occurs if any non-lazy packages are not already present in
88 /// the package cache directory.
89 /// * Missing hash field causes an error, and no fetching occurs so it does
90 /// not print the correct hash like usual.
91 read_only: bool,
8392 recursive: bool,
8493 /// Dumps hash information to stdout which can be used to troubleshoot why
8594 /// two hashes of the same package do not match.
......@@ -270,7 +279,8 @@ pub fn run(f: *Fetch) RunError!void {
270279 // We want to fail unless the resolved relative path has a
271280 // prefix of "p/$hash/".
272281 const digest_len = @typeInfo(Manifest.MultiHashHexDigest).Array.len;
273 const expected_prefix = f.parent_package_root.sub_path[0 .. "p/".len + digest_len];
282 const prefix_len: usize = if (f.job_queue.read_only) 0 else "p/".len;
283 const expected_prefix = f.parent_package_root.sub_path[0 .. prefix_len + digest_len];
274284 if (!std.mem.startsWith(u8, pkg_root.sub_path, expected_prefix)) {
275285 return f.fail(
276286 f.location_tok,
......@@ -311,7 +321,9 @@ pub fn run(f: *Fetch) RunError!void {
311321
312322 const s = fs.path.sep_str;
313323 if (remote.hash) |expected_hash| {
314 const pkg_sub_path = "p" ++ s ++ expected_hash;
324 const prefixed_pkg_sub_path = "p" ++ s ++ expected_hash;
325 const prefix_len: usize = if (f.job_queue.read_only) "p/".len else 0;
326 const pkg_sub_path = prefixed_pkg_sub_path[prefix_len..];
315327 if (cache_root.handle.access(pkg_sub_path, .{})) |_| {
316328 f.package_root = .{
317329 .root_dir = cache_root,
......@@ -322,7 +334,14 @@ pub fn run(f: *Fetch) RunError!void {
322334 if (!f.job_queue.recursive) return;
323335 return queueJobsForDeps(f);
324336 } else |err| switch (err) {
325 error.FileNotFound => {},
337 error.FileNotFound => {
338 if (f.job_queue.read_only) return f.fail(
339 f.location_tok,
340 try eb.printString("package not found at '{}{s}'", .{
341 cache_root, pkg_sub_path,
342 }),
343 );
344 },
326345 else => |e| {
327346 try eb.addRootErrorMessage(.{
328347 .msg = try eb.printString("unable to open global package cache directory '{}{s}': {s}", .{
......@@ -332,6 +351,12 @@ pub fn run(f: *Fetch) RunError!void {
332351 return error.FetchFailed;
333352 },
334353 }
354 } else {
355 try eb.addRootErrorMessage(.{
356 .msg = try eb.addString("dependency is missing hash field"),
357 .src_loc = try f.srcLoc(f.location_tok),
358 });
359 return error.FetchFailed;
335360 }
336361
337362 // Fetch and unpack the remote into a temporary directory.
src/main.zig+24-2
......@@ -5179,6 +5179,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
51795179 var verbose_cimport = false;
51805180 var verbose_llvm_cpu_features = false;
51815181 var fetch_only = false;
5182 var system_pkg_dir_path: ?[]const u8 = null;
51825183
51835184 const argv_index_exe = child_argv.items.len;
51845185 _ = try child_argv.addOne();
......@@ -5235,6 +5236,12 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
52355236 reference_trace = 256;
52365237 } else if (mem.eql(u8, arg, "--fetch")) {
52375238 fetch_only = true;
5239 } else if (mem.eql(u8, arg, "--system")) {
5240 if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});
5241 i += 1;
5242 system_pkg_dir_path = args[i];
5243 try child_argv.append("--system");
5244 continue;
52385245 } else if (mem.startsWith(u8, arg, "-freference-trace=")) {
52395246 const num = arg["-freference-trace=".len..];
52405247 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
54195426 var http_client: std.http.Client = .{ .allocator = gpa };
54205427 defer http_client.deinit();
54215428
5422 try http_client.loadDefaultProxies();
5423
54245429 var progress: std.Progress = .{ .dont_print_on_dumb = true };
54255430 const root_prog_node = progress.start("Fetch Packages", 0);
54265431 defer root_prog_node.end();
......@@ -5429,12 +5434,28 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
54295434 .http_client = &http_client,
54305435 .thread_pool = &thread_pool,
54315436 .global_cache = global_cache_directory,
5437 .read_only = false,
54325438 .recursive = true,
54335439 .debug_hash = false,
54345440 .work_around_btrfs_bug = work_around_btrfs_bug,
54355441 };
54365442 defer job_queue.deinit();
54375443
5444 if (system_pkg_dir_path) |p| {
5445 job_queue.global_cache = .{
5446 .path = p,
5447 .handle = fs.cwd().openDir(p, .{}) catch |err| {
5448 fatal("unable to open system package directory '{s}': {s}", .{
5449 p, @errorName(err),
5450 });
5451 },
5452 };
5453 job_queue.read_only = true;
5454 cleanup_build_dir = job_queue.global_cache.handle;
5455 } else {
5456 try http_client.loadDefaultProxies();
5457 }
5458
54385459 try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1);
54395460 try job_queue.table.ensureUnusedCapacity(gpa, 1);
54405461
......@@ -7363,6 +7384,7 @@ fn cmdFetch(
73637384 .thread_pool = &thread_pool,
73647385 .global_cache = global_cache_directory,
73657386 .recursive = false,
7387 .read_only = false,
73667388 .debug_hash = debug_hash,
73677389 .work_around_btrfs_bug = work_around_btrfs_bug,
73687390 };