authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 12:51:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:36-07:00
log9eb85c4e5eb65ae987463af33ca24225f12b3a8b
tree4692117790117cd29eb9022b2c195df1ce2e721d
parentea151030bc4a1366ef3ca0bd1f59d4867a215762

build system: track TODOs outside source code

related to #363

10 files changed, 28 insertions(+), 41 deletions(-)

build.zig-2
......@@ -1525,8 +1525,6 @@ fn generateLangRef(b: *std.Build) !std.Build.LazyPath {
15251525 cmd.addArg("--zig");
15261526 cmd.addFileArg(.zig_exe);
15271527
1528 // TODO: enhance doctest to use "--listen=-" rather than operating in a
1529 // temporary directory
15301528 cmd.addArg("--cache-root");
15311529 cmd.addDirectoryArg(.cache_root);
15321530
lib/compiler/Maker.zig+3-5
......@@ -184,7 +184,6 @@ pub fn main(init: process.Init.Minimal) !void {
184184 } else if (mem.eql(u8, arg, "--sysroot")) {
185185 graph.sysroot = nextArgOrFatal(args, &arg_idx);
186186 } else if (mem.eql(u8, arg, "--maxrss")) {
187 // TODO refactor and reuse the fuzz number parsing here
188187 const max_rss_text = nextArgOrFatal(args, &arg_idx);
189188 max_rss = std.fmt.parseIntSizeSuffix(max_rss_text, 10) catch |err|
190189 fatal("invalid byte size {q}: {t}", .{ max_rss_text, err });
......@@ -269,7 +268,6 @@ pub fn main(init: process.Init.Minimal) !void {
269268 graph.build_id = std.zig.BuildId.parse(style) catch |err|
270269 fatal("unable to parse --build-id style {q}: {t}", .{ style, err });
271270 } else if (mem.eql(u8, arg, "--debounce")) {
272 // TODO refactor and reuse the timeout parsing code also here
273271 const next_arg = nextArg(args, &arg_idx) orelse
274272 fatalWithHint("expected u16 after {q}", .{arg});
275273 debounce_interval_ms = std.fmt.parseUnsigned(u16, next_arg, 0) catch |err| {
......@@ -1887,7 +1885,7 @@ pub fn truncatePath(
18871885) Step.ExtendedMakeError!void {
18881886 const graph = maker.graph;
18891887 const io = graph.io;
1890 if (graph.verbose) try graph.handleVerbose(.inherit, null, &.{
1888 if (graph.verbose) try graph.handleVerbose(null, null, &.{
18911889 "truncate", try dest_path.toString(arena),
18921890 });
18931891 const err = e: {
......@@ -1924,7 +1922,7 @@ pub fn installPath(
19241922) Step.ExtendedMakeError!Dir.PrevStatus {
19251923 const graph = maker.graph;
19261924 const io = graph.io;
1927 if (graph.verbose) try graph.handleVerbose(.inherit, null, &.{
1925 if (graph.verbose) try graph.handleVerbose(null, null, &.{
19281926 "install", "-C", try src_path.toString(arena), try dest_path.toString(arena),
19291927 });
19301928 return Dir.updateFile(
......@@ -1949,7 +1947,7 @@ pub fn installDir(
19491947) Step.ExtendedMakeError!Dir.CreatePathStatus {
19501948 const graph = maker.graph;
19511949 const io = graph.io;
1952 if (graph.verbose) try graph.handleVerbose(.inherit, null, &.{
1950 if (graph.verbose) try graph.handleVerbose(null, null, &.{
19531951 "install", "-d", try dest_path.toString(arena),
19541952 });
19551953 return dest_path.root_dir.handle.createDirPathStatus(io, dest_path.sub_path, .default_dir) catch |err| {
lib/compiler/Maker/Graph.zig+1-1
......@@ -69,7 +69,7 @@ enable_rosetta: bool = false,
6969/// before spawning them.
7070pub fn handleVerbose(
7171 graph: *const Graph,
72 cwd: std.process.Child.Cwd,
72 cwd: ?[]const u8,
7373 opt_env: ?*const std.process.Environ.Map,
7474 argv: []const []const u8,
7575) error{OutOfMemory}!void {
lib/compiler/Maker/Step.zig+2-2
......@@ -341,7 +341,7 @@ pub fn captureChildProcess(s: *Step, maker: *Maker, options: CaptureChildProcess
341341 s.result_failed_command = try std.zig.allocPrintCmd(gpa, options.argv, .{});
342342
343343 try handleChildProcUnsupported(s, maker);
344 try graph.handleVerbose(.inherit, null, options.argv);
344 try graph.handleVerbose(null, null, options.argv);
345345
346346 const result = std.process.run(arena, io, .{
347347 .argv = options.argv,
......@@ -459,7 +459,7 @@ pub fn evalZigProcess(
459459 assert(argv.len != 0);
460460
461461 try handleChildProcUnsupported(s, maker);
462 try graph.handleVerbose(.inherit, null, argv);
462 try graph.handleVerbose(null, null, argv);
463463
464464 const zp = try gpa.create(ZigProcess);
465465 defer if (!watch) gpa.destroy(zp);
lib/compiler/Maker/Step/InstallDir.zig-1
......@@ -81,7 +81,6 @@ pub fn make(
8181 .file => {
8282 for (blank_extensions) |ext| {
8383 if (endsWith(u8, entry.path, ext.slice(conf))) {
84 // TODO check if the file was already there and length 0
8584 try maker.truncatePath(arena, dest_path, step_index);
8685 continue :next_entry;
8786 }
lib/compiler/Maker/Step/Run.zig+12-8
......@@ -1796,7 +1796,12 @@ fn runCommand(
17961796 }
17971797 }
17981798
1799 try graph.handleVerbose(cwd, environ_map, argv);
1799 const cwd_string = switch (cwd) {
1800 .path => |p| p,
1801 .dir => unreachable,
1802 .inherit => null,
1803 };
1804 try graph.handleVerbose(cwd_string, environ_map, argv);
18001805
18011806 const opt_generic_result = spawnChildAndCollect(
18021807 run_index,
......@@ -1812,10 +1817,6 @@ fn runCommand(
18121817 error.InvalidExe, // cpu arch mismatch
18131818 error.FileNotFound, // can happen with a wrong dynamic linker path
18141819 => interpret: {
1815 // TODO: learn the target from the binary directly rather than from
1816 // relying on it being a Compile step. This will make this logic
1817 // work even for the edge case that the binary was produced by a
1818 // third party.
18191820 const producer_index = arg0.producer.value orelse break :interpret;
18201821 const producer_step = producer_index.ptr(conf);
18211822 const producer = producer_step.extended.get(conf.extra).compile;
......@@ -1829,7 +1830,6 @@ fn runCommand(
18291830 const root_target = std.zig.system.resolveTargetQuery(io, other_target_query) catch unreachable;
18301831 const link_libc = maker.stepByIndex(producer_index).extended.compile.is_linking_libc;
18311832
1832 // TODO get this from the parent process instead
18331833 const host: std.Target = std.zig.system.resolveTargetQuery(io, .{}) catch |he| switch (he) {
18341834 error.Canceled => |e| return e,
18351835 else => builtin.target,
......@@ -1941,7 +1941,7 @@ fn runCommand(
19411941
19421942 gpa.free(step.result_failed_command.?);
19431943 step.result_failed_command = null;
1944 try graph.handleVerbose(cwd, environ_map, interp_argv.items);
1944 try graph.handleVerbose(cwd_string, environ_map, interp_argv.items);
19451945
19461946 break :term spawnChildAndCollect(
19471947 run_index,
......@@ -2148,7 +2148,11 @@ fn spawnChildAndCollect(
21482148 // If an error occurs, it's caused by this command:
21492149 assert(step.result_failed_command == null);
21502150 step.result_failed_command = try std.zig.allocPrintCmd(gpa, argv, .{
2151 .cwd = child_cwd,
2151 .cwd = switch (child_cwd) {
2152 .path => |p| p,
2153 .dir => unreachable,
2154 .inherit => null,
2155 },
21522156 .child_env = environ_map,
21532157 .parent_env = &graph.environ_map,
21542158 });
lib/compiler/Maker/WebServer.zig-14
......@@ -225,7 +225,6 @@ pub fn updateStepStatus(
225225) void {
226226 const maker = ws.maker;
227227 const all_steps = maker.step_stack.keys();
228 // TODO don't do linear search, especially in a hot loop like this
229228 const step_idx: u32 = for (all_steps, 0..) |s, i| {
230229 if (s == step_index) break @intCast(i);
231230 } else unreachable;
......@@ -569,16 +568,6 @@ pub fn serveTarFile(ws: *WebServer, request: *http.Server.Request, paths: []cons
569568 var read_buffer: [1024]u8 = undefined;
570569 var file_reader: Io.File.Reader = .initSize(file, io, &read_buffer, stat.size);
571570
572 // TODO: this logic is completely bogus -- obviously so, because `path.root_dir.path` can
573 // be cwd-relative. This is also related to why linkification doesn't work in the fuzzer UI:
574 // it turns out the WASM treats the first path component as the module name, typically
575 // resulting in modules named "" and "src". The compiler needs to tell the build system
576 // about the module graph so that the build system can correctly encode this information in
577 // the tar file.
578 //
579 // Additionally, this needs to ensure that all path separators for both prefix and
580 // sub_path are using the POSIX-style `/` on platforms that don't use it as their native
581 // path separator.
582571 archiver.prefix = path.root_dir.path orelse graph.cache.cwd;
583572 try archiver.writeFile(path.sub_path, &file_reader, @intCast(stat.mtime.toSeconds()));
584573 }
......@@ -799,7 +788,6 @@ pub fn updateTimeReportCompile(ws: *WebServer, opts: struct {
799788 const io = maker.graph.io;
800789 const all_steps = maker.step_stack.keys();
801790
802 // TODO don't do linear search
803791 const step_idx: u32 = for (all_steps, 0..) |s, i| {
804792 if (s == opts.compile_step) break @intCast(i);
805793 } else unreachable;
......@@ -843,7 +831,6 @@ pub fn updateTimeReportGeneric(ws: *WebServer, step_index: Configuration.Step.In
843831 const io = maker.graph.io;
844832 const all_steps = maker.step_stack.keys();
845833
846 // TODO don't do linear search
847834 const step_idx: u32 = for (all_steps, 0..) |s, i| {
848835 if (s == step_index) break @intCast(i);
849836 } else unreachable;
......@@ -882,7 +869,6 @@ pub fn updateTimeReportRunTest(
882869 const io = maker.graph.io;
883870 const all_steps = maker.step_stack.keys();
884871
885 // TODO don't do linear search
886872 const step_idx: u32 = for (all_steps, 0..) |s, i| {
887873 if (s == run_step_index) break @intCast(i);
888874 } else unreachable;
lib/std/Build.zig+5-1
......@@ -1890,7 +1890,11 @@ pub fn runFallible(b: *Build, argv: []const []const u8, options: RunOptions) Run
18901890 const arena = graph.arena;
18911891
18921892 const print_opts: std.zig.AllocPrintCmdOptions = .{
1893 .cwd = options.cwd,
1893 .cwd = switch (options.cwd) {
1894 .inherit => null,
1895 .path => |p| p,
1896 .dir => null, // Unknown without changing function signature of runFallible.
1897 },
18941898 .child_env = options.environ_map,
18951899 .parent_env = &graph.environ_map,
18961900 };
lib/std/Build/Configuration.zig+2-2
......@@ -3099,7 +3099,7 @@ pub const Storage = enum {
30993099 .value = if (match) dataField(buffer, i, container, Field.Value) else null,
31003100 };
31013101 },
3102 .extended => @compileError("TODO"),
3102 .extended => @compileError("unimplemented"),
31033103 .length_prefixed_list => {
31043104 const n = @divExact(@sizeOf(Field.Elem), @sizeOf(u32));
31053105 const data_start = i.* + 1;
......@@ -3260,7 +3260,7 @@ pub const Storage = enum {
32603260 .flag_union => return switch (value.u) {
32613261 inline else => |x| setExtraField(buffer, i, @TypeOf(x), x),
32623262 },
3263 .extended => @compileError("TODO"),
3263 .extended => @compileError("unimplemented"),
32643264 .flag_length_prefixed_list => {
32653265 const len: u32 = @intCast(value.slice.len);
32663266 if (len == 0) return 0; // Flag bit hides the length prefix.
lib/std/zig.zig+3-5
......@@ -1168,7 +1168,7 @@ pub const ClangCliParam = struct {
11681168};
11691169
11701170pub const AllocPrintCmdOptions = struct {
1171 cwd: std.process.Child.Cwd = .inherit,
1171 cwd: ?[]const u8 = null,
11721172 parent_env: ?*const std.process.Environ.Map = null,
11731173 child_env: ?*const std.process.Environ.Map = null,
11741174};
......@@ -1212,10 +1212,8 @@ pub fn allocPrintCmd(gpa: Allocator, argv: []const []const u8, options: AllocPri
12121212 var aw: Io.Writer.Allocating = .init(gpa);
12131213 defer aw.deinit();
12141214 const writer = &aw.writer;
1215 switch (options.cwd) {
1216 .inherit => {},
1217 .path => |path| writer.print("cd {s} && ", .{path}) catch return error.OutOfMemory,
1218 .dir => @panic("TODO"),
1215 if (options.cwd) |path| {
1216 writer.print("cd {s} && ", .{path}) catch return error.OutOfMemory;
12191217 }
12201218 if (options.child_env) |child_env| {
12211219 for (child_env.keys(), child_env.values()) |key, value| {