authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-06-17 01:04:57-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-06-17 01:04:57-04:00
logfda2458f6ac9c4f5ddc7d0fb70ab6194ce1adc47
tree8bf0091d50ad426e800e3a1ce69136fd9a6ec4f0
parent2c373b0fb6e9f37919115d53c110070be9ccb401
parentcb1d1bdf59f2979de9c534c21813d824f9736cfb
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20321 from ziglang/build-system-fmt

enhance `std.Build.Step.Fmt` and use it more

9 files changed, 43 insertions(+), 50 deletions(-)

build.zig+5-5
...@@ -428,18 +428,21 @@ pub fn build(b: *std.Build) !void {...@@ -428,18 +428,21 @@ pub fn build(b: *std.Build) !void {
428 }428 }
429 const optimization_modes = chosen_opt_modes_buf[0..chosen_mode_index];429 const optimization_modes = chosen_opt_modes_buf[0..chosen_mode_index];
430430
431 const fmt_include_paths = &.{ "doc", "lib", "src", "test", "tools", "build.zig" };431 const fmt_include_paths = &.{ "lib", "src", "test", "tools", "build.zig", "build.zig.zon" };
432 const fmt_exclude_paths = &.{"test/cases"};432 const fmt_exclude_paths = &.{"test/cases"};
433 const do_fmt = b.addFmt(.{433 const do_fmt = b.addFmt(.{
434 .paths = fmt_include_paths,434 .paths = fmt_include_paths,
435 .exclude_paths = fmt_exclude_paths,435 .exclude_paths = fmt_exclude_paths,
436 });436 });
437 b.step("fmt", "Modify source files in place to have conforming formatting").dependOn(&do_fmt.step);
437438
438 b.step("test-fmt", "Check source files having conforming formatting").dependOn(&b.addFmt(.{439 const check_fmt = b.step("test-fmt", "Check source files having conforming formatting");
440 check_fmt.dependOn(&b.addFmt(.{
439 .paths = fmt_include_paths,441 .paths = fmt_include_paths,
440 .exclude_paths = fmt_exclude_paths,442 .exclude_paths = fmt_exclude_paths,
441 .check = true,443 .check = true,
442 }).step);444 }).step);
445 test_step.dependOn(check_fmt);
443446
444 const test_cases_step = b.step("test-cases", "Run the main compiler test cases");447 const test_cases_step = b.step("test-cases", "Run the main compiler test cases");
445 try tests.addCases(b, test_cases_step, test_filters, check_case_exe, target, .{448 try tests.addCases(b, test_cases_step, test_filters, check_case_exe, target, .{
...@@ -534,9 +537,6 @@ pub fn build(b: *std.Build) !void {...@@ -534,9 +537,6 @@ pub fn build(b: *std.Build) !void {
534537
535 try addWasiUpdateStep(b, version);538 try addWasiUpdateStep(b, version);
536539
537 b.step("fmt", "Modify source files in place to have conforming formatting")
538 .dependOn(&do_fmt.step);
539
540 const update_mingw_step = b.step("update-mingw", "Update zig's bundled mingw");540 const update_mingw_step = b.step("update-mingw", "Update zig's bundled mingw");
541 const opt_mingw_src_path = b.option([]const u8, "mingw-src", "path to mingw-w64 source directory");541 const opt_mingw_src_path = b.option([]const u8, "mingw-src", "path to mingw-w64 source directory");
542 const update_mingw_exe = b.addExecutable(.{542 const update_mingw_exe = b.addExecutable(.{
ci/aarch64-linux-debug.sh-7
...@@ -49,13 +49,6 @@ unset CXX...@@ -49,13 +49,6 @@ unset CXX
4949
50ninja install50ninja install
5151
52# TODO: move this to a build.zig step (check-fmt)
53echo "Looking for non-conforming code formatting..."
54stage3-debug/bin/zig fmt --check .. \
55 --exclude ../test/cases/ \
56 --exclude ../doc/ \
57 --exclude ../build-debug
58
59# simultaneously test building self-hosted without LLVM and with 32-bit arm52# simultaneously test building self-hosted without LLVM and with 32-bit arm
60stage3-debug/bin/zig build \53stage3-debug/bin/zig build \
61 -Dtarget=arm-linux-musleabihf \54 -Dtarget=arm-linux-musleabihf \
ci/aarch64-linux-release.sh-7
...@@ -49,13 +49,6 @@ unset CXX...@@ -49,13 +49,6 @@ unset CXX
4949
50ninja install50ninja install
5151
52# TODO: move this to a build.zig step (check-fmt)
53echo "Looking for non-conforming code formatting..."
54stage3-release/bin/zig fmt --check .. \
55 --exclude ../test/cases/ \
56 --exclude ../doc/ \
57 --exclude ../build-release
58
59# simultaneously test building self-hosted without LLVM and with 32-bit arm52# simultaneously test building self-hosted without LLVM and with 32-bit arm
60stage3-release/bin/zig build \53stage3-release/bin/zig build \
61 -Dtarget=arm-linux-musleabihf \54 -Dtarget=arm-linux-musleabihf \
ci/x86_64-linux-debug.sh-7
...@@ -57,13 +57,6 @@ unset CXX...@@ -57,13 +57,6 @@ unset CXX
5757
58ninja install58ninja install
5959
60# TODO: move this to a build.zig step (check-fmt)
61echo "Looking for non-conforming code formatting..."
62stage3-debug/bin/zig fmt --check .. \
63 --exclude ../test/cases/ \
64 --exclude ../doc/ \
65 --exclude ../build-debug
66
67# simultaneously test building self-hosted without LLVM and with 32-bit arm60# simultaneously test building self-hosted without LLVM and with 32-bit arm
68stage3-debug/bin/zig build \61stage3-debug/bin/zig build \
69 -Dtarget=arm-linux-musleabihf \62 -Dtarget=arm-linux-musleabihf \
ci/x86_64-linux-release.sh-8
...@@ -57,14 +57,6 @@ unset CXX...@@ -57,14 +57,6 @@ unset CXX
5757
58ninja install58ninja install
5959
60# TODO: move this to a build.zig step (check-fmt)
61echo "Looking for non-conforming code formatting..."
62stage3-release/bin/zig fmt --check .. \
63 --exclude ../test/cases/ \
64 --exclude ../doc/ \
65 --exclude ../build-debug \
66 --exclude ../build-release
67
68# simultaneously test building self-hosted without LLVM and with 32-bit arm60# simultaneously test building self-hosted without LLVM and with 32-bit arm
69stage3-release/bin/zig build \61stage3-release/bin/zig build \
70 -Dtarget=arm-linux-musleabihf \62 -Dtarget=arm-linux-musleabihf \
lib/std/Build/Step.zig+13-2
...@@ -272,7 +272,17 @@ const Allocator = std.mem.Allocator;...@@ -272,7 +272,17 @@ const Allocator = std.mem.Allocator;
272const assert = std.debug.assert;272const assert = std.debug.assert;
273const builtin = @import("builtin");273const builtin = @import("builtin");
274274
275pub fn evalChildProcess(s: *Step, argv: []const []const u8) !void {275pub fn evalChildProcess(s: *Step, argv: []const []const u8) ![]u8 {
276 const run_result = try captureChildProcess(s, std.Progress.Node.none, argv);
277 try handleChildProcessTerm(s, run_result.term, null, argv);
278 return run_result.stdout;
279}
280
281pub fn captureChildProcess(
282 s: *Step,
283 progress_node: std.Progress.Node,
284 argv: []const []const u8,
285) !std.process.Child.RunResult {
276 const arena = s.owner.allocator;286 const arena = s.owner.allocator;
277287
278 try handleChildProcUnsupported(s, null, argv);288 try handleChildProcUnsupported(s, null, argv);
...@@ -281,13 +291,14 @@ pub fn evalChildProcess(s: *Step, argv: []const []const u8) !void {...@@ -281,13 +291,14 @@ pub fn evalChildProcess(s: *Step, argv: []const []const u8) !void {
281 const result = std.process.Child.run(.{291 const result = std.process.Child.run(.{
282 .allocator = arena,292 .allocator = arena,
283 .argv = argv,293 .argv = argv,
294 .progress_node = progress_node,
284 }) catch |err| return s.fail("unable to spawn {s}: {s}", .{ argv[0], @errorName(err) });295 }) catch |err| return s.fail("unable to spawn {s}: {s}", .{ argv[0], @errorName(err) });
285296
286 if (result.stderr.len > 0) {297 if (result.stderr.len > 0) {
287 try s.result_error_msgs.append(arena, result.stderr);298 try s.result_error_msgs.append(arena, result.stderr);
288 }299 }
289300
290 try handleChildProcessTerm(s, result.term, null, argv);301 return result;
291}302}
292303
293pub fn fail(step: *Step, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, MakeFailed } {304pub fn fail(step: *Step, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, MakeFailed } {
lib/std/Build/Step/Fmt.zig+11-4
...@@ -37,9 +37,6 @@ pub fn create(owner: *std.Build, options: Options) *Fmt {...@@ -37,9 +37,6 @@ pub fn create(owner: *std.Build, options: Options) *Fmt {
37}37}
3838
39fn make(step: *Step, prog_node: std.Progress.Node) !void {39fn make(step: *Step, prog_node: std.Progress.Node) !void {
40 // zig fmt is fast enough that no progress is needed.
41 _ = prog_node;
42
43 // TODO: if check=false, this means we are modifying source files in place, which40 // TODO: if check=false, this means we are modifying source files in place, which
44 // is an operation that could race against other operations also modifying source files41 // is an operation that could race against other operations also modifying source files
45 // in place. In this case, this step should obtain a write lock while making those42 // in place. In this case, this step should obtain a write lock while making those
...@@ -68,5 +65,15 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void {...@@ -68,5 +65,15 @@ fn make(step: *Step, prog_node: std.Progress.Node) !void {
68 argv.appendAssumeCapacity(b.pathFromRoot(p));65 argv.appendAssumeCapacity(b.pathFromRoot(p));
69 }66 }
7067
71 return step.evalChildProcess(argv.items);68 const run_result = try step.captureChildProcess(prog_node, argv.items);
69 if (fmt.check) switch (run_result.term) {
70 .Exited => |code| if (code != 0 and run_result.stdout.len != 0) {
71 var it = std.mem.tokenizeScalar(u8, run_result.stdout, '\n');
72 while (it.next()) |bad_file_name| {
73 try step.addError("{s}: non-conforming formatting", .{bad_file_name});
74 }
75 },
76 else => {},
77 };
78 try step.handleChildProcessTerm(run_result.term, null, argv.items);
72}79}
lib/std/Progress.zig+11-9
...@@ -80,6 +80,8 @@ pub const Options = struct {...@@ -80,6 +80,8 @@ pub const Options = struct {
80pub const Node = struct {80pub const Node = struct {
81 index: OptionalIndex,81 index: OptionalIndex,
8282
83 pub const none: Node = .{ .index = .none };
84
83 pub const max_name_len = 40;85 pub const max_name_len = 40;
8486
85 const Storage = extern struct {87 const Storage = extern struct {
...@@ -177,9 +179,9 @@ pub const Node = struct {...@@ -177,9 +179,9 @@ pub const Node = struct {
177 pub fn start(node: Node, name: []const u8, estimated_total_items: usize) Node {179 pub fn start(node: Node, name: []const u8, estimated_total_items: usize) Node {
178 if (noop_impl) {180 if (noop_impl) {
179 assert(node.index == .none);181 assert(node.index == .none);
180 return .{ .index = .none };182 return Node.none;
181 }183 }
182 const node_index = node.index.unwrap() orelse return .{ .index = .none };184 const node_index = node.index.unwrap() orelse return Node.none;
183 const parent = node_index.toParent();185 const parent = node_index.toParent();
184186
185 const freelist_head = &global_progress.node_freelist_first;187 const freelist_head = &global_progress.node_freelist_first;
...@@ -196,7 +198,7 @@ pub const Node = struct {...@@ -196,7 +198,7 @@ pub const Node = struct {
196 if (free_index >= global_progress.node_storage.len) {198 if (free_index >= global_progress.node_storage.len) {
197 // Ran out of node storage memory. Progress for this node will not be tracked.199 // Ran out of node storage memory. Progress for this node will not be tracked.
198 _ = @atomicRmw(u32, &global_progress.node_end_index, .Sub, 1, .monotonic);200 _ = @atomicRmw(u32, &global_progress.node_end_index, .Sub, 1, .monotonic);
199 return .{ .index = .none };201 return Node.none;
200 }202 }
201203
202 return init(@enumFromInt(free_index), parent, name, estimated_total_items);204 return init(@enumFromInt(free_index), parent, name, estimated_total_items);
...@@ -357,7 +359,7 @@ pub fn start(options: Options) Node {...@@ -357,7 +359,7 @@ pub fn start(options: Options) Node {
357 global_progress.initial_delay_ns = options.initial_delay_ns;359 global_progress.initial_delay_ns = options.initial_delay_ns;
358360
359 if (noop_impl)361 if (noop_impl)
360 return .{ .index = .none };362 return Node.none;
361363
362 if (std.process.parseEnvVarInt("ZIG_PROGRESS", u31, 10)) |ipc_fd| {364 if (std.process.parseEnvVarInt("ZIG_PROGRESS", u31, 10)) |ipc_fd| {
363 global_progress.update_thread = std.Thread.spawn(.{}, ipcThreadRun, .{365 global_progress.update_thread = std.Thread.spawn(.{}, ipcThreadRun, .{
...@@ -368,12 +370,12 @@ pub fn start(options: Options) Node {...@@ -368,12 +370,12 @@ pub fn start(options: Options) Node {
368 }),370 }),
369 }) catch |err| {371 }) catch |err| {
370 std.log.warn("failed to spawn IPC thread for communicating progress to parent: {s}", .{@errorName(err)});372 std.log.warn("failed to spawn IPC thread for communicating progress to parent: {s}", .{@errorName(err)});
371 return .{ .index = .none };373 return Node.none;
372 };374 };
373 } else |env_err| switch (env_err) {375 } else |env_err| switch (env_err) {
374 error.EnvironmentVariableNotFound => {376 error.EnvironmentVariableNotFound => {
375 if (options.disable_printing) {377 if (options.disable_printing) {
376 return .{ .index = .none };378 return Node.none;
377 }379 }
378 const stderr = std.io.getStdErr();380 const stderr = std.io.getStdErr();
379 global_progress.terminal = stderr;381 global_progress.terminal = stderr;
...@@ -386,7 +388,7 @@ pub fn start(options: Options) Node {...@@ -386,7 +388,7 @@ pub fn start(options: Options) Node {
386 }388 }
387389
388 if (global_progress.terminal_mode == .off) {390 if (global_progress.terminal_mode == .off) {
389 return .{ .index = .none };391 return Node.none;
390 }392 }
391393
392 if (have_sigwinch) {394 if (have_sigwinch) {
...@@ -408,12 +410,12 @@ pub fn start(options: Options) Node {...@@ -408,12 +410,12 @@ pub fn start(options: Options) Node {
408 global_progress.update_thread = thread;410 global_progress.update_thread = thread;
409 } else |err| {411 } else |err| {
410 std.log.warn("unable to spawn thread for printing progress to terminal: {s}", .{@errorName(err)});412 std.log.warn("unable to spawn thread for printing progress to terminal: {s}", .{@errorName(err)});
411 return .{ .index = .none };413 return Node.none;
412 }414 }
413 },415 },
414 else => |e| {416 else => |e| {
415 std.log.warn("invalid ZIG_PROGRESS file descriptor integer: {s}", .{@errorName(e)});417 std.log.warn("invalid ZIG_PROGRESS file descriptor integer: {s}", .{@errorName(e)});
416 return .{ .index = .none };418 return Node.none;
417 },419 },
418 }420 }
419421
lib/std/process/Child.zig+3-1
...@@ -101,7 +101,7 @@ resource_usage_statistics: ResourceUsageStatistics = .{},...@@ -101,7 +101,7 @@ resource_usage_statistics: ResourceUsageStatistics = .{},
101///101///
102/// The child's progress tree will be grafted into the parent's progress tree,102/// The child's progress tree will be grafted into the parent's progress tree,
103/// by substituting this node with the child's root node.103/// by substituting this node with the child's root node.
104progress_node: std.Progress.Node = .{ .index = .none },104progress_node: std.Progress.Node = std.Progress.Node.none,
105105
106pub const ResourceUsageStatistics = struct {106pub const ResourceUsageStatistics = struct {
107 rusage: @TypeOf(rusage_init) = rusage_init,107 rusage: @TypeOf(rusage_init) = rusage_init,
...@@ -376,6 +376,7 @@ pub fn run(args: struct {...@@ -376,6 +376,7 @@ pub fn run(args: struct {
376 env_map: ?*const EnvMap = null,376 env_map: ?*const EnvMap = null,
377 max_output_bytes: usize = 50 * 1024,377 max_output_bytes: usize = 50 * 1024,
378 expand_arg0: Arg0Expand = .no_expand,378 expand_arg0: Arg0Expand = .no_expand,
379 progress_node: std.Progress.Node = std.Progress.Node.none,
379}) RunError!RunResult {380}) RunError!RunResult {
380 var child = ChildProcess.init(args.argv, args.allocator);381 var child = ChildProcess.init(args.argv, args.allocator);
381 child.stdin_behavior = .Ignore;382 child.stdin_behavior = .Ignore;
...@@ -385,6 +386,7 @@ pub fn run(args: struct {...@@ -385,6 +386,7 @@ pub fn run(args: struct {
385 child.cwd_dir = args.cwd_dir;386 child.cwd_dir = args.cwd_dir;
386 child.env_map = args.env_map;387 child.env_map = args.env_map;
387 child.expand_arg0 = args.expand_arg0;388 child.expand_arg0 = args.expand_arg0;
389 child.progress_node = args.progress_node;
388390
389 var stdout = std.ArrayList(u8).init(args.allocator);391 var stdout = std.ArrayList(u8).init(args.allocator);
390 var stderr = std.ArrayList(u8).init(args.allocator);392 var stderr = std.ArrayList(u8).init(args.allocator);