authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-12 17:45:44-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-12 17:45:44-07:00
logc8160b8a2ecd8ebf23e6e26a5dbb4dd6f3e60ffc
treefbef701cc261d1908fc2cf5dac2a2c3002c0b86c
parent9276a56e3cee12a067f93d719a5e7f2762dd4603

Maker: --help works even when configuration fails


2 files changed, 196 insertions(+), 154 deletions(-)

lib/compiler/Maker.zig+60-35
...@@ -23,6 +23,7 @@ const Color = std.zig.Color;...@@ -23,6 +23,7 @@ const Color = std.zig.Color;
23const Client = std.zig.Client;23const Client = std.zig.Client;
24const Server = std.zig.Server;24const Server = std.zig.Server;
25const EnvVar = std.zig.EnvVar;25const EnvVar = std.zig.EnvVar;
26const ErrorBundle = std.zig.ErrorBundle;
26const default_local_zig_cache_basename = std.zig.default_local_zig_cache_basename;27const default_local_zig_cache_basename = std.zig.default_local_zig_cache_basename;
27const stringToEnum = std.meta.stringToEnum;28const stringToEnum = std.meta.stringToEnum;
2829
...@@ -35,6 +36,7 @@ const ScannedConfig = @import("Maker/ScannedConfig.zig");...@@ -35,6 +36,7 @@ const ScannedConfig = @import("Maker/ScannedConfig.zig");
35const PkgConfig = @import("Maker/PkgConfig.zig");36const PkgConfig = @import("Maker/PkgConfig.zig");
36const Fetch = @import("Maker/Fetch.zig");37const Fetch = @import("Maker/Fetch.zig");
37const Package = @import("Maker/Package.zig");38const Package = @import("Maker/Package.zig");
39const Manifest = Package.Manifest;
3840
39pub const std_options: std.Options = .{41pub const std_options: std.Options = .{
40 .side_channels_mitigations = .none,42 .side_channels_mitigations = .none,
...@@ -601,10 +603,16 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -601,10 +603,16 @@ pub fn main(init: process.Init.Minimal) !void {
601 const cwd_path = std.zig.getResolvedCwd(io, arena) catch |err|603 const cwd_path = std.zig.getResolvedCwd(io, arena) catch |err|
602 fatal("resolving current directory path failed: {t}", .{err});604 fatal("resolving current directory path failed: {t}", .{err});
603605
604 var build_root = try findBuildRoot(arena, io, .{606 var build_root = findBuildRoot(arena, io, .{
605 .cwd_path = cwd_path,607 .cwd_path = cwd_path,
606 .build_file = build_file,608 .build_file = build_file,
607 });609 }) catch |err| switch (err) {
610 error.BuildZigNotFound => {
611 if (help_menu) printUsageWithoutConfiguration(&graph, "build.zig not found");
612 process.exit(1);
613 },
614 else => |e| return e,
615 };
608 defer build_root.deinit(io);616 defer build_root.deinit(io);
609617
610 graph.build_root_directory = build_root.directory;618 graph.build_root_directory = build_root.directory;
...@@ -740,7 +748,7 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -740,7 +748,7 @@ pub fn main(init: process.Init.Minimal) !void {
740 var configure_source_files: Cache.Manifest.SelfContainedFiles = .empty;748 var configure_source_files: Cache.Manifest.SelfContainedFiles = .empty;
741 defer configure_source_files.deinit(gpa);749 defer configure_source_files.deinit(gpa);
742750
743 var configure_error_bundle: std.zig.ErrorBundle = .empty;751 var configure_error_bundle: ErrorBundle = .empty;
744 defer configure_error_bundle.deinit(gpa);752 defer configure_error_bundle.deinit(gpa);
745753
746 // If this fails, we can still start the server and wait for user754 // If this fails, we can still start the server and wait for user
...@@ -1042,7 +1050,10 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -1042,7 +1050,10 @@ pub fn main(init: process.Init.Minimal) !void {
1042 } else |err| {1050 } else |err| {
1043 const can_fs_watch = switch (err) {1051 const can_fs_watch = switch (err) {
1044 error.AlreadyReported => false,1052 error.AlreadyReported => false,
1045 error.FailedButCacheIntact => true,1053 error.FailedButCacheIntact => c: {
1054 if (help_menu) printUsageWithoutConfiguration(&graph, "build.zig compilation failure");
1055 break :c true;
1056 },
1046 else => |e| w: {1057 else => |e| w: {
1047 log.err("configuration failed: {t}", .{e});1058 log.err("configuration failed: {t}", .{e});
1048 break :w false;1059 break :w false;
...@@ -1064,6 +1075,17 @@ pub fn main(init: process.Init.Minimal) !void {...@@ -1064,6 +1075,17 @@ pub fn main(init: process.Init.Minimal) !void {
1064 }1075 }
1065}1076}
10661077
1078fn printUsageWithoutConfiguration(graph: *Graph, reason: []const u8) noreturn {
1079 const io = graph.io;
1080 _ = io.lockStderr(&.{}, graph.stderr_mode) catch {};
1081 const writer = initStdoutWriter(io);
1082 ScannedConfig.printUsageWithoutConfiguration(graph.zig_exe, writer, reason) catch |err| switch (err) {
1083 error.WriteFailed => fatal("failed writing to stdout: {t}", .{stdout_writer_allocation.err.?}),
1084 };
1085 stdout_writer_allocation.flush() catch |err| fatal("failed writing to stdout: {t}", .{err});
1086 return process.exit(0);
1087}
1088
1067/// Temporarily adds the reconfigure pseudostep to step_stack, calls1089/// Temporarily adds the reconfigure pseudostep to step_stack, calls
1068/// `Watch.update`, and then pops it again.1090/// `Watch.update`, and then pops it again.
1069fn updateWatch(maker: *Maker, watch: *Watch) !void {1091fn updateWatch(maker: *Maker, watch: *Watch) !void {
...@@ -1091,7 +1113,7 @@ const ConfigureOptions = struct {...@@ -1091,7 +1113,7 @@ const ConfigureOptions = struct {
1091 print_configuration: PrintConfiguration,1113 print_configuration: PrintConfiguration,
1092 forks: []Fork,1114 forks: []Fork,
1093 src_files: *Cache.Manifest.SelfContainedFiles,1115 src_files: *Cache.Manifest.SelfContainedFiles,
1094 error_bundle: ?*std.zig.ErrorBundle = null,1116 error_bundle: ?*ErrorBundle = null,
1095};1117};
10961118
1097fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {1119fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
...@@ -1402,7 +1424,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {...@@ -1402,7 +1424,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig {
1402 for (fetches) |f| {1424 for (fetches) |f| {
1403 if (!f.have_manifest) continue;1425 if (!f.have_manifest) continue;
1404 if (config_man) |man| {1426 if (config_man) |man| {
1405 const manifest_path = try f.package_root.join(arena, Package.Manifest.basename);1427 const manifest_path = try f.package_root.join(arena, Manifest.basename);
1406 _ = try man.addInputPath(manifest_path, .{});1428 _ = try man.addInputPath(manifest_path, .{});
1407 }1429 }
1408 const mod = f.cli_module orelse continue;1430 const mod = f.cli_module orelse continue;
...@@ -1932,8 +1954,8 @@ fn cmdFetch(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {...@@ -1932,8 +1954,8 @@ fn cmdFetch(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {
1932 try ast.render(gpa, &aw.writer, fixups);1954 try ast.render(gpa, &aw.writer, fixups);
1933 const rendered = aw.written();1955 const rendered = aw.written();
19341956
1935 build_root.directory.handle.writeFile(io, .{ .sub_path = Package.Manifest.basename, .data = rendered }) catch |err| {1957 build_root.directory.handle.writeFile(io, .{ .sub_path = Manifest.basename, .data = rendered }) catch |err| {
1936 fatal("unable to write {s} file: {t}", .{ Package.Manifest.basename, err });1958 fatal("unable to write {s} file: {t}", .{ Manifest.basename, err });
1937 };1959 };
19381960
1939 return process.cleanExit(io);1961 return process.cleanExit(io);
...@@ -2135,7 +2157,7 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {...@@ -2135,7 +2157,7 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {
2135 const s = Dir.path.sep_str;2157 const s = Dir.path.sep_str;
2136 const template_paths = [_][]const u8{2158 const template_paths = [_][]const u8{
2137 default_build_zig_basename,2159 default_build_zig_basename,
2138 Package.Manifest.basename,2160 Manifest.basename,
2139 "src" ++ s ++ "main.zig",2161 "src" ++ s ++ "main.zig",
2140 "src" ++ s ++ "root.zig",2162 "src" ++ s ++ "root.zig",
2141 };2163 };
...@@ -2159,7 +2181,7 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {...@@ -2159,7 +2181,7 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {
2159 return process.cleanExit(io);2181 return process.cleanExit(io);
2160 },2182 },
2161 .minimal => {2183 .minimal => {
2162 Templates.writeSimpleFile(io, Io.Dir.cwd(), Package.Manifest.basename,2184 Templates.writeSimpleFile(io, Io.Dir.cwd(), Manifest.basename,
2163 \\.{{2185 \\.{{
2164 \\ .name = .{s},2186 \\ .name = .{s},
2165 \\ .version = "0.0.1",2187 \\ .version = "0.0.1",
...@@ -2173,8 +2195,8 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {...@@ -2173,8 +2195,8 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {
2173 builtin.zig_version_string,2195 builtin.zig_version_string,
2174 fingerprint.int(),2196 fingerprint.int(),
2175 }) catch |err| switch (err) {2197 }) catch |err| switch (err) {
2176 else => fatal("failed to create {q}: {t}", .{ Package.Manifest.basename, err }),2198 else => fatal("failed to create {q}: {t}", .{ Manifest.basename, err }),
2177 error.PathAlreadyExists => fatal("refusing to overwrite {q}", .{Package.Manifest.basename}),2199 error.PathAlreadyExists => fatal("refusing to overwrite {q}", .{Manifest.basename}),
2178 };2200 };
2179 Templates.writeSimpleFile(io, Io.Dir.cwd(), default_build_zig_basename,2201 Templates.writeSimpleFile(io, Io.Dir.cwd(), default_build_zig_basename,
2180 \\const std = @import("std");2202 \\const std = @import("std");
...@@ -2189,12 +2211,12 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {...@@ -2189,12 +2211,12 @@ fn cmdInit(gpa: Allocator, graph: *Graph, args: []const []const u8) !void {
2189 // their `build.zig.zon` *after* writing their `build.zig`. So this one isn't fatal.2211 // their `build.zig.zon` *after* writing their `build.zig`. So this one isn't fatal.
2190 error.PathAlreadyExists => {2212 error.PathAlreadyExists => {
2191 log.info("successfully populated {q}, preserving existing {q}", .{2213 log.info("successfully populated {q}, preserving existing {q}", .{
2192 Package.Manifest.basename, default_build_zig_basename,2214 Manifest.basename, default_build_zig_basename,
2193 });2215 });
2194 return process.cleanExit(io);2216 return process.cleanExit(io);
2195 },2217 },
2196 };2218 };
2197 log.info("successfully populated {q} and {q}", .{ Package.Manifest.basename, default_build_zig_basename });2219 log.info("successfully populated {q} and {q}", .{ Manifest.basename, default_build_zig_basename });
2198 return process.cleanExit(io);2220 return process.cleanExit(io);
2199 },2221 },
2200 }2222 }
...@@ -3277,7 +3299,7 @@ pub fn invalidateResult(maker: *Maker, step: *Step) error{MustReconfigure}!bool...@@ -3277,7 +3299,7 @@ pub fn invalidateResult(maker: *Maker, step: *Step) error{MustReconfigure}!bool
3277pub fn printErrorMessages(3299pub fn printErrorMessages(
3278 maker: *Maker,3300 maker: *Maker,
3279 failing_step_index: Configuration.Step.Index,3301 failing_step_index: Configuration.Step.Index,
3280 options: std.zig.ErrorBundle.RenderOptions,3302 options: ErrorBundle.RenderOptions,
3281 stderr: Io.Terminal,3303 stderr: Io.Terminal,
3282 error_style: ErrorStyle,3304 error_style: ErrorStyle,
3283 multiline_errors: MultilineErrors,3305 multiline_errors: MultilineErrors,
...@@ -4037,7 +4059,9 @@ const FindBuildRootOptions = struct {...@@ -4037,7 +4059,9 @@ const FindBuildRootOptions = struct {
4037 cwd_path: []const u8,4059 cwd_path: []const u8,
4038};4060};
40394061
4040fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !BuildRoot {4062const FindBuildRootError = error{ OutOfMemory, BuildZigNotFound };
4063
4064fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) FindBuildRootError!BuildRoot {
4041 const build_zig_basename = if (options.build_file) |bf|4065 const build_zig_basename = if (options.build_file) |bf|
4042 Dir.path.basename(bf)4066 Dir.path.basename(bf)
4043 else4067 else
...@@ -4088,11 +4112,12 @@ fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !Build...@@ -4088,11 +4112,12 @@ fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !Build
4088 dirname = Dir.path.dirname(dirname orelse options.cwd_path) orelse {4112 dirname = Dir.path.dirname(dirname orelse options.cwd_path) orelse {
4089 log.info("initialize {s} template file with \"zig init\"", .{std.zig.build_zig_basename});4113 log.info("initialize {s} template file with \"zig init\"", .{std.zig.build_zig_basename});
4090 log.info("see \"zig --help\" for more options", .{});4114 log.info("see \"zig --help\" for more options", .{});
4091 fatal("no build.zig file found, in the current directory or any parent directories", .{});4115 log.err("no build.zig file found, in the current directory or any parent directories", .{});
4116 return error.BuildZigNotFound;
4092 };4117 };
4093 continue;4118 continue;
4094 },4119 },
4095 else => |e| return e,4120 else => |e| fatal("accessing {q} while searching for build.zig file failed: {t}", .{ joined_path, e }),
4096 }4121 }
4097 }4122 }
4098}4123}
...@@ -4100,8 +4125,8 @@ fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !Build...@@ -4100,8 +4125,8 @@ fn findBuildRoot(arena: Allocator, io: Io, options: FindBuildRootOptions) !Build
4100const Fork = struct {4125const Fork = struct {
4101 path: Path,4126 path: Path,
4102 manifest_ast: std.zig.Ast,4127 manifest_ast: std.zig.Ast,
4103 manifest: Package.Manifest,4128 manifest: Manifest,
4104 error_bundle: std.zig.ErrorBundle.Wip,4129 error_bundle: ErrorBundle.Wip,
4105 failed: bool,4130 failed: bool,
4106 arena_allocator: std.heap.ArenaAllocator,4131 arena_allocator: std.heap.ArenaAllocator,
41074132
...@@ -4134,12 +4159,12 @@ const Fork = struct {...@@ -4134,12 +4159,12 @@ const Fork = struct {
4134 fork.arena_allocator = .init(gpa);4159 fork.arena_allocator = .init(gpa);
4135 const arena = fork.arena_allocator.allocator();4160 const arena = fork.arena_allocator.allocator();
41364161
4137 var error_bundle: std.zig.ErrorBundle.Wip = try .init(gpa);4162 var error_bundle: ErrorBundle.Wip = try .init(gpa);
4138 defer error_bundle.deinit();4163 defer error_bundle.deinit();
41394164
4140 const manifest_path = try fork.path.join(arena, Package.Manifest.basename);4165 const manifest_path = try fork.path.join(arena, Manifest.basename);
41414166
4142 Package.Manifest.load(4167 Manifest.load(
4143 io,4168 io,
4144 arena,4169 arena,
4145 manifest_path,4170 manifest_path,
...@@ -4189,20 +4214,20 @@ fn loadManifest(...@@ -4189,20 +4214,20 @@ fn loadManifest(
4189 arena: Allocator,4214 arena: Allocator,
4190 io: Io,4215 io: Io,
4191 options: LoadManifestOptions,4216 options: LoadManifestOptions,
4192) !struct { Package.Manifest, std.zig.Ast } {4217) !struct { Manifest, std.zig.Ast } {
4193 const rng: std.Random.IoSource = .{ .io = io };4218 const rng: std.Random.IoSource = .{ .io = io };
41944219
4195 const manifest_bytes = while (true) {4220 const manifest_bytes = while (true) {
4196 break options.dir.readFileAllocOptions(4221 break options.dir.readFileAllocOptions(
4197 io,4222 io,
4198 Package.Manifest.basename,4223 Manifest.basename,
4199 arena,4224 arena,
4200 .limited(Package.Manifest.max_bytes),4225 .limited(Manifest.max_bytes),
4201 .@"1",4226 .@"1",
4202 0,4227 0,
4203 ) catch |err| switch (err) {4228 ) catch |err| switch (err) {
4204 error.FileNotFound => {4229 error.FileNotFound => {
4205 Templates.writeSimpleFile(io, options.dir, Package.Manifest.basename,4230 Templates.writeSimpleFile(io, options.dir, Manifest.basename,
4206 \\.{{4231 \\.{{
4207 \\ .name = .{s},4232 \\ .name = .{s},
4208 \\ .version = "0.0.1",4233 \\ .version = "0.0.1",
...@@ -4216,29 +4241,29 @@ fn loadManifest(...@@ -4216,29 +4241,29 @@ fn loadManifest(
4216 builtin.zig_version_string,4241 builtin.zig_version_string,
4217 Package.Fingerprint.generate(rng.interface(), options.root_name).int(),4242 Package.Fingerprint.generate(rng.interface(), options.root_name).int(),
4218 }) catch |e| {4243 }) catch |e| {
4219 fatal("unable to write {s}: {t}", .{ Package.Manifest.basename, e });4244 fatal("unable to write {s}: {t}", .{ Manifest.basename, e });
4220 };4245 };
4221 continue;4246 continue;
4222 },4247 },
4223 else => |e| fatal("unable to load {s}: {t}", .{ Package.Manifest.basename, e }),4248 else => |e| fatal("unable to load {s}: {t}", .{ Manifest.basename, e }),
4224 };4249 };
4225 };4250 };
4226 var ast = try std.zig.Ast.parse(gpa, manifest_bytes, .{ .mode = .zon });4251 var ast = try std.zig.Ast.parse(gpa, manifest_bytes, .{ .mode = .zon });
4227 errdefer ast.deinit(gpa);4252 errdefer ast.deinit(gpa);
42284253
4229 if (ast.errors.len > 0) {4254 if (ast.errors.len > 0) {
4230 try std.zig.printAstErrorsToStderr(gpa, io, ast, Package.Manifest.basename, options.color);4255 try std.zig.printAstErrorsToStderr(gpa, io, ast, Manifest.basename, options.color);
4231 process.exit(2);4256 process.exit(2);
4232 }4257 }
42334258
4234 var manifest = try Package.Manifest.parse(gpa, &ast, rng.interface(), .{});4259 var manifest = try Manifest.parse(gpa, &ast, rng.interface(), .{});
4235 errdefer manifest.deinit(gpa);4260 errdefer manifest.deinit(gpa);
42364261
4237 if (manifest.errors.len > 0) {4262 if (manifest.errors.len > 0) {
4238 var wip_errors: std.zig.ErrorBundle.Wip = try .init(gpa);4263 var wip_errors: ErrorBundle.Wip = try .init(gpa);
4239 defer wip_errors.deinit();4264 defer wip_errors.deinit();
42404265
4241 const src_path = try wip_errors.addString(Package.Manifest.basename);4266 const src_path = try wip_errors.addString(Manifest.basename);
4242 try manifest.copyErrorsIntoBundle(ast, src_path, &wip_errors);4267 try manifest.copyErrorsIntoBundle(ast, src_path, &wip_errors);
42434268
4244 var error_bundle = try wip_errors.toOwnedBundle("");4269 var error_bundle = try wip_errors.toOwnedBundle("");
...@@ -4262,8 +4287,8 @@ fn sanitizeExampleName(arena: Allocator, bytes: []const u8) error{OutOfMemory}![...@@ -4262,8 +4287,8 @@ fn sanitizeExampleName(arena: Allocator, bytes: []const u8) error{OutOfMemory}![
4262 else => continue,4287 else => continue,
4263 };4288 };
4264 if (!std.zig.isValidId(result.items)) return "foo";4289 if (!std.zig.isValidId(result.items)) return "foo";
4265 if (result.items.len > Package.Manifest.max_name_len)4290 if (result.items.len > Manifest.max_name_len)
4266 result.shrinkRetainingCapacity(Package.Manifest.max_name_len);4291 result.shrinkRetainingCapacity(Manifest.max_name_len);
42674292
4268 return result.toOwnedSlice(arena);4293 return result.toOwnedSlice(arena);
4269}4294}
lib/compiler/Maker/ScannedConfig.zig+136-119
...@@ -238,6 +238,18 @@ pub fn printSteps(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {...@@ -238,6 +238,18 @@ pub fn printSteps(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {
238 }238 }
239}239}
240240
241pub fn printUsageWithoutConfiguration(zig_exe: []const u8, w: *Writer, reason: []const u8) Writer.Error!void {
242 try w.print(
243 \\Usage: {s} build [steps] [options]
244 \\
245 \\Steps: (unavailable due to {s})
246 \\Project-Specific Options: (unavailable due to {s})
247 \\{s}
248 \\ (unavailable due to {s})
249 \\{s}
250 , .{ zig_exe, reason, reason, system_integration_usage, reason, general_usage });
251}
252
241pub fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {253pub fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {
242 const arena = graph.arena;254 const arena = graph.arena;
243255
...@@ -274,37 +286,7 @@ pub fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {...@@ -274,37 +286,7 @@ pub fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {
274 }286 }
275 }287 }
276288
277 try w.writeAll(289 try w.writeAll(system_integration_usage);
278 \\
279 \\System Integration Options:
280 \\ --search-prefix [path] Add a path to look for binaries, libraries, headers
281 \\ --sysroot [path] Set the system root directory (usually /)
282 \\ --libc [file] Provide a file which specifies libc paths
283 \\
284 \\ --system [pkgdir] Disable package fetching; enable all integrations
285 \\ -fsys=[name] Enable a system integration
286 \\ -fno-sys=[name] Disable a system integration
287 \\
288 \\ -fdarling, -fno-darling Integration with system-installed Darling to
289 \\ execute macOS programs on Linux hosts
290 \\ (default: no)
291 \\ -fqemu, -fno-qemu Integration with system-installed QEMU to execute
292 \\ foreign-architecture programs on Linux hosts
293 \\ (default: no)
294 \\ --libc-runtimes [path] Enhances QEMU integration by providing dynamic libc
295 \\ (e.g. glibc or musl) built for multiple foreign
296 \\ architectures, allowing execution of non-native
297 \\ programs that link with libc.
298 \\ -frosetta, -fno-rosetta Rely on Rosetta to execute x86_64 programs on
299 \\ ARM64 macOS hosts. (default: no)
300 \\ -fwasmtime, -fno-wasmtime Integration with system-installed wasmtime to
301 \\ execute WASI binaries. (default: no)
302 \\ -fwine, -fno-wine Integration with system-installed Wine to execute
303 \\ Windows programs on Linux hosts. (default: no)
304 \\
305 \\ Available System Integrations: Enabled:
306 \\
307 );
308 if (sc.configuration.system_integrations.len == 0) {290 if (sc.configuration.system_integrations.len == 0) {
309 try w.writeAll(" (none) -\n");291 try w.writeAll(" (none) -\n");
310 } else {292 } else {
...@@ -318,92 +300,127 @@ pub fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {...@@ -318,92 +300,127 @@ pub fn printUsage(sc: *const ScannedConfig, graph: *Graph, w: *Writer) !void {
318 }300 }
319 }301 }
320302
321 try w.writeAll(303 try w.writeAll(general_usage);
322 \\304}
323 \\General Options:305
324 \\ -h, --help Print this help to stdout and exit306const system_integration_usage =
325 \\ -l, --list-steps Print available steps to stdout and exit307 \\
326 \\308 \\System Integration Options:
327 \\ -p, --prefix [path] Where to install files (default: zig-out)309 \\ --search-prefix [path] Add a path to look for binaries, libraries, headers
328 \\ --prefix-lib-dir [path] Where to install libraries310 \\ --sysroot [path] Set the system root directory (usually /)
329 \\ --prefix-exe-dir [path] Where to install executables311 \\ --libc [file] Provide a file which specifies libc paths
330 \\ --prefix-include-dir [path] Where to install C header files312 \\
331 \\ --release[=mode] Request release mode, optionally specifying a313 \\ --system [pkgdir] Disable package fetching; enable all integrations
332 \\ preferred optimization mode: fast, safe, small314 \\ -fsys=[name] Enable a system integration
333 \\315 \\ -fno-sys=[name] Disable a system integration
334 \\ --verbose Print commands before executing them316 \\
335 \\ --color [auto|off|on] Enable or disable colored error messages317 \\ -fdarling, -fno-darling Integration with system-installed Darling to
336 \\ --error-style [style] Control how build errors are printed318 \\ execute macOS programs on Linux hosts
337 \\ verbose (Default) Report errors with full context319 \\ (default: no)
338 \\ minimal Report errors after summary, excluding context like command lines320 \\ -fqemu, -fno-qemu Integration with system-installed QEMU to execute
339 \\ verbose_clear Like 'verbose', but clear the terminal at the start of each update321 \\ foreign-architecture programs on Linux hosts
340 \\ minimal_clear Like 'minimal', but clear the terminal at the start of each update322 \\ (default: no)
341 \\ --multiline-errors [style] Control how multi-line error messages are printed323 \\ --libc-runtimes [path] Enhances QEMU integration by providing dynamic libc
342 \\ indent (Default) Indent non-initial lines to align with initial line324 \\ (e.g. glibc or musl) built for multiple foreign
343 \\ newline Include a leading newline so that the error message is on its own lines325 \\ architectures, allowing execution of non-native
344 \\ none Print as usual so the first line is misaligned326 \\ programs that link with libc.
345 \\ --summary [mode] Control the printing of the build summary327 \\ -frosetta, -fno-rosetta Rely on Rosetta to execute x86_64 programs on
346 \\ all Print the build summary in its entirety328 \\ ARM64 macOS hosts. (default: no)
347 \\ new Omit cached steps329 \\ -fwasmtime, -fno-wasmtime Integration with system-installed wasmtime to
348 \\ failures (Default if short-lived) Only print failed steps330 \\ execute WASI binaries. (default: no)
349 \\ line (Default if long-lived) Only print the single-line summary331 \\ -fwine, -fno-wine Integration with system-installed Wine to execute
350 \\ none Do not print the build summary332 \\ Windows programs on Linux hosts. (default: no)
351 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)333 \\
352 \\ --maxrss <bytes> Limit memory usage (default is to use available memory)334 \\ Available System Integrations: Enabled:
353 \\ --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss335 \\
354 \\ --test-timeout <timeout> Limit execution time of unit tests, terminating if exceeded.336;
355 \\ The timeout must include a unit: ns, us, ms, s, m, h337
356 \\ --watch Continuously rebuild when source files are modified338const general_usage =
357 \\ --debounce <ms> Delay before rebuilding after changed file detected339 \\
358 \\ --webui[=ip] Enable the web interface on the given IP address340 \\General Options:
359 \\ --fuzz[=limit] Continuously search for unit test failures with an optional 341 \\ -h, --help Print this help to stdout and exit
360 \\ limit to the max number of iterations. The argument supports342 \\ -l, --list-steps Print available steps to stdout and exit
361 \\ an optional 'K', 'M', or 'G' suffix (e.g. '10K'). Implies343 \\
362 \\ '--webui' when no limit is specified.344 \\ -p, --prefix [path] Where to install files (default: zig-out)
363 \\ --listen=- Enable the build server protocol on stdio345 \\ --prefix-lib-dir [path] Where to install libraries
364 \\ --time-report Force full rebuild and provide detailed information on346 \\ --prefix-exe-dir [path] Where to install executables
365 \\ compilation time of Zig source code (implies '--webui')347 \\ --prefix-include-dir [path] Where to install C header files
366 \\ -fincremental Enable incremental compilation348 \\ --release[=mode] Request release mode, optionally specifying a
367 \\ -fno-incremental Disable incremental compilation349 \\ preferred optimization mode: fast, safe, small
368 \\350 \\
369 \\Package Management Options:351 \\ --verbose Print commands before executing them
370 \\ --fetch[=mode] Fetch dependency tree (optionally choose laziness) and exit352 \\ --color [auto|off|on] Enable or disable colored error messages
371 \\ needed (Default) Lazy dependencies are fetched as needed353 \\ --error-style [style] Control how build errors are printed
372 \\ all Lazy dependencies are always fetched354 \\ verbose (Default) Report errors with full context
373 \\ --fork=[path], --fork [path] Override one or more projects from dependency tree355 \\ minimal Report errors after summary, excluding context like command lines
374 \\356 \\ verbose_clear Like 'verbose', but clear the terminal at the start of each update
375 \\Advanced Options:357 \\ minimal_clear Like 'minimal', but clear the terminal at the start of each update
376 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error358 \\ --multiline-errors [style] Control how multi-line error messages are printed
377 \\ -fno-reference-trace Disable reference trace359 \\ indent (Default) Indent non-initial lines to align with initial line
378 \\ -fallow-so-scripts Allows .so files to be GNU ld scripts360 \\ newline Include a leading newline so that the error message is on its own lines
379 \\ -fno-allow-so-scripts (default) .so files must be ELF files361 \\ none Print as usual so the first line is misaligned
380 \\ --error-limit [num] Set the maximum amount of distinct error values362 \\ --summary [mode] Control the printing of the build summary
381 \\ --build-file [file] Override path to build.zig363 \\ all Print the build summary in its entirety
382 \\ --cache-dir [path] Override path to local Zig cache directory364 \\ new Omit cached steps
383 \\ --zig-lib=[arg] Override path to Zig lib directory365 \\ failures (Default if short-lived) Only print failed steps
384 \\ --seed [integer] For shuffling dependency traversal order (default: random)366 \\ line (Default if long-lived) Only print the single-line summary
385 \\ --cache-poison[=mode] Override configuration caching behavior367 \\ none Do not print the build summary
386 \\ pure (default) Avoid false positive cache hits368 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
387 \\ poisoned Don't cache the configuration369 \\ --maxrss <bytes> Limit memory usage (default is to use available memory)
388 \\ disallowed Panics when cache would be poisoned370 \\ --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss
389 \\ ignored A little poison never hurt anybody371 \\ --test-timeout <timeout> Limit execution time of unit tests, terminating if exceeded.
390 \\ --print-configuration Render configuration as .zon to stdout372 \\ The timeout must include a unit: ns, us, ms, s, m, h
391 \\ --print-configuration-path Print the path to the binary configuration file to stdout373 \\ --watch Continuously rebuild when source files are modified
392 \\ --build-id[=style] At a minor link-time expense, embeds a build ID in binaries374 \\ --debounce <ms> Delay before rebuilding after changed file detected
393 \\ fast 8-byte non-cryptographic hash (COFF, ELF, WASM)375 \\ --webui[=ip] Enable the web interface on the given IP address
394 \\ sha1, tree 20-byte cryptographic hash (ELF, WASM)376 \\ --fuzz[=limit] Continuously search for unit test failures with an optional
395 \\ md5 16-byte cryptographic hash (ELF)377 \\ limit to the max number of iterations. The argument supports
396 \\ uuid 16-byte random UUID (ELF, WASM)378 \\ an optional 'K', 'M', or 'G' suffix (e.g. '10K'). Implies
397 \\ 0x[hexstring] Constant ID, maximum 32 bytes (ELF, WASM)379 \\ '--webui' when no limit is specified.
398 \\ none (default) No build ID380 \\ --listen=- Enable the build server protocol on stdio
399 \\ --debug-log [scope] Enable debugging the compiler381 \\ --time-report Force full rebuild and provide detailed information on
400 \\ --debug-pkg-config Fail if unknown pkg-config flags encountered382 \\ compilation time of Zig source code (implies '--webui')
401 \\ --verbose-link Enable compiler debug output for linking383 \\ -fincremental Enable incremental compilation
402 \\ --verbose-air Enable compiler debug output for Zig AIR384 \\ -fno-incremental Disable incremental compilation
403 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR385 \\
404 \\ --verbose-cimport Enable compiler debug output for C imports386 \\Package Management Options:
405 \\ --verbose-cc Enable compiler debug output for C compilation387 \\ --fetch[=mode] Fetch dependency tree (optionally choose laziness) and exit
406 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features388 \\ needed (Default) Lazy dependencies are fetched as needed
407 \\389 \\ all Lazy dependencies are always fetched
408 );390 \\ --fork=[path], --fork [path] Override one or more projects from dependency tree
391 \\
392 \\Advanced Options:
393 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
394 \\ -fno-reference-trace Disable reference trace
395 \\ -fallow-so-scripts Allows .so files to be GNU ld scripts
396 \\ -fno-allow-so-scripts (default) .so files must be ELF files
397 \\ --error-limit [num] Set the maximum amount of distinct error values
398 \\ --build-file [file] Override path to build.zig
399 \\ --cache-dir [path] Override path to local Zig cache directory
400 \\ --zig-lib=[arg] Override path to Zig lib directory
401 \\ --seed [integer] For shuffling dependency traversal order (default: random)
402 \\ --cache-poison[=mode] Override configuration caching behavior
403 \\ pure (default) Avoid false positive cache hits
404 \\ poisoned Don't cache the configuration
405 \\ disallowed Panics when cache would be poisoned
406 \\ ignored A little poison never hurt anybody
407 \\ --print-configuration Render configuration as .zon to stdout
408 \\ --print-configuration-path Print the path to the binary configuration file to stdout
409 \\ --build-id[=style] At a minor link-time expense, embeds a build ID in binaries
410 \\ fast 8-byte non-cryptographic hash (COFF, ELF, WASM)
411 \\ sha1, tree 20-byte cryptographic hash (ELF, WASM)
412 \\ md5 16-byte cryptographic hash (ELF)
413 \\ uuid 16-byte random UUID (ELF, WASM)
414 \\ 0x[hexstring] Constant ID, maximum 32 bytes (ELF, WASM)
415 \\ none (default) No build ID
416 \\ --debug-log [scope] Enable debugging the compiler
417 \\ --debug-pkg-config Fail if unknown pkg-config flags encountered
418 \\ --verbose-link Enable compiler debug output for linking
419 \\ --verbose-air Enable compiler debug output for Zig AIR
420 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
421 \\ --verbose-cimport Enable compiler debug output for C imports
422 \\ --verbose-cc Enable compiler debug output for C compilation
423 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
424 \\
425;
409}426}