authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-17 18:17:49-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:35-07:00
log9709efce98289f393ae496921ba30123ea6123f5
treeb8f3e0f8fe1abfed0a50153d9f399b1c6e6b3748
parente2dbf6f48ffe09b01c701887b8eb77b326cfe7b2

std.Build.Step.Run: introduce Arg.cc_args

provides a way for the build system to append -target and -isystem/-I flags to a Run step. needed by translate-c package to avoid doing naughty stuff in the configure phase.

6 files changed, 132 insertions(+), 29 deletions(-)

BRANCH_TODO+3
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1* double check when targets get resolved (should be at configure time)
1* pass overridden pkg-dir to maker2* pass overridden pkg-dir to maker
2* finish migrating the rest of the build steps3* finish migrating the rest of the build steps
3* inspect b4ffb402c082605c4b324e88120306fc8fb3cf32 diff and apply changes as needed (merge conflict)4* inspect b4ffb402c082605c4b324e88120306fc8fb3cf32 diff and apply changes as needed (merge conflict)
...@@ -7,6 +8,7 @@...@@ -7,6 +8,7 @@
7* solve the TODOs added in this branch8* solve the TODOs added in this branch
8* get zig tests passing9* get zig tests passing
9* test a bunch of third party projects / help people migrate10* test a bunch of third party projects / help people migrate
11 * tetris
1012
11* get the target from the parent process instead13* get the target from the parent process instead
12* [handle missing cache hits when chaining two run steps](https://codeberg.org/ziglang/zig/pulls/30762)14* [handle missing cache hits when chaining two run steps](https://codeberg.org/ziglang/zig/pulls/30762)
...@@ -80,6 +82,7 @@ closes #31397...@@ -80,6 +82,7 @@ closes #31397
8082
81* `b.build_root` (Directory) -> `b.root` (Path)83* `b.build_root` (Directory) -> `b.root` (Path)
82* `ConfigHeader.Options`: `include_guard_override` -> `include_guard`84* `ConfigHeader.Options`: `include_guard_override` -> `include_guard`
85* `LazyPath`: `getDisplayName` -> `format` or `fmt`
8386
84### Perf Data Point: `zig build -h` (cached)87### Perf Data Point: `zig build -h` (cached)
8588
lib/compiler/Maker/Step/Run.zig+3
...@@ -184,6 +184,9 @@ pub fn make(...@@ -184,6 +184,9 @@ pub fn make(
184 man.hash.addListOfBytes(run_args);184 man.hash.addListOfBytes(run_args);
185 }185 }
186 },186 },
187 .cc_args => {
188 @panic("TODO Run make cc_args");
189 },
187 }190 }
188 }191 }
189192
lib/compiler/configurer.zig+46-1
...@@ -312,6 +312,8 @@ const Serialize = struct {...@@ -312,6 +312,8 @@ const Serialize = struct {
312 .producer = true,312 .producer = true,
313 .generated = false,313 .generated = false,
314 .dep_file = false,314 .dep_file = false,
315 .target_query = false,
316 .link_libc = false,
315 },317 },
316 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },318 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },
317 .suffix = .{ .value = null },319 .suffix = .{ .value = null },
...@@ -319,6 +321,7 @@ const Serialize = struct {...@@ -319,6 +321,7 @@ const Serialize = struct {
319 .path = .{ .value = null },321 .path = .{ .value = null },
320 .producer = .{ .value = stepIndex(s, &a.artifact.step) },322 .producer = .{ .value = stepIndex(s, &a.artifact.step) },
321 .generated = .{ .value = null },323 .generated = .{ .value = null },
324 .target_query = .{ .value = null },
322 },325 },
323 .lazy_path => |a| .{326 .lazy_path => |a| .{
324 .flags = .{327 .flags = .{
...@@ -330,6 +333,8 @@ const Serialize = struct {...@@ -330,6 +333,8 @@ const Serialize = struct {
330 .producer = false,333 .producer = false,
331 .generated = false,334 .generated = false,
332 .dep_file = false,335 .dep_file = false,
336 .target_query = false,
337 .link_libc = false,
333 },338 },
334 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },339 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },
335 .suffix = .{ .value = null },340 .suffix = .{ .value = null },
...@@ -337,6 +342,7 @@ const Serialize = struct {...@@ -337,6 +342,7 @@ const Serialize = struct {
337 .path = .{ .value = try addLazyPath(s, a.lazy_path) },342 .path = .{ .value = try addLazyPath(s, a.lazy_path) },
338 .producer = .{ .value = null },343 .producer = .{ .value = null },
339 .generated = .{ .value = null },344 .generated = .{ .value = null },
345 .target_query = .{ .value = null },
340 },346 },
341 .decorated_directory => |a| .{347 .decorated_directory => |a| .{
342 .flags = .{348 .flags = .{
...@@ -348,6 +354,8 @@ const Serialize = struct {...@@ -348,6 +354,8 @@ const Serialize = struct {
348 .producer = false,354 .producer = false,
349 .generated = false,355 .generated = false,
350 .dep_file = false,356 .dep_file = false,
357 .target_query = false,
358 .link_libc = false,
351 },359 },
352 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },360 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },
353 .suffix = .{ .value = try addOptionalString(s, a.suffix) },361 .suffix = .{ .value = try addOptionalString(s, a.suffix) },
...@@ -355,6 +363,7 @@ const Serialize = struct {...@@ -355,6 +363,7 @@ const Serialize = struct {
355 .path = .{ .value = try addLazyPath(s, a.lazy_path) },363 .path = .{ .value = try addLazyPath(s, a.lazy_path) },
356 .producer = .{ .value = null },364 .producer = .{ .value = null },
357 .generated = .{ .value = null },365 .generated = .{ .value = null },
366 .target_query = .{ .value = null },
358 },367 },
359 .file_content => |a| .{368 .file_content => |a| .{
360 .flags = .{369 .flags = .{
...@@ -366,6 +375,8 @@ const Serialize = struct {...@@ -366,6 +375,8 @@ const Serialize = struct {
366 .producer = false,375 .producer = false,
367 .generated = false,376 .generated = false,
368 .dep_file = false,377 .dep_file = false,
378 .target_query = false,
379 .link_libc = false,
369 },380 },
370 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },381 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },
371 .suffix = .{ .value = null },382 .suffix = .{ .value = null },
...@@ -373,6 +384,7 @@ const Serialize = struct {...@@ -373,6 +384,7 @@ const Serialize = struct {
373 .path = .{ .value = try addLazyPath(s, a.lazy_path) },384 .path = .{ .value = try addLazyPath(s, a.lazy_path) },
374 .producer = .{ .value = null },385 .producer = .{ .value = null },
375 .generated = .{ .value = null },386 .generated = .{ .value = null },
387 .target_query = .{ .value = null },
376 },388 },
377 .bytes => |a| .{389 .bytes => |a| .{
378 .flags = .{390 .flags = .{
...@@ -384,6 +396,8 @@ const Serialize = struct {...@@ -384,6 +396,8 @@ const Serialize = struct {
384 .producer = false,396 .producer = false,
385 .generated = false,397 .generated = false,
386 .dep_file = false,398 .dep_file = false,
399 .target_query = false,
400 .link_libc = false,
387 },401 },
388 .prefix = .{ .value = try wc.addString(a) },402 .prefix = .{ .value = try wc.addString(a) },
389 .suffix = .{ .value = null },403 .suffix = .{ .value = null },
...@@ -391,6 +405,7 @@ const Serialize = struct {...@@ -391,6 +405,7 @@ const Serialize = struct {
391 .path = .{ .value = null },405 .path = .{ .value = null },
392 .producer = .{ .value = null },406 .producer = .{ .value = null },
393 .generated = .{ .value = null },407 .generated = .{ .value = null },
408 .target_query = .{ .value = null },
394 },409 },
395 .output_file, .output_file_dep => |a, tag| .{410 .output_file, .output_file_dep => |a, tag| .{
396 .flags = .{411 .flags = .{
...@@ -402,6 +417,8 @@ const Serialize = struct {...@@ -402,6 +417,8 @@ const Serialize = struct {
402 .producer = false,417 .producer = false,
403 .generated = true,418 .generated = true,
404 .dep_file = tag == .output_file_dep,419 .dep_file = tag == .output_file_dep,
420 .target_query = false,
421 .link_libc = false,
405 },422 },
406 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },423 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },
407 .suffix = .{ .value = null },424 .suffix = .{ .value = null },
...@@ -409,6 +426,7 @@ const Serialize = struct {...@@ -409,6 +426,7 @@ const Serialize = struct {
409 .path = .{ .value = null },426 .path = .{ .value = null },
410 .producer = .{ .value = null },427 .producer = .{ .value = null },
411 .generated = .{ .value = a.generated_file },428 .generated = .{ .value = a.generated_file },
429 .target_query = .{ .value = null },
412 },430 },
413 .output_directory => |a| .{431 .output_directory => |a| .{
414 .flags = .{432 .flags = .{
...@@ -420,6 +438,8 @@ const Serialize = struct {...@@ -420,6 +438,8 @@ const Serialize = struct {
420 .producer = false,438 .producer = false,
421 .generated = true,439 .generated = true,
422 .dep_file = false,440 .dep_file = false,
441 .target_query = false,
442 .link_libc = false,
423 },443 },
424 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },444 .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null },
425 .suffix = .{ .value = null },445 .suffix = .{ .value = null },
...@@ -427,6 +447,7 @@ const Serialize = struct {...@@ -427,6 +447,7 @@ const Serialize = struct {
427 .path = .{ .value = null },447 .path = .{ .value = null },
428 .producer = .{ .value = null },448 .producer = .{ .value = null },
429 .generated = .{ .value = a.generated_file },449 .generated = .{ .value = a.generated_file },
450 .target_query = .{ .value = null },
430 },451 },
431 .passthru => .{452 .passthru => .{
432 .flags = .{453 .flags = .{
...@@ -438,6 +459,8 @@ const Serialize = struct {...@@ -438,6 +459,8 @@ const Serialize = struct {
438 .producer = false,459 .producer = false,
439 .generated = false,460 .generated = false,
440 .dep_file = false,461 .dep_file = false,
462 .target_query = false,
463 .link_libc = false,
441 },464 },
442 .prefix = .{ .value = null },465 .prefix = .{ .value = null },
443 .suffix = .{ .value = null },466 .suffix = .{ .value = null },
...@@ -445,6 +468,28 @@ const Serialize = struct {...@@ -445,6 +468,28 @@ const Serialize = struct {
445 .path = .{ .value = null },468 .path = .{ .value = null },
446 .producer = .{ .value = null },469 .producer = .{ .value = null },
447 .generated = .{ .value = null },470 .generated = .{ .value = null },
471 .target_query = .{ .value = null },
472 },
473 .cc_args => |a| .{
474 .flags = .{
475 .tag = .cc_args,
476 .prefix = false,
477 .suffix = false,
478 .basename = false,
479 .path = false,
480 .producer = false,
481 .generated = false,
482 .dep_file = false,
483 .target_query = a.target_query != .none,
484 .link_libc = a.link_libc,
485 },
486 .prefix = .{ .value = null },
487 .suffix = .{ .value = null },
488 .basename = .{ .value = null },
489 .path = .{ .value = null },
490 .producer = .{ .value = null },
491 .generated = .{ .value = null },
492 .target_query = .{ .value = a.target_query.unwrap() },
448 },493 },
449 })));494 })));
450 }495 }
...@@ -1234,7 +1279,7 @@ fn addOptionalResolvedTarget(...@@ -1234,7 +1279,7 @@ fn addOptionalResolvedTarget(
1234) !Configuration.ResolvedTarget.OptionalIndex {1279) !Configuration.ResolvedTarget.OptionalIndex {
1235 const resolved_target = optional_resolved_target orelse return .none;1280 const resolved_target = optional_resolved_target orelse return .none;
1236 return @enumFromInt(try wc.addDeduped(@as(Configuration.ResolvedTarget, .{1281 return @enumFromInt(try wc.addDeduped(@as(Configuration.ResolvedTarget, .{
1237 .query = try wc.addTargetQuery(resolved_target.query),1282 .query = try wc.addTargetQuery(&resolved_target.query),
1238 .result = try wc.addTarget(resolved_target.result),1283 .result = try wc.addTarget(resolved_target.result),
1239 })));1284 })));
1240}1285}
lib/std/Build.zig+50-25
...@@ -129,13 +129,17 @@ pub const Graph = struct {...@@ -129,13 +129,17 @@ pub const Graph = struct {
129 ///129 ///
130 /// Use of this function indicates a dependency on the host system.130 /// Use of this function indicates a dependency on the host system.
131 pub fn cwdRelativePath(graph: *Graph, sub_path: []const u8) LazyPath {131 pub fn cwdRelativePath(graph: *Graph, sub_path: []const u8) LazyPath {
132 return @This().path(graph, .cwd, sub_path);
133 }
134
135 /// A path whose components and contents are known at some point during
136 /// `Step` resolution, relative to the provided base directory.
137 pub fn path(graph: *Graph, base: Configuration.Path.Base, sub_path: []const u8) LazyPath {
132 const wc = &graph.wip_configuration;138 const wc = &graph.wip_configuration;
133 return .{139 return .{ .relative = .{
134 .relative = .{140 .base = base,
135 .base = .cwd,141 .sub_path = wc.addString(sub_path) catch @panic("OOM"),
136 .sub_path = wc.addString(sub_path) catch @panic("OOM"),142 } };
137 },
138 };
139 }143 }
140144
141 /// Allocates using the global process arena, failing the build on145 /// Allocates using the global process arena, failing the build on
...@@ -780,8 +784,10 @@ pub const AssemblyOptions = struct {...@@ -780,8 +784,10 @@ pub const AssemblyOptions = struct {
780/// it available to other packages which depend on this one.784/// it available to other packages which depend on this one.
781/// `createModule` can be used instead to create a private module.785/// `createModule` can be used instead to create a private module.
782pub fn addModule(b: *Build, name: []const u8, options: Module.CreateOptions) *Module {786pub fn addModule(b: *Build, name: []const u8, options: Module.CreateOptions) *Module {
787 const graph = b.graph;
788 const arena = graph.arena;
783 const module = Module.create(b, options);789 const module = Module.create(b, options);
784 b.modules.put(b.graph.arena, b.dupe(name), module) catch @panic("OOM");790 b.modules.put(arena, graph.dupeString(name), module) catch @panic("OOM");
785 return module;791 return module;
786}792}
787793
...@@ -913,13 +919,15 @@ pub fn addWriteFile(b: *Build, file_path: []const u8, data: []const u8) *Step.Wr...@@ -913,13 +919,15 @@ pub fn addWriteFile(b: *Build, file_path: []const u8, data: []const u8) *Step.Wr
913}919}
914920
915pub fn addNamedWriteFiles(b: *Build, name: []const u8) *Step.WriteFile {921pub fn addNamedWriteFiles(b: *Build, name: []const u8) *Step.WriteFile {
922 const graph = b.graph;
916 const wf = Step.WriteFile.create(b);923 const wf = Step.WriteFile.create(b);
917 b.named_writefiles.put(b.graph.arena, b.dupe(name), wf) catch @panic("OOM");924 b.named_writefiles.put(graph.arena, graph.dupeString(name), wf) catch @panic("OOM");
918 return wf;925 return wf;
919}926}
920927
921pub fn addNamedLazyPath(b: *Build, name: []const u8, lp: LazyPath) void {928pub fn addNamedLazyPath(b: *Build, name: []const u8, lp: LazyPath) void {
922 b.named_lazy_paths.put(b.graph.arena, b.dupe(name), lp.dupe(b)) catch @panic("OOM");929 const graph = b.graph;
930 b.named_lazy_paths.put(graph.arena, graph.dupeString(name), lp.dupe(graph)) catch @panic("OOM");
923}931}
924932
925/// Creates a step for mutating files inside a temporary directory created lazily933/// Creates a step for mutating files inside a temporary directory created lazily
...@@ -1183,16 +1191,18 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw...@@ -1183,16 +1191,18 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw
1183}1191}
11841192
1185pub fn step(b: *Build, name: []const u8, description: []const u8) *Step {1193pub fn step(b: *Build, name: []const u8, description: []const u8) *Step {
1186 const step_info = b.allocator.create(Step.TopLevel) catch @panic("OOM");1194 const graph = b.graph;
1195 const arena = graph.arena;
1196 const step_info = arena.create(Step.TopLevel) catch @panic("OOM");
1187 step_info.* = .{1197 step_info.* = .{
1188 .step = .init(.{1198 .step = .init(.{
1189 .tag = .top_level,1199 .tag = .top_level,
1190 .name = name,1200 .name = name,
1191 .owner = b,1201 .owner = b,
1192 }),1202 }),
1193 .description = b.dupe(description),1203 .description = graph.dupeString(description),
1194 };1204 };
1195 const gop = b.top_level_steps.getOrPut(b.allocator, name) catch @panic("OOM");1205 const gop = b.top_level_steps.getOrPut(arena, name) catch @panic("OOM");
1196 if (gop.found_existing) panic("A top-level step with name \"{s}\" already exists", .{name});1206 if (gop.found_existing) panic("A top-level step with name \"{s}\" already exists", .{name});
11971207
1198 gop.key_ptr.* = step_info.step.name;1208 gop.key_ptr.* = step_info.step.name;
...@@ -1302,6 +1312,9 @@ pub fn parseTargetQuery(options: std.Target.Query.ParseOptions) error{ParseFaile...@@ -1302,6 +1312,9 @@ pub fn parseTargetQuery(options: std.Target.Query.ParseOptions) error{ParseFaile
13021312
1303/// Exposes standard `zig build` options for choosing a target.1313/// Exposes standard `zig build` options for choosing a target.
1304pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs) Target.Query {1314pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs) Target.Query {
1315 const graph = b.graph;
1316 const arena = graph.arena;
1317
1305 const maybe_triple = b.option(1318 const maybe_triple = b.option(
1306 []const u8,1319 []const u8,
1307 "target",1320 "target",
...@@ -1350,20 +1363,22 @@ pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs...@@ -1350,20 +1363,22 @@ pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs
13501363
1351 for (whitelist) |q| {1364 for (whitelist) |q| {
1352 log.info("allowed target: -Dtarget={s} -Dcpu={s}", .{1365 log.info("allowed target: -Dtarget={s} -Dcpu={s}", .{
1353 q.zigTriple(b.allocator) catch @panic("OOM"),1366 q.zigTriple(arena) catch @panic("OOM"),
1354 q.serializeCpuAlloc(b.allocator) catch @panic("OOM"),1367 q.serializeCpuAlloc(arena) catch @panic("OOM"),
1355 });1368 });
1356 }1369 }
1357 log.err("chosen target '{s}' does not match one of the allowed targets", .{1370 log.err("chosen target '{s}' does not match one of the allowed targets", .{
1358 selected_target.zigTriple(b.allocator) catch @panic("OOM"),1371 selected_target.zigTriple(arena) catch @panic("OOM"),
1359 });1372 });
1360 b.markInvalidUserInput();1373 b.markInvalidUserInput();
1361 return args.default_target;1374 return args.default_target;
1362}1375}
13631376
1364pub fn addUserInputOption(b: *Build, name_raw: []const u8, value_raw: []const u8) error{OutOfMemory}!bool {1377pub fn addUserInputOption(b: *Build, name_raw: []const u8, value_raw: []const u8) error{OutOfMemory}!bool {
1365 const name = b.dupe(name_raw);1378 const graph = b.graph;
1366 const value = b.dupe(value_raw);1379 const arena = graph.arena;
1380 const name = graph.dupeString(name_raw);
1381 const value = graph.dupeString(value_raw);
1367 const gop = try b.user_input_options.getOrPut(name);1382 const gop = try b.user_input_options.getOrPut(name);
1368 if (!gop.found_existing) {1383 if (!gop.found_existing) {
1369 gop.value_ptr.* = UserInputOption{1384 gop.value_ptr.* = UserInputOption{
...@@ -1378,7 +1393,7 @@ pub fn addUserInputOption(b: *Build, name_raw: []const u8, value_raw: []const u8...@@ -1378,7 +1393,7 @@ pub fn addUserInputOption(b: *Build, name_raw: []const u8, value_raw: []const u8
1378 switch (gop.value_ptr.value) {1393 switch (gop.value_ptr.value) {
1379 .scalar => |s| {1394 .scalar => |s| {
1380 // turn it into a list1395 // turn it into a list
1381 var list = std.array_list.Managed([]const u8).init(b.allocator);1396 var list = std.array_list.Managed([]const u8).init(arena);
1382 try list.append(s);1397 try list.append(s);
1383 try list.append(value);1398 try list.append(value);
1384 try b.user_input_options.put(name, .{1399 try b.user_input_options.put(name, .{
...@@ -1608,15 +1623,21 @@ pub fn pathList(b: *Build, sub_paths: []const []const u8) []const LazyPath {...@@ -1608,15 +1623,21 @@ pub fn pathList(b: *Build, sub_paths: []const []const u8) []const LazyPath {
1608}1623}
16091624
1610pub fn pathJoin(b: *Build, paths: []const []const u8) []u8 {1625pub fn pathJoin(b: *Build, paths: []const []const u8) []u8 {
1611 return fs.path.join(b.allocator, paths) catch @panic("OOM");1626 const graph = b.graph;
1627 const arena = graph.arena;
1628 return fs.path.join(arena, paths) catch @panic("OOM");
1612}1629}
16131630
1614pub fn pathResolve(b: *Build, paths: []const []const u8) []u8 {1631pub fn pathResolve(b: *Build, paths: []const []const u8) []u8 {
1615 return fs.path.resolve(b.allocator, paths) catch @panic("OOM");1632 const graph = b.graph;
1633 const arena = graph.arena;
1634 return fs.path.resolve(arena, paths) catch @panic("OOM");
1616}1635}
16171636
1618pub fn fmt(b: *Build, comptime format: []const u8, args: anytype) []u8 {1637pub fn fmt(b: *Build, comptime format: []const u8, args: anytype) []u8 {
1619 return std.fmt.allocPrint(b.allocator, format, args) catch @panic("OOM");1638 const graph = b.graph;
1639 const arena = graph.arena;
1640 return std.fmt.allocPrint(arena, format, args) catch @panic("OOM");
1620}1641}
16211642
1622/// Creates an anonymous `Step` that searches for an executable on the host that1643/// Creates an anonymous `Step` that searches for an executable on the host that
...@@ -2264,7 +2285,9 @@ pub const LazyPath = union(enum) {...@@ -2264,7 +2285,9 @@ pub const LazyPath = union(enum) {
2264 }2285 }
22652286
2266 pub fn path(lazy_path: LazyPath, b: *Build, sub_path: []const u8) LazyPath {2287 pub fn path(lazy_path: LazyPath, b: *Build, sub_path: []const u8) LazyPath {
2267 return lazy_path.join(b.allocator, sub_path) catch @panic("OOM");2288 const graph = b.graph;
2289 const arena = graph.arena;
2290 return lazy_path.join(arena, sub_path) catch @panic("OOM");
2268 }2291 }
22692292
2270 pub fn join(lazy_path: LazyPath, arena: Allocator, sub_path: []const u8) Allocator.Error!LazyPath {2293 pub fn join(lazy_path: LazyPath, arena: Allocator, sub_path: []const u8) Allocator.Error!LazyPath {
...@@ -2460,7 +2483,9 @@ pub fn systemIntegrationOption(...@@ -2460,7 +2483,9 @@ pub fn systemIntegrationOption(
2460 name: []const u8,2483 name: []const u8,
2461 config: SystemIntegrationOptionConfig,2484 config: SystemIntegrationOptionConfig,
2462) bool {2485) bool {
2463 const gop = b.graph.system_integration_options.getOrPut(b.allocator, name) catch @panic("OOM");2486 const graph = b.graph;
2487 const arena = graph.arena;
2488 const gop = graph.system_integration_options.getOrPut(arena, name) catch @panic("OOM");
2464 if (gop.found_existing) switch (gop.value_ptr.*) {2489 if (gop.found_existing) switch (gop.value_ptr.*) {
2465 .user_disabled => {2490 .user_disabled => {
2466 gop.value_ptr.* = .declared_disabled;2491 gop.value_ptr.* = .declared_disabled;
...@@ -2473,8 +2498,8 @@ pub fn systemIntegrationOption(...@@ -2473,8 +2498,8 @@ pub fn systemIntegrationOption(
2473 .declared_disabled => return false,2498 .declared_disabled => return false,
2474 .declared_enabled => return true,2499 .declared_enabled => return true,
2475 } else {2500 } else {
2476 gop.key_ptr.* = b.dupe(name);2501 gop.key_ptr.* = graph.dupeString(name);
2477 if (config.default orelse b.graph.system_package_mode) {2502 if (config.default orelse graph.system_package_mode) {
2478 gop.value_ptr.* = .declared_enabled;2503 gop.value_ptr.* = .declared_enabled;
2479 return true;2504 return true;
2480 } else {2505 } else {
lib/std/Build/Configuration.zig+7-3
...@@ -230,7 +230,7 @@ pub const Wip = struct {...@@ -230,7 +230,7 @@ pub const Wip = struct {
230 return addString(wip, writer.buffered());230 return addString(wip, writer.buffered());
231 }231 }
232232
233 pub fn addTargetQuery(wip: *Wip, q: std.Target.Query) !TargetQuery.OptionalIndex {233 pub fn addTargetQuery(wip: *Wip, q: *const std.Target.Query) !TargetQuery.OptionalIndex {
234 if (q.isNative()) return .none;234 if (q.isNative()) return .none;
235 const gpa = wip.gpa;235 const gpa = wip.gpa;
236 const cpu_name: ?String = switch (q.cpu_model) {236 const cpu_name: ?String = switch (q.cpu_model) {
...@@ -575,6 +575,7 @@ pub const Step = extern struct {...@@ -575,6 +575,7 @@ pub const Step = extern struct {
575 /// Always a compile step.575 /// Always a compile step.
576 producer: Storage.FlagOptional(.flags, .producer, Step.Index),576 producer: Storage.FlagOptional(.flags, .producer, Step.Index),
577 generated: Storage.FlagOptional(.flags, .generated, GeneratedFileIndex),577 generated: Storage.FlagOptional(.flags, .generated, GeneratedFileIndex),
578 target_query: Storage.FlagOptional(.flags, .target_query, TargetQuery.Index),
578579
579 pub const Flags = packed struct(u32) {580 pub const Flags = packed struct(u32) {
580 tag: Arg.Tag,581 tag: Arg.Tag,
...@@ -585,10 +586,12 @@ pub const Step = extern struct {...@@ -585,10 +586,12 @@ pub const Step = extern struct {
585 producer: bool,586 producer: bool,
586 generated: bool,587 generated: bool,
587 dep_file: bool,588 dep_file: bool,
588 _: u22 = 0,589 target_query: bool,
590 link_libc: bool,
591 _: u19 = 0,
589 };592 };
590593
591 pub const Tag = enum(u3) {594 pub const Tag = enum(u4) {
592 artifact,595 artifact,
593 /// `path` contains the file.596 /// `path` contains the file.
594 path_file,597 path_file,
...@@ -599,6 +602,7 @@ pub const Step = extern struct {...@@ -599,6 +602,7 @@ pub const Step = extern struct {
599 output_file,602 output_file,
600 output_directory,603 output_directory,
601 passthru,604 passthru,
605 cc_args,
602 };606 };
603607
604 pub const Index = IndexType(@This());608 pub const Index = IndexType(@This());
lib/std/Build/Step/Run.zig+23
...@@ -143,6 +143,13 @@ pub const Arg = union(enum) {...@@ -143,6 +143,13 @@ pub const Arg = union(enum) {
143 output_directory: *Output,143 output_directory: *Output,
144 /// The arguments passed after "--" on the "zig build" CLI.144 /// The arguments passed after "--" on the "zig build" CLI.
145 passthru,145 passthru,
146 /// Adds standard "-isystem" and "-iframework" arguments corresponding to the libc of the target.
147 cc_args: CcArgs,
148};
149
150pub const CcArgs = struct {
151 link_libc: bool,
152 target_query: Configuration.TargetQuery.OptionalIndex,
146};153};
147154
148pub const PrefixedArtifact = struct {155pub const PrefixedArtifact = struct {
...@@ -529,6 +536,22 @@ pub fn addPassthruArgs(run: *Run) void {...@@ -529,6 +536,22 @@ pub fn addPassthruArgs(run: *Run) void {
529 run.argv.append(arena, .passthru) catch @panic("OOM");536 run.argv.append(arena, .passthru) catch @panic("OOM");
530}537}
531538
539pub const AddCcArgs = struct {
540 link_libc: bool = false,
541 target_query: ?*const std.Target.Query = null,
542};
543
544/// Appends C compiler flags for the target and for including libc.
545pub fn addCcArgs(run: *Run, options: AddCcArgs) void {
546 const graph = run.step.owner.graph;
547 const arena = graph.arena;
548 const wc = &graph.wip_configuration;
549 run.argv.append(arena, .{ .cc_args = .{
550 .link_libc = options.link_libc,
551 .target_query = if (options.target_query) |q| wc.addTargetQuery(q) catch @panic("OOM") else .none,
552 } }) catch @panic("OOM");
553}
554
532pub fn setStdIn(run: *Run, stdin: StdIn) void {555pub fn setStdIn(run: *Run, stdin: StdIn) void {
533 switch (stdin) {556 switch (stdin) {
534 .lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step),557 .lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step),