| author | |
| committer | |
| log | b40b1178ef29ea9b013f73cc3cd4f9b976d0e120 |
| tree | 66b4f4416ff944f95e72dedae4c52f4ebb356612 |
| parent | c5d6277ace183cf4261c13cc9b44a53ec1622199 |
* Adds a new API that takes an options struct instead of having a
function for each combination of options
* Adds support for prefix and suffix to every argument type
* Adds support for making paths absolute when passed as arguments
* Deprecates the old API
* Fixes mismatch between documentation and behavior of
`process.currentPath` on WASI7 files changed, 384 insertions(+), 132 deletions(-)
lib/compiler/Maker/Step/Run.zig+31-13| ... | @@ -87,8 +87,9 @@ pub fn make( | ... | @@ -87,8 +87,9 @@ pub fn make( |
| 87 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; | 87 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 88 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); | 88 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 89 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ | 89 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 90 | prefix, try convertPathArg(arena, run_index, maker, file_path), suffix, | 90 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 91 | })); | 91 | })); |
| 92 | man.hash.add(arg.flags.make_absolute); | ||
| 92 | man.hash.addBytesZ(prefix); | 93 | man.hash.addBytesZ(prefix); |
| 93 | man.hash.addBytesZ(suffix); | 94 | man.hash.addBytesZ(suffix); |
| 94 | _ = try man.addFilePath(file_path, null); | 95 | _ = try man.addFilePath(file_path, null); |
| ... | @@ -98,9 +99,10 @@ pub fn make( | ... | @@ -98,9 +99,10 @@ pub fn make( |
| 98 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; | 99 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 99 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); | 100 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 100 | const resolved_arg = try mem.concat(arena, u8, &.{ | 101 | const resolved_arg = try mem.concat(arena, u8, &.{ |
| 101 | prefix, try convertPathArg(arena, run_index, maker, file_path), suffix, | 102 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 102 | }); | 103 | }); |
| 103 | argv_list.appendAssumeCapacity(resolved_arg); | 104 | argv_list.appendAssumeCapacity(resolved_arg); |
| 105 | man.hash.add(arg.flags.make_absolute); | ||
| 104 | man.hash.addBytes(resolved_arg); | 106 | man.hash.addBytes(resolved_arg); |
| 105 | }, | 107 | }, |
| 106 | .file_content => { | 108 | .file_content => { |
| ... | @@ -142,9 +144,12 @@ pub fn make( | ... | @@ -142,9 +144,12 @@ pub fn make( |
| 142 | const file_path = producer_make_comp.installed_path orelse maker.generatedPath(producer.generated_bin.value.?).*; | 144 | const file_path = producer_make_comp.installed_path orelse maker.generatedPath(producer.generated_bin.value.?).*; |
| 143 | 145 | ||
| 144 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ | 146 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 145 | prefix, try convertPathArg(arena, run_index, maker, file_path), suffix, | 147 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 146 | })); | 148 | })); |
| 147 | 149 | ||
| 150 | man.hash.add(arg.flags.make_absolute); | ||
| 151 | man.hash.addBytesZ(prefix); | ||
| 152 | man.hash.addBytesZ(suffix); | ||
| 148 | _ = try man.addFilePath(file_path, null); | 153 | _ = try man.addFilePath(file_path, null); |
| 149 | }, | 154 | }, |
| 150 | .output_file, .output_directory => { | 155 | .output_file, .output_directory => { |
| ... | @@ -152,6 +157,7 @@ pub fn make( | ... | @@ -152,6 +157,7 @@ pub fn make( |
| 152 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; | 157 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 153 | const basename = arg.basename.value.?.slice(conf); | 158 | const basename = arg.basename.value.?.slice(conf); |
| 154 | 159 | ||
| 160 | man.hash.add(arg.flags.make_absolute); | ||
| 155 | man.hash.addBytesZ(prefix); | 161 | man.hash.addBytesZ(prefix); |
| 156 | man.hash.addBytesZ(basename); | 162 | man.hash.addBytesZ(basename); |
| 157 | man.hash.addBytesZ(suffix); | 163 | man.hash.addBytesZ(suffix); |
| ... | @@ -181,7 +187,7 @@ pub fn make( | ... | @@ -181,7 +187,7 @@ pub fn make( |
| 181 | 187 | ||
| 182 | man.hash.add(conf_run.flags.test_runner_mode); | 188 | man.hash.add(conf_run.flags.test_runner_mode); |
| 183 | if (conf_run.flags.test_runner_mode) { | 189 | if (conf_run.flags.test_runner_mode) { |
| 184 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }); | 190 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }, false); |
| 185 | 191 | ||
| 186 | try argv_list.ensureUnusedCapacity(gpa, 3); | 192 | try argv_list.ensureUnusedCapacity(gpa, 3); |
| 187 | argv_list.appendAssumeCapacity(try allocPrint(arena, "--cache-dir={s}", .{cache_dir_string})); | 193 | argv_list.appendAssumeCapacity(try allocPrint(arena, "--cache-dir={s}", .{cache_dir_string})); |
| ... | @@ -1552,7 +1558,7 @@ pub fn rerunInFuzzMode( | ... | @@ -1552,7 +1558,7 @@ pub fn rerunInFuzzMode( |
| 1552 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; | 1558 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 1553 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); | 1559 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 1554 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ | 1560 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 1555 | prefix, try convertPathArg(arena, run_index, maker, file_path), suffix, | 1561 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 1556 | })); | 1562 | })); |
| 1557 | }, | 1563 | }, |
| 1558 | .path_directory => { | 1564 | .path_directory => { |
| ... | @@ -1560,7 +1566,7 @@ pub fn rerunInFuzzMode( | ... | @@ -1560,7 +1566,7 @@ pub fn rerunInFuzzMode( |
| 1560 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; | 1566 | const suffix = if (arg.suffix.value) |p| p.slice(conf) else ""; |
| 1561 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); | 1567 | const file_path = try maker.resolveLazyPathIndex(arena, arg.path.value.?, run_index); |
| 1562 | const resolved_arg = try mem.concat(arena, u8, &.{ | 1568 | const resolved_arg = try mem.concat(arena, u8, &.{ |
| 1563 | prefix, try convertPathArg(arena, run_index, maker, file_path), suffix, | 1569 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 1564 | }); | 1570 | }); |
| 1565 | argv_list.appendAssumeCapacity(resolved_arg); | 1571 | argv_list.appendAssumeCapacity(resolved_arg); |
| 1566 | }, | 1572 | }, |
| ... | @@ -1602,7 +1608,7 @@ pub fn rerunInFuzzMode( | ... | @@ -1602,7 +1608,7 @@ pub fn rerunInFuzzMode( |
| 1602 | producer_make_comp.installed_path orelse | 1608 | producer_make_comp.installed_path orelse |
| 1603 | maker.generatedPath(producer.generated_bin.value.?).*; | 1609 | maker.generatedPath(producer.generated_bin.value.?).*; |
| 1604 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ | 1610 | argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ |
| 1605 | prefix, try convertPathArg(arena, run_index, maker, file_path), suffix, | 1611 | prefix, try convertPathArg(arena, run_index, maker, file_path, arg.flags.make_absolute), suffix, |
| 1606 | })); | 1612 | })); |
| 1607 | }, | 1613 | }, |
| 1608 | .output_file => unreachable, | 1614 | .output_file => unreachable, |
| ... | @@ -1612,7 +1618,7 @@ pub fn rerunInFuzzMode( | ... | @@ -1612,7 +1618,7 @@ pub fn rerunInFuzzMode( |
| 1612 | } | 1618 | } |
| 1613 | 1619 | ||
| 1614 | if (conf_run.flags.test_runner_mode) { | 1620 | if (conf_run.flags.test_runner_mode) { |
| 1615 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }); | 1621 | const cache_dir_string = try convertPathArg(arena, run_index, maker, .{ .root_dir = cache_root }, false); |
| 1616 | 1622 | ||
| 1617 | try argv_list.ensureUnusedCapacity(gpa, 3); | 1623 | try argv_list.ensureUnusedCapacity(gpa, 3); |
| 1618 | argv_list.appendAssumeCapacity(try allocPrint(arena, "--cache-dir={s}", .{cache_dir_string})); | 1624 | argv_list.appendAssumeCapacity(try allocPrint(arena, "--cache-dir={s}", .{cache_dir_string})); |
| ... | @@ -1688,7 +1694,7 @@ fn populateGeneratedPathsCreateDirs( | ... | @@ -1688,7 +1694,7 @@ fn populateGeneratedPathsCreateDirs( |
| 1688 | 1694 | ||
| 1689 | maker.generatedPath(arg.generated.value.?).* = generated_path; | 1695 | maker.generatedPath(arg.generated.value.?).* = generated_path; |
| 1690 | 1696 | ||
| 1691 | const arg_output_path = try convertPathArg(arena, run_index, maker, generated_path); | 1697 | const arg_output_path = try convertPathArg(arena, run_index, maker, generated_path, arg.flags.make_absolute); |
| 1692 | argv[placeholder.index] = try mem.concat(arena, u8, &.{ prefix, arg_output_path, suffix }); | 1698 | argv[placeholder.index] = try mem.concat(arena, u8, &.{ prefix, arg_output_path, suffix }); |
| 1693 | } | 1699 | } |
| 1694 | } | 1700 | } |
| ... | @@ -2290,11 +2296,18 @@ fn checksContainStderr(conf_run: *const Configuration.Step.Run) bool { | ... | @@ -2290,11 +2296,18 @@ fn checksContainStderr(conf_run: *const Configuration.Step.Run) bool { |
| 2290 | return conf_run.expect_stderr_exact.value != null or conf_run.expect_stderr_match.slice.len != 0; | 2296 | return conf_run.expect_stderr_exact.value != null or conf_run.expect_stderr_match.slice.len != 0; |
| 2291 | } | 2297 | } |
| 2292 | 2298 | ||
| 2293 | /// If `path` is cwd-relative, make it relative to the cwd of the child instead. | 2299 | /// If `path` is absolute, return it unchanged. If `make_absolute` is true, make it absolute. |
| 2300 | /// Otherwise, make it relative to the cwd of the child. | ||
| 2294 | /// | 2301 | /// |
| 2295 | /// Whenever a path is included in the argv of a child, it should be put through this function first | 2302 | /// Whenever a path is included in the argv of a child, it should be put through this function |
| 2296 | /// to make sure the child doesn't see paths relative to a cwd other than its own. | 2303 | /// first. |
| 2297 | fn convertPathArg(arena: Allocator, run_index: Configuration.Step.Index, maker: *Maker, path: Path) ![]const u8 { | 2304 | fn convertPathArg( |
| 2305 | arena: Allocator, | ||
| 2306 | run_index: Configuration.Step.Index, | ||
| 2307 | maker: *Maker, | ||
| 2308 | path: Path, | ||
| 2309 | make_absolute: bool, | ||
| 2310 | ) ![]const u8 { | ||
| 2298 | const conf = &maker.scanned_config.configuration; | 2311 | const conf = &maker.scanned_config.configuration; |
| 2299 | const conf_step = run_index.ptr(conf); | 2312 | const conf_step = run_index.ptr(conf); |
| 2300 | const conf_run = conf_step.extended.get(conf.extra).run; | 2313 | const conf_run = conf_step.extended.get(conf.extra).run; |
| ... | @@ -2305,6 +2318,11 @@ fn convertPathArg(arena: Allocator, run_index: Configuration.Step.Index, maker: | ... | @@ -2305,6 +2318,11 @@ fn convertPathArg(arena: Allocator, run_index: Configuration.Step.Index, maker: |
| 2305 | // Absolute paths don't need changing. | 2318 | // Absolute paths don't need changing. |
| 2306 | return path_str; | 2319 | return path_str; |
| 2307 | } | 2320 | } |
| 2321 | |||
| 2322 | if (make_absolute) { | ||
| 2323 | return Dir.path.join(arena, &.{ graph.cache.cwd, path_str }); | ||
| 2324 | } | ||
| 2325 | |||
| 2308 | const child_cwd_rel: []const u8 = rel: { | 2326 | const child_cwd_rel: []const u8 = rel: { |
| 2309 | const child_lazy_cwd = conf_run.cwd.value orelse break :rel path_str; | 2327 | const child_lazy_cwd = conf_run.cwd.value orelse break :rel path_str; |
| 2310 | const child_cwd = try maker.resolveLazyPathIndexAbs(arena, child_lazy_cwd, run_index); | 2328 | const child_cwd = try maker.resolveLazyPathIndexAbs(arena, child_lazy_cwd, run_index); |
lib/compiler/configurer.zig+22-14| ... | @@ -312,15 +312,16 @@ const Serialize = struct { | ... | @@ -312,15 +312,16 @@ const Serialize = struct { |
| 312 | .flags = .{ | 312 | .flags = .{ |
| 313 | .tag = .artifact, | 313 | .tag = .artifact, |
| 314 | .prefix = a.prefix.len != 0, | 314 | .prefix = a.prefix.len != 0, |
| 315 | .suffix = false, | 315 | .suffix = a.suffix.len != 0, |
| 316 | .basename = false, | 316 | .basename = false, |
| 317 | .path = false, | 317 | .path = false, |
| 318 | .producer = true, | 318 | .producer = true, |
| 319 | .generated = false, | 319 | .generated = false, |
| 320 | .dep_file = false, | 320 | .dep_file = false, |
| 321 | .make_absolute = a.make_absolute, | ||
| 321 | }, | 322 | }, |
| 322 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, | 323 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, |
| 323 | .suffix = .{ .value = null }, | 324 | .suffix = .{ .value = if (a.suffix.len != 0) try wc.addString(a.suffix) else null }, |
| 324 | .basename = .{ .value = null }, | 325 | .basename = .{ .value = null }, |
| 325 | .path = .{ .value = null }, | 326 | .path = .{ .value = null }, |
| 326 | .producer = .{ .value = stepIndex(s, &a.artifact.step) }, | 327 | .producer = .{ .value = stepIndex(s, &a.artifact.step) }, |
| ... | @@ -330,15 +331,16 @@ const Serialize = struct { | ... | @@ -330,15 +331,16 @@ const Serialize = struct { |
| 330 | .flags = .{ | 331 | .flags = .{ |
| 331 | .tag = .path_file, | 332 | .tag = .path_file, |
| 332 | .prefix = a.prefix.len != 0, | 333 | .prefix = a.prefix.len != 0, |
| 333 | .suffix = false, | 334 | .suffix = a.suffix.len != 0, |
| 334 | .basename = false, | 335 | .basename = false, |
| 335 | .path = true, | 336 | .path = true, |
| 336 | .producer = false, | 337 | .producer = false, |
| 337 | .generated = false, | 338 | .generated = false, |
| 338 | .dep_file = false, | 339 | .dep_file = false, |
| 340 | .make_absolute = a.make_absolute, | ||
| 339 | }, | 341 | }, |
| 340 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, | 342 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, |
| 341 | .suffix = .{ .value = null }, | 343 | .suffix = .{ .value = if (a.suffix.len != 0) try wc.addString(a.suffix) else null }, |
| 342 | .basename = .{ .value = null }, | 344 | .basename = .{ .value = null }, |
| 343 | .path = .{ .value = try addLazyPath(s, a.lazy_path) }, | 345 | .path = .{ .value = try addLazyPath(s, a.lazy_path) }, |
| 344 | .producer = .{ .value = null }, | 346 | .producer = .{ .value = null }, |
| ... | @@ -354,6 +356,7 @@ const Serialize = struct { | ... | @@ -354,6 +356,7 @@ const Serialize = struct { |
| 354 | .producer = false, | 356 | .producer = false, |
| 355 | .generated = false, | 357 | .generated = false, |
| 356 | .dep_file = false, | 358 | .dep_file = false, |
| 359 | .make_absolute = a.make_absolute, | ||
| 357 | }, | 360 | }, |
| 358 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, | 361 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, |
| 359 | .suffix = .{ .value = if (a.suffix.len != 0) try wc.addString(a.suffix) else null }, | 362 | .suffix = .{ .value = if (a.suffix.len != 0) try wc.addString(a.suffix) else null }, |
| ... | @@ -366,15 +369,16 @@ const Serialize = struct { | ... | @@ -366,15 +369,16 @@ const Serialize = struct { |
| 366 | .flags = .{ | 369 | .flags = .{ |
| 367 | .tag = .file_content, | 370 | .tag = .file_content, |
| 368 | .prefix = a.prefix.len != 0, | 371 | .prefix = a.prefix.len != 0, |
| 369 | .suffix = false, | 372 | .suffix = a.suffix.len != 0, |
| 370 | .basename = false, | 373 | .basename = false, |
| 371 | .path = true, | 374 | .path = true, |
| 372 | .producer = false, | 375 | .producer = false, |
| 373 | .generated = false, | 376 | .generated = false, |
| 374 | .dep_file = false, | 377 | .dep_file = false, |
| 378 | .make_absolute = false, | ||
| 375 | }, | 379 | }, |
| 376 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, | 380 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, |
| 377 | .suffix = .{ .value = null }, | 381 | .suffix = .{ .value = if (a.suffix.len != 0) try wc.addString(a.suffix) else null }, |
| 378 | .basename = .{ .value = null }, | 382 | .basename = .{ .value = null }, |
| 379 | .path = .{ .value = try addLazyPath(s, a.lazy_path) }, | 383 | .path = .{ .value = try addLazyPath(s, a.lazy_path) }, |
| 380 | .producer = .{ .value = null }, | 384 | .producer = .{ .value = null }, |
| ... | @@ -390,6 +394,7 @@ const Serialize = struct { | ... | @@ -390,6 +394,7 @@ const Serialize = struct { |
| 390 | .producer = false, | 394 | .producer = false, |
| 391 | .generated = false, | 395 | .generated = false, |
| 392 | .dep_file = false, | 396 | .dep_file = false, |
| 397 | .make_absolute = false, | ||
| 393 | }, | 398 | }, |
| 394 | .prefix = .{ .value = try wc.addString(a) }, | 399 | .prefix = .{ .value = try wc.addString(a) }, |
| 395 | .suffix = .{ .value = null }, | 400 | .suffix = .{ .value = null }, |
| ... | @@ -402,15 +407,16 @@ const Serialize = struct { | ... | @@ -402,15 +407,16 @@ const Serialize = struct { |
| 402 | .flags = .{ | 407 | .flags = .{ |
| 403 | .tag = .output_file, | 408 | .tag = .output_file, |
| 404 | .prefix = a.prefix.len != 0, | 409 | .prefix = a.prefix.len != 0, |
| 405 | .suffix = false, | 410 | .suffix = a.suffix.len != 0, |
| 406 | .basename = a.basename.len != 0, | 411 | .basename = a.basename.len != 0, |
| 407 | .path = false, | 412 | .path = false, |
| 408 | .producer = false, | 413 | .producer = false, |
| 409 | .generated = true, | 414 | .generated = true, |
| 410 | .dep_file = tag == .output_file_dep, | 415 | .dep_file = tag == .output_file_dep, |
| 416 | .make_absolute = a.make_absolute, | ||
| 411 | }, | 417 | }, |
| 412 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, | 418 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, |
| 413 | .suffix = .{ .value = null }, | 419 | .suffix = .{ .value = if (a.suffix.len != 0) try wc.addString(a.suffix) else null }, |
| 414 | .basename = .{ .value = if (a.basename.len != 0) try wc.addString(a.basename) else null }, | 420 | .basename = .{ .value = if (a.basename.len != 0) try wc.addString(a.basename) else null }, |
| 415 | .path = .{ .value = null }, | 421 | .path = .{ .value = null }, |
| 416 | .producer = .{ .value = null }, | 422 | .producer = .{ .value = null }, |
| ... | @@ -420,15 +426,16 @@ const Serialize = struct { | ... | @@ -420,15 +426,16 @@ const Serialize = struct { |
| 420 | .flags = .{ | 426 | .flags = .{ |
| 421 | .tag = .output_directory, | 427 | .tag = .output_directory, |
| 422 | .prefix = a.prefix.len != 0, | 428 | .prefix = a.prefix.len != 0, |
| 423 | .suffix = false, | 429 | .suffix = a.suffix.len != 0, |
| 424 | .basename = a.basename.len != 0, | 430 | .basename = a.basename.len != 0, |
| 425 | .path = false, | 431 | .path = false, |
| 426 | .producer = false, | 432 | .producer = false, |
| 427 | .generated = true, | 433 | .generated = true, |
| 428 | .dep_file = false, | 434 | .dep_file = false, |
| 435 | .make_absolute = a.make_absolute, | ||
| 429 | }, | 436 | }, |
| 430 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, | 437 | .prefix = .{ .value = if (a.prefix.len != 0) try wc.addString(a.prefix) else null }, |
| 431 | .suffix = .{ .value = null }, | 438 | .suffix = .{ .value = if (a.suffix.len != 0) try wc.addString(a.suffix) else null }, |
| 432 | .basename = .{ .value = if (a.basename.len != 0) try wc.addString(a.basename) else null }, | 439 | .basename = .{ .value = if (a.basename.len != 0) try wc.addString(a.basename) else null }, |
| 433 | .path = .{ .value = null }, | 440 | .path = .{ .value = null }, |
| 434 | .producer = .{ .value = null }, | 441 | .producer = .{ .value = null }, |
| ... | @@ -444,6 +451,7 @@ const Serialize = struct { | ... | @@ -444,6 +451,7 @@ const Serialize = struct { |
| 444 | .producer = false, | 451 | .producer = false, |
| 445 | .generated = false, | 452 | .generated = false, |
| 446 | .dep_file = false, | 453 | .dep_file = false, |
| 454 | .make_absolute = false, | ||
| 447 | }, | 455 | }, |
| 448 | .prefix = .{ .value = null }, | 456 | .prefix = .{ .value = null }, |
| 449 | .suffix = .{ .value = null }, | 457 | .suffix = .{ .value = null }, |
| ... | @@ -1066,12 +1074,12 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void { | ... | @@ -1066,12 +1074,12 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void { |
| 1066 | .args = .{ .slice = try s.initArgsList(run.argv.items) }, | 1074 | .args = .{ .slice = try s.initArgsList(run.argv.items) }, |
| 1067 | .cwd = .{ .value = try s.addOptionalLazyPath(run.cwd) }, | 1075 | .cwd = .{ .value = try s.addOptionalLazyPath(run.cwd) }, |
| 1068 | .captured_stdout = .{ .value = if (run.captured_stdout) |cs| .{ | 1076 | .captured_stdout = .{ .value = if (run.captured_stdout) |cs| .{ |
| 1069 | .basename = try wc.addString(cs.output.basename), | 1077 | .basename = try wc.addString(cs.basename), |
| 1070 | .generated_file = cs.output.generated_file, | 1078 | .generated_file = cs.generated_file, |
| 1071 | } else null }, | 1079 | } else null }, |
| 1072 | .captured_stderr = .{ .value = if (run.captured_stderr) |cs| .{ | 1080 | .captured_stderr = .{ .value = if (run.captured_stderr) |cs| .{ |
| 1073 | .basename = try wc.addString(cs.output.basename), | 1081 | .basename = try wc.addString(cs.basename), |
| 1074 | .generated_file = cs.output.generated_file, | 1082 | .generated_file = cs.generated_file, |
| 1075 | } else null }, | 1083 | } else null }, |
| 1076 | .environ_map = .{ .value = try s.addEnvironMap(run.environ_map) }, | 1084 | .environ_map = .{ .value = try s.addEnvironMap(run.environ_map) }, |
| 1077 | .expect_term_value = .{ .value = if (expect_term) |t| t.value else null }, | 1085 | .expect_term_value = .{ .value = if (expect_term) |t| t.value else null }, |
lib/std/Build/Configuration.zig+2-1| ... | @@ -610,7 +610,8 @@ pub const Step = extern struct { | ... | @@ -610,7 +610,8 @@ pub const Step = extern struct { |
| 610 | producer: bool, | 610 | producer: bool, |
| 611 | generated: bool, | 611 | generated: bool, |
| 612 | dep_file: bool, | 612 | dep_file: bool, |
| 613 | _: u21 = 0, | 613 | make_absolute: bool, |
| 614 | _: u20 = 0, | ||
| 614 | }; | 615 | }; |
| 615 | 616 | ||
| 616 | pub const Tag = enum(u4) { | 617 | pub const Tag = enum(u4) { |
lib/std/Build/Step/Run.zig+134-104| ... | @@ -133,10 +133,10 @@ pub const StdIo = union(enum) { | ... | @@ -133,10 +133,10 @@ pub const StdIo = union(enum) { |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | pub const Arg = union(enum) { | 135 | pub const Arg = union(enum) { |
| 136 | artifact: PrefixedArtifact, | 136 | artifact: DecoratedArtifact, |
| 137 | lazy_path: PrefixedLazyPath, | 137 | lazy_path: DecoratedLazyPath, |
| 138 | decorated_directory: DecoratedLazyPath, | 138 | decorated_directory: DecoratedLazyPath, |
| 139 | file_content: PrefixedLazyPath, | 139 | file_content: DecoratedFileContent, |
| 140 | bytes: []const u8, | 140 | bytes: []const u8, |
| 141 | output_file: *Output, | 141 | output_file: *Output, |
| 142 | output_file_dep: *Output, | 142 | output_file_dep: *Output, |
| ... | @@ -145,17 +145,21 @@ pub const Arg = union(enum) { | ... | @@ -145,17 +145,21 @@ pub const Arg = union(enum) { |
| 145 | passthru, | 145 | passthru, |
| 146 | }; | 146 | }; |
| 147 | 147 | ||
| 148 | pub const PrefixedArtifact = struct { | 148 | pub const DecoratedArtifact = struct { |
| 149 | prefix: []const u8, | 149 | prefix: []const u8, |
| 150 | suffix: []const u8, | ||
| 150 | artifact: *Step.Compile, | 151 | artifact: *Step.Compile, |
| 152 | make_absolute: bool, | ||
| 151 | }; | 153 | }; |
| 152 | 154 | ||
| 153 | pub const PrefixedLazyPath = struct { | 155 | pub const DecoratedLazyPath = struct { |
| 154 | prefix: []const u8, | 156 | prefix: []const u8, |
| 155 | lazy_path: std.Build.LazyPath, | 157 | lazy_path: std.Build.LazyPath, |
| 158 | suffix: []const u8, | ||
| 159 | make_absolute: bool, | ||
| 156 | }; | 160 | }; |
| 157 | 161 | ||
| 158 | pub const DecoratedLazyPath = struct { | 162 | pub const DecoratedFileContent = struct { |
| 159 | prefix: []const u8, | 163 | prefix: []const u8, |
| 160 | lazy_path: std.Build.LazyPath, | 164 | lazy_path: std.Build.LazyPath, |
| 161 | suffix: []const u8, | 165 | suffix: []const u8, |
| ... | @@ -165,10 +169,14 @@ pub const Output = struct { | ... | @@ -165,10 +169,14 @@ pub const Output = struct { |
| 165 | generated_file: Configuration.GeneratedFileIndex, | 169 | generated_file: Configuration.GeneratedFileIndex, |
| 166 | prefix: []const u8, | 170 | prefix: []const u8, |
| 167 | basename: []const u8, | 171 | basename: []const u8, |
| 172 | suffix: []const u8, | ||
| 173 | make_absolute: bool, | ||
| 168 | }; | 174 | }; |
| 169 | 175 | ||
| 170 | pub const CapturedStdIo = struct { | 176 | pub const CapturedStdIo = struct { |
| 171 | output: Output, | 177 | generated_file: Configuration.GeneratedFileIndex, |
| 178 | prefix: []const u8, | ||
| 179 | basename: []const u8, | ||
| 172 | trim_whitespace: TrimWhitespace, | 180 | trim_whitespace: TrimWhitespace, |
| 173 | 181 | ||
| 174 | pub const Options = struct { | 182 | pub const Options = struct { |
| ... | @@ -219,17 +227,38 @@ pub fn enableTestRunnerMode(run: *Run) void { | ... | @@ -219,17 +227,38 @@ pub fn enableTestRunnerMode(run: *Run) void { |
| 219 | run.test_runner_mode = true; | 227 | run.test_runner_mode = true; |
| 220 | } | 228 | } |
| 221 | 229 | ||
| 230 | pub const ArgOptions = struct { | ||
| 231 | prefix: []const u8 = "", | ||
| 232 | suffix: []const u8 = "", | ||
| 233 | }; | ||
| 234 | |||
| 235 | pub const PathArgOptions = struct { | ||
| 236 | prefix: []const u8 = "", | ||
| 237 | suffix: []const u8 = "", | ||
| 238 | /// Makes the path absolute before passing it to the child process. Not supported by all hosts, | ||
| 239 | /// prefer accepting relative paths when possible. | ||
| 240 | make_absolute: bool = false, | ||
| 241 | }; | ||
| 242 | |||
| 243 | /// Deprecated, use `addArtifactArg2`. | ||
| 222 | pub fn addArtifactArg(run: *Run, artifact: *Step.Compile) void { | 244 | pub fn addArtifactArg(run: *Run, artifact: *Step.Compile) void { |
| 223 | run.addPrefixedArtifactArg("", artifact); | 245 | run.addArtifactArg2(artifact, .{}); |
| 224 | } | 246 | } |
| 225 | 247 | ||
| 248 | /// Deprecated, use `addArtifactArg2`. | ||
| 226 | pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Compile) void { | 249 | pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Compile) void { |
| 250 | run.addArtifactArg2(artifact, .{ .prefix = prefix }); | ||
| 251 | } | ||
| 252 | |||
| 253 | pub fn addArtifactArg2(run: *Run, artifact: *Step.Compile, options: PathArgOptions) void { | ||
| 227 | const graph = run.step.owner.graph; | 254 | const graph = run.step.owner.graph; |
| 228 | const arena = graph.arena; | 255 | const arena = graph.arena; |
| 229 | 256 | ||
| 230 | const prefixed_artifact: PrefixedArtifact = .{ | 257 | const prefixed_artifact: DecoratedArtifact = .{ |
| 231 | .prefix = graph.dupeString(prefix), | 258 | .prefix = graph.dupeString(options.prefix), |
| 232 | .artifact = artifact, | 259 | .artifact = artifact, |
| 260 | .suffix = graph.dupeString(options.suffix), | ||
| 261 | .make_absolute = options.make_absolute, | ||
| 233 | }; | 262 | }; |
| 234 | run.argv.append(arena, .{ .artifact = prefixed_artifact }) catch @panic("OOM"); | 263 | run.argv.append(arena, .{ .artifact = prefixed_artifact }) catch @panic("OOM"); |
| 235 | 264 | ||
| ... | @@ -237,19 +266,18 @@ pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Com | ... | @@ -237,19 +266,18 @@ pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Com |
| 237 | bin_file.addStepDependencies(&run.step); | 266 | bin_file.addStepDependencies(&run.step); |
| 238 | } | 267 | } |
| 239 | 268 | ||
| 240 | /// Provides a file path as a command line argument to the command being run. | 269 | /// Deprecated, use `addOutputFileArg2`. |
| 241 | /// | ||
| 242 | /// Returns a `std.Build.LazyPath` which can be used as inputs to other APIs | ||
| 243 | /// throughout the build system. | ||
| 244 | /// | ||
| 245 | /// `sub_path` is the name of the generated output file which may have zero or | ||
| 246 | /// more path components. | ||
| 247 | /// | ||
| 248 | /// Related: | ||
| 249 | /// * `addPrefixedOutputFileArg` - same thing but prepends a string to the argument | ||
| 250 | /// * `addFileArg` - for input files given to the child process | ||
| 251 | pub fn addOutputFileArg(run: *Run, sub_path: []const u8) std.Build.LazyPath { | 270 | pub fn addOutputFileArg(run: *Run, sub_path: []const u8) std.Build.LazyPath { |
| 252 | return run.addPrefixedOutputFileArg("", sub_path); | 271 | return run.addOutputFileArg2(sub_path, .{}); |
| 272 | } | ||
| 273 | |||
| 274 | /// Deprecated, use `addOutputFileArg2`. | ||
| 275 | pub fn addPrefixedOutputFileArg( | ||
| 276 | run: *Run, | ||
| 277 | prefix: []const u8, | ||
| 278 | sub_path: []const u8, | ||
| 279 | ) std.Build.LazyPath { | ||
| 280 | return run.addOutputFileArg2(sub_path, .{ .prefix = prefix }); | ||
| 253 | } | 281 | } |
| 254 | 282 | ||
| 255 | /// Provides a file path as a command line argument to the command being run. | 283 | /// Provides a file path as a command line argument to the command being run. |
| ... | @@ -264,16 +292,15 @@ pub fn addOutputFileArg(run: *Run, sub_path: []const u8) std.Build.LazyPath { | ... | @@ -264,16 +292,15 @@ pub fn addOutputFileArg(run: *Run, sub_path: []const u8) std.Build.LazyPath { |
| 264 | /// throughout the build system. | 292 | /// throughout the build system. |
| 265 | /// | 293 | /// |
| 266 | /// Related: | 294 | /// Related: |
| 267 | /// * `addOutputFileArg` - same thing but without the prefix | ||
| 268 | /// * `addFileArg` - for input files given to the child process | 295 | /// * `addFileArg` - for input files given to the child process |
| 269 | pub fn addPrefixedOutputFileArg( | 296 | pub fn addOutputFileArg2( |
| 270 | run: *Run, | 297 | run: *Run, |
| 271 | prefix: []const u8, | ||
| 272 | /// The name of the generated output file which may have zero or more path | 298 | /// The name of the generated output file which may have zero or more path |
| 273 | /// components. | 299 | /// components. |
| 274 | /// | 300 | /// |
| 275 | /// Asserted to be non-empty. | 301 | /// Asserted to be non-empty. |
| 276 | sub_path: []const u8, | 302 | sub_path: []const u8, |
| 303 | options: PathArgOptions, | ||
| 277 | ) std.Build.LazyPath { | 304 | ) std.Build.LazyPath { |
| 278 | const b = run.step.owner; | 305 | const b = run.step.owner; |
| 279 | const graph = b.graph; | 306 | const graph = b.graph; |
| ... | @@ -282,9 +309,11 @@ pub fn addPrefixedOutputFileArg( | ... | @@ -282,9 +309,11 @@ pub fn addPrefixedOutputFileArg( |
| 282 | 309 | ||
| 283 | const output = graph.create(Output); | 310 | const output = graph.create(Output); |
| 284 | output.* = .{ | 311 | output.* = .{ |
| 285 | .prefix = graph.dupeString(prefix), | 312 | .prefix = graph.dupeString(options.prefix), |
| 286 | .basename = graph.dupeString(sub_path), | 313 | .basename = graph.dupeString(sub_path), |
| 314 | .suffix = graph.dupeString(options.suffix), | ||
| 287 | .generated_file = graph.addGeneratedFile(&run.step), | 315 | .generated_file = graph.addGeneratedFile(&run.step), |
| 316 | .make_absolute = options.make_absolute, | ||
| 288 | }; | 317 | }; |
| 289 | run.argv.append(arena, .{ .output_file = output }) catch @panic("OOM"); | 318 | run.argv.append(arena, .{ .output_file = output }) catch @panic("OOM"); |
| 290 | 319 | ||
| ... | @@ -295,17 +324,14 @@ pub fn addPrefixedOutputFileArg( | ... | @@ -295,17 +324,14 @@ pub fn addPrefixedOutputFileArg( |
| 295 | return .{ .generated = .{ .index = output.generated_file } }; | 324 | return .{ .generated = .{ .index = output.generated_file } }; |
| 296 | } | 325 | } |
| 297 | 326 | ||
| 298 | /// Appends an input file to the command line arguments. | 327 | /// See `addFileArg2`. |
| 299 | /// | ||
| 300 | /// The child process will see a file path. Modifications to this file will be | ||
| 301 | /// detected as a cache miss in subsequent builds, causing the child process to | ||
| 302 | /// be re-executed. | ||
| 303 | /// | ||
| 304 | /// Related: | ||
| 305 | /// * `addPrefixedFileArg` - same thing but prepends a string to the argument | ||
| 306 | /// * `addOutputFileArg` - for files generated by the child process | ||
| 307 | pub fn addFileArg(run: *Run, lp: std.Build.LazyPath) void { | 328 | pub fn addFileArg(run: *Run, lp: std.Build.LazyPath) void { |
| 308 | run.addPrefixedFileArg("", lp); | 329 | run.addFileArg2(lp, .{}); |
| 330 | } | ||
| 331 | |||
| 332 | /// See `addFileArg2`. | ||
| 333 | pub fn addPrefixedFileArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { | ||
| 334 | run.addFileArg2(lp, .{ .prefix = prefix }); | ||
| 309 | } | 335 | } |
| 310 | 336 | ||
| 311 | /// Appends an input file to the command line arguments prepended with a string. | 337 | /// Appends an input file to the command line arguments prepended with a string. |
| ... | @@ -318,36 +344,29 @@ pub fn addFileArg(run: *Run, lp: std.Build.LazyPath) void { | ... | @@ -318,36 +344,29 @@ pub fn addFileArg(run: *Run, lp: std.Build.LazyPath) void { |
| 318 | /// subsequent builds, causing the child process to be re-executed. | 344 | /// subsequent builds, causing the child process to be re-executed. |
| 319 | /// | 345 | /// |
| 320 | /// Related: | 346 | /// Related: |
| 321 | /// * `addFileArg` - same thing but without the prefix | ||
| 322 | /// * `addOutputFileArg` - for files generated by the child process | 347 | /// * `addOutputFileArg` - for files generated by the child process |
| 323 | pub fn addPrefixedFileArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { | 348 | pub fn addFileArg2(run: *Run, lp: std.Build.LazyPath, options: PathArgOptions) void { |
| 324 | const graph = run.step.owner.graph; | 349 | const graph = run.step.owner.graph; |
| 325 | const arena = graph.arena; | 350 | const arena = graph.arena; |
| 326 | 351 | ||
| 327 | const prefixed_file_source: PrefixedLazyPath = .{ | 352 | const prefixed_file_source: DecoratedLazyPath = .{ |
| 328 | .prefix = graph.dupeString(prefix), | 353 | .prefix = graph.dupeString(options.prefix), |
| 329 | .lazy_path = lp.dupe(graph), | 354 | .lazy_path = lp.dupe(graph), |
| 355 | .suffix = graph.dupeString(options.suffix), | ||
| 356 | .make_absolute = options.make_absolute, | ||
| 330 | }; | 357 | }; |
| 331 | run.argv.append(arena, .{ .lazy_path = prefixed_file_source }) catch @panic("OOM"); | 358 | run.argv.append(arena, .{ .lazy_path = prefixed_file_source }) catch @panic("OOM"); |
| 332 | lp.addStepDependencies(&run.step); | 359 | lp.addStepDependencies(&run.step); |
| 333 | } | 360 | } |
| 334 | 361 | ||
| 335 | /// Appends the content of an input file to the command line arguments. | 362 | /// Deprecated, use `addFileContentArg2`. |
| 336 | /// | ||
| 337 | /// The child process will see a single argument, even if the file contains whitespace. | ||
| 338 | /// This means that the entire file content up to EOF is rendered as one contiguous | ||
| 339 | /// string, including escape sequences. Notably, any (trailing) newlines will show up | ||
| 340 | /// like this: "hello,\nfile world!\n" | ||
| 341 | /// | ||
| 342 | /// Modifications to the source file will be detected as a cache miss in subsequent | ||
| 343 | /// builds, causing the child process to be re-executed. | ||
| 344 | /// | ||
| 345 | /// This function may not be used to supply the first argument of a `Run` step. | ||
| 346 | /// | ||
| 347 | /// Related: | ||
| 348 | /// * `addPrefixedFileContentArg` - same thing but prepends a string to the argument | ||
| 349 | pub fn addFileContentArg(run: *Run, lp: std.Build.LazyPath) void { | 363 | pub fn addFileContentArg(run: *Run, lp: std.Build.LazyPath) void { |
| 350 | run.addPrefixedFileContentArg("", lp); | 364 | return run.addFileContentArg2(lp, .{}); |
| 365 | } | ||
| 366 | |||
| 367 | /// Deprecated, use `addFileContentArg2`. | ||
| 368 | pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { | ||
| 369 | return run.addFileContentArg2(lp, .{ .prefix = prefix }); | ||
| 351 | } | 370 | } |
| 352 | 371 | ||
| 353 | /// Appends the content of an input file to the command line arguments prepended with a string. | 372 | /// Appends the content of an input file to the command line arguments prepended with a string. |
| ... | @@ -368,7 +387,7 @@ pub fn addFileContentArg(run: *Run, lp: std.Build.LazyPath) void { | ... | @@ -368,7 +387,7 @@ pub fn addFileContentArg(run: *Run, lp: std.Build.LazyPath) void { |
| 368 | /// | 387 | /// |
| 369 | /// Related: | 388 | /// Related: |
| 370 | /// * `addFileContentArg` - same thing but without the prefix | 389 | /// * `addFileContentArg` - same thing but without the prefix |
| 371 | pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { | 390 | pub fn addFileContentArg2(run: *Run, lp: std.Build.LazyPath, options: ArgOptions) void { |
| 372 | const graph = run.step.owner.graph; | 391 | const graph = run.step.owner.graph; |
| 373 | const arena = graph.arena; | 392 | const arena = graph.arena; |
| 374 | 393 | ||
| ... | @@ -379,24 +398,27 @@ pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.La | ... | @@ -379,24 +398,27 @@ pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.La |
| 379 | @panic("'addFileContentArg'/'addPrefixedFileContentArg' cannot be first argument"); | 398 | @panic("'addFileContentArg'/'addPrefixedFileContentArg' cannot be first argument"); |
| 380 | } | 399 | } |
| 381 | 400 | ||
| 382 | const prefixed_file_source: PrefixedLazyPath = .{ | 401 | const file_content: DecoratedFileContent = .{ |
| 383 | .prefix = graph.dupeString(prefix), | 402 | .prefix = graph.dupeString(options.prefix), |
| 384 | .lazy_path = lp.dupe(graph), | 403 | .lazy_path = lp.dupe(graph), |
| 404 | .suffix = graph.dupeString(options.suffix), | ||
| 385 | }; | 405 | }; |
| 386 | run.argv.append(arena, .{ .file_content = prefixed_file_source }) catch @panic("OOM"); | 406 | run.argv.append(arena, .{ .file_content = file_content }) catch @panic("OOM"); |
| 387 | lp.addStepDependencies(&run.step); | 407 | lp.addStepDependencies(&run.step); |
| 388 | } | 408 | } |
| 389 | 409 | ||
| 390 | /// Provides a directory path as a command line argument to the command being run. | 410 | /// Deprecated, use `addOutputDirectoryArg2`. |
| 391 | /// | ||
| 392 | /// Returns a `std.Build.LazyPath` which can be used as inputs to other APIs | ||
| 393 | /// throughout the build system. | ||
| 394 | /// | ||
| 395 | /// Related: | ||
| 396 | /// * `addPrefixedOutputDirectoryArg` - same thing but prepends a string to the argument | ||
| 397 | /// * `addDirectoryArg` - for input directories given to the child process | ||
| 398 | pub fn addOutputDirectoryArg(run: *Run, basename: []const u8) std.Build.LazyPath { | 411 | pub fn addOutputDirectoryArg(run: *Run, basename: []const u8) std.Build.LazyPath { |
| 399 | return run.addPrefixedOutputDirectoryArg("", basename); | 412 | return run.addOutputDirectoryArg2(basename, .{}); |
| 413 | } | ||
| 414 | |||
| 415 | /// Deprecated, use `addOutputDirectoryArg2`. | ||
| 416 | pub fn addPrefixedOutputDirectoryArg( | ||
| 417 | run: *Run, | ||
| 418 | prefix: []const u8, | ||
| 419 | basename: []const u8, | ||
| 420 | ) std.Build.LazyPath { | ||
| 421 | return run.addOutputDirectoryArg2(basename, .{ .prefix = prefix }); | ||
| 400 | } | 422 | } |
| 401 | 423 | ||
| 402 | /// Provides a directory path as a command line argument to the command being run. | 424 | /// Provides a directory path as a command line argument to the command being run. |
| ... | @@ -412,12 +434,11 @@ pub fn addOutputDirectoryArg(run: *Run, basename: []const u8) std.Build.LazyPath | ... | @@ -412,12 +434,11 @@ pub fn addOutputDirectoryArg(run: *Run, basename: []const u8) std.Build.LazyPath |
| 412 | /// throughout the build system. | 434 | /// throughout the build system. |
| 413 | /// | 435 | /// |
| 414 | /// Related: | 436 | /// Related: |
| 415 | /// * `addOutputDirectoryArg` - same thing but without the prefix | ||
| 416 | /// * `addDirectoryArg` - for input directories given to the child process | 437 | /// * `addDirectoryArg` - for input directories given to the child process |
| 417 | pub fn addPrefixedOutputDirectoryArg( | 438 | pub fn addOutputDirectoryArg2( |
| 418 | run: *Run, | 439 | run: *Run, |
| 419 | prefix: []const u8, | ||
| 420 | basename: []const u8, | 440 | basename: []const u8, |
| 441 | options: PathArgOptions, | ||
| 421 | ) std.Build.LazyPath { | 442 | ) std.Build.LazyPath { |
| 422 | if (basename.len == 0) @panic("basename must not be empty"); | 443 | if (basename.len == 0) @panic("basename must not be empty"); |
| 423 | const graph = run.step.owner.graph; | 444 | const graph = run.step.owner.graph; |
| ... | @@ -425,9 +446,11 @@ pub fn addPrefixedOutputDirectoryArg( | ... | @@ -425,9 +446,11 @@ pub fn addPrefixedOutputDirectoryArg( |
| 425 | 446 | ||
| 426 | const output = arena.create(Output) catch @panic("OOM"); | 447 | const output = arena.create(Output) catch @panic("OOM"); |
| 427 | output.* = .{ | 448 | output.* = .{ |
| 428 | .prefix = graph.dupeString(prefix), | 449 | .prefix = graph.dupeString(options.prefix), |
| 429 | .basename = graph.dupeString(basename), | 450 | .basename = graph.dupeString(basename), |
| 451 | .suffix = graph.dupeString(options.suffix), | ||
| 430 | .generated_file = graph.addGeneratedFile(&run.step), | 452 | .generated_file = graph.addGeneratedFile(&run.step), |
| 453 | .make_absolute = options.make_absolute, | ||
| 431 | }; | 454 | }; |
| 432 | run.argv.append(arena, .{ .output_directory = output }) catch @panic("OOM"); | 455 | run.argv.append(arena, .{ .output_directory = output }) catch @panic("OOM"); |
| 433 | 456 | ||
| ... | @@ -438,56 +461,67 @@ pub fn addPrefixedOutputDirectoryArg( | ... | @@ -438,56 +461,67 @@ pub fn addPrefixedOutputDirectoryArg( |
| 438 | return .{ .generated = .{ .index = output.generated_file } }; | 461 | return .{ .generated = .{ .index = output.generated_file } }; |
| 439 | } | 462 | } |
| 440 | 463 | ||
| 464 | /// Deprecated, use `addDirectoryArg2`. | ||
| 441 | pub fn addDirectoryArg(run: *Run, lazy_directory: std.Build.LazyPath) void { | 465 | pub fn addDirectoryArg(run: *Run, lazy_directory: std.Build.LazyPath) void { |
| 442 | run.addDecoratedDirectoryArg("", lazy_directory, ""); | 466 | run.addDirectoryArg2(lazy_directory, .{}); |
| 443 | } | 467 | } |
| 444 | 468 | ||
| 469 | /// Deprecated, use `addDirectoryArg2`. | ||
| 445 | pub fn addPrefixedDirectoryArg(run: *Run, prefix: []const u8, lazy_directory: std.Build.LazyPath) void { | 470 | pub fn addPrefixedDirectoryArg(run: *Run, prefix: []const u8, lazy_directory: std.Build.LazyPath) void { |
| 446 | const graph = run.step.owner.graph; | 471 | run.addDirectoryArg2(lazy_directory, .{ .prefix = prefix }); |
| 447 | const arena = graph.arena; | ||
| 448 | run.argv.append(arena, .{ .decorated_directory = .{ | ||
| 449 | .prefix = graph.dupeString(prefix), | ||
| 450 | .lazy_path = lazy_directory.dupe(graph), | ||
| 451 | .suffix = "", | ||
| 452 | } }) catch @panic("OOM"); | ||
| 453 | lazy_directory.addStepDependencies(&run.step); | ||
| 454 | } | 472 | } |
| 455 | 473 | ||
| 474 | /// Deprecated, use `addDirectoryArg2`. | ||
| 456 | pub fn addDecoratedDirectoryArg( | 475 | pub fn addDecoratedDirectoryArg( |
| 457 | run: *Run, | 476 | run: *Run, |
| 458 | prefix: []const u8, | 477 | prefix: []const u8, |
| 459 | lazy_directory: std.Build.LazyPath, | 478 | lazy_directory: std.Build.LazyPath, |
| 460 | suffix: []const u8, | 479 | suffix: []const u8, |
| 480 | ) void { | ||
| 481 | run.addDirectoryArg2(lazy_directory, .{ .prefix = prefix, .suffix = suffix }); | ||
| 482 | } | ||
| 483 | |||
| 484 | pub fn addDirectoryArg2( | ||
| 485 | run: *Run, | ||
| 486 | lazy_directory: std.Build.LazyPath, | ||
| 487 | options: PathArgOptions, | ||
| 461 | ) void { | 488 | ) void { |
| 462 | const graph = run.step.owner.graph; | 489 | const graph = run.step.owner.graph; |
| 463 | const arena = graph.arena; | 490 | const arena = graph.arena; |
| 464 | run.argv.append(arena, .{ .decorated_directory = .{ | 491 | run.argv.append(arena, .{ .decorated_directory = .{ |
| 465 | .prefix = graph.dupeString(prefix), | 492 | .prefix = graph.dupeString(options.prefix), |
| 466 | .lazy_path = lazy_directory.dupe(graph), | 493 | .lazy_path = lazy_directory.dupe(graph), |
| 467 | .suffix = graph.dupeString(suffix), | 494 | .suffix = graph.dupeString(options.suffix), |
| 495 | .make_absolute = options.make_absolute, | ||
| 468 | } }) catch @panic("OOM"); | 496 | } }) catch @panic("OOM"); |
| 469 | lazy_directory.addStepDependencies(&run.step); | 497 | lazy_directory.addStepDependencies(&run.step); |
| 470 | } | 498 | } |
| 471 | 499 | ||
| 472 | /// Add a path argument to a dep file (.d) for the child process to write its | 500 | /// Deprecated, use `addDepFileOutputArg2`. |
| 473 | /// discovered additional dependencies. | ||
| 474 | /// Only one dep file argument is allowed by instance. | ||
| 475 | pub fn addDepFileOutputArg(run: *Run, basename: []const u8) std.Build.LazyPath { | 501 | pub fn addDepFileOutputArg(run: *Run, basename: []const u8) std.Build.LazyPath { |
| 476 | return run.addPrefixedDepFileOutputArg("", basename); | 502 | return run.addDepFileOutputArg2(basename, .{}); |
| 477 | } | 503 | } |
| 478 | 504 | ||
| 479 | /// Add a prefixed path argument to a dep file (.d) for the child process to | 505 | /// Deprecated, use `addDepFileOutputArg2`. |
| 480 | /// write its discovered additional dependencies. | ||
| 481 | pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []const u8) std.Build.LazyPath { | 506 | pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []const u8) std.Build.LazyPath { |
| 507 | return run.addDepFileOutputArg2(basename, .{ .prefix = prefix }); | ||
| 508 | } | ||
| 509 | |||
| 510 | /// Add a path argument to a dep file (.d) for the child process to write its | ||
| 511 | /// discovered additional dependencies. | ||
| 512 | /// Only one dep file argument is allowed by instance. | ||
| 513 | pub fn addDepFileOutputArg2(run: *Run, basename: []const u8, options: PathArgOptions) std.Build.LazyPath { | ||
| 482 | const b = run.step.owner; | 514 | const b = run.step.owner; |
| 483 | const graph = b.graph; | 515 | const graph = b.graph; |
| 484 | const arena = graph.arena; | 516 | const arena = graph.arena; |
| 485 | 517 | ||
| 486 | const dep_file = arena.create(Output) catch @panic("OOM"); | 518 | const dep_file = arena.create(Output) catch @panic("OOM"); |
| 487 | dep_file.* = .{ | 519 | dep_file.* = .{ |
| 488 | .prefix = graph.dupeString(prefix), | 520 | .prefix = graph.dupeString(options.prefix), |
| 489 | .basename = graph.dupeString(basename), | 521 | .basename = graph.dupeString(basename), |
| 522 | .suffix = graph.dupeString(options.suffix), | ||
| 490 | .generated_file = graph.addGeneratedFile(&run.step), | 523 | .generated_file = graph.addGeneratedFile(&run.step), |
| 524 | .make_absolute = options.make_absolute, | ||
| 491 | }; | 525 | }; |
| 492 | 526 | ||
| 493 | run.argv.append(arena, .{ .output_file_dep = dep_file }) catch @panic("OOM"); | 527 | run.argv.append(arena, .{ .output_file_dep = dep_file }) catch @panic("OOM"); |
| ... | @@ -642,19 +676,17 @@ pub fn captureStdErr(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa | ... | @@ -642,19 +676,17 @@ pub fn captureStdErr(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa |
| 642 | const graph = b.graph; | 676 | const graph = b.graph; |
| 643 | const arena = graph.arena; | 677 | const arena = graph.arena; |
| 644 | 678 | ||
| 645 | if (run.captured_stderr) |captured| return .{ .generated = .{ .index = captured.output.generated_file } }; | 679 | if (run.captured_stderr) |captured| return .{ .generated = .{ .index = captured.generated_file } }; |
| 646 | 680 | ||
| 647 | const captured = arena.create(CapturedStdIo) catch @panic("OOM"); | 681 | const captured = arena.create(CapturedStdIo) catch @panic("OOM"); |
| 648 | captured.* = .{ | 682 | captured.* = .{ |
| 649 | .output = .{ | 683 | .prefix = "", |
| 650 | .prefix = "", | 684 | .basename = if (options.basename) |basename| graph.dupeString(basename) else "stderr", |
| 651 | .basename = if (options.basename) |basename| graph.dupeString(basename) else "stderr", | 685 | .generated_file = graph.addGeneratedFile(&run.step), |
| 652 | .generated_file = graph.addGeneratedFile(&run.step), | ||
| 653 | }, | ||
| 654 | .trim_whitespace = options.trim_whitespace, | 686 | .trim_whitespace = options.trim_whitespace, |
| 655 | }; | 687 | }; |
| 656 | run.captured_stderr = captured; | 688 | run.captured_stderr = captured; |
| 657 | return .{ .generated = .{ .index = captured.output.generated_file } }; | 689 | return .{ .generated = .{ .index = captured.generated_file } }; |
| 658 | } | 690 | } |
| 659 | 691 | ||
| 660 | pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPath { | 692 | pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPath { |
| ... | @@ -665,19 +697,17 @@ pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa | ... | @@ -665,19 +697,17 @@ pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa |
| 665 | const graph = b.graph; | 697 | const graph = b.graph; |
| 666 | const arena = graph.arena; | 698 | const arena = graph.arena; |
| 667 | 699 | ||
| 668 | if (run.captured_stdout) |captured| return .{ .generated = .{ .index = captured.output.generated_file } }; | 700 | if (run.captured_stdout) |captured| return .{ .generated = .{ .index = captured.generated_file } }; |
| 669 | 701 | ||
| 670 | const captured = arena.create(CapturedStdIo) catch @panic("OOM"); | 702 | const captured = arena.create(CapturedStdIo) catch @panic("OOM"); |
| 671 | captured.* = .{ | 703 | captured.* = .{ |
| 672 | .output = .{ | 704 | .prefix = "", |
| 673 | .prefix = "", | 705 | .basename = if (options.basename) |basename| graph.dupeString(basename) else "stdout", |
| 674 | .basename = if (options.basename) |basename| graph.dupeString(basename) else "stdout", | 706 | .generated_file = graph.addGeneratedFile(&run.step), |
| 675 | .generated_file = graph.addGeneratedFile(&run.step), | ||
| 676 | }, | ||
| 677 | .trim_whitespace = options.trim_whitespace, | 707 | .trim_whitespace = options.trim_whitespace, |
| 678 | }; | 708 | }; |
| 679 | run.captured_stdout = captured; | 709 | run.captured_stdout = captured; |
| 680 | return .{ .generated = .{ .index = captured.output.generated_file } }; | 710 | return .{ .generated = .{ .index = captured.generated_file } }; |
| 681 | } | 711 | } |
| 682 | 712 | ||
| 683 | /// Adds an additional input files that, when modified, indicates that this Run | 713 | /// Adds an additional input files that, when modified, indicates that this Run |
test/standalone/build.zig.zon+3| ... | @@ -196,6 +196,9 @@ | ... | @@ -196,6 +196,9 @@ |
| 196 | .elf2 = .{ | 196 | .elf2 = .{ |
| 197 | .path = "elf2", | 197 | .path = "elf2", |
| 198 | }, | 198 | }, |
| 199 | .run_args = .{ | ||
| 200 | .path = "run_args", | ||
| 201 | }, | ||
| 199 | }, | 202 | }, |
| 200 | .paths = .{ | 203 | .paths = .{ |
| 201 | "build.zig", | 204 | "build.zig", |
test/standalone/run_args/build.zig created+160| ... | @@ -0,0 +1,160 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | /// Tests that args are passed to run steps correctly. | ||
| 4 | /// | ||
| 5 | /// Note that when `make_absolute` is true we make sure the resulting path argument is absolute, but | ||
| 6 | /// when it is false we allow either absolute or relative paths. This is because the maker receives | ||
| 7 | /// absolute paths when build is run from anywhere other than the build root. | ||
| 8 | pub fn build(b: *std.Build) !void { | ||
| 9 | const step = b.step("test", "Run artifact args standalone test cases"); | ||
| 10 | b.default_step = step; | ||
| 11 | |||
| 12 | const exe = b.addExecutable(.{ | ||
| 13 | .name = "exe", | ||
| 14 | .root_module = b.createModule(.{ | ||
| 15 | .root_source_file = b.path("main.zig"), | ||
| 16 | .target = b.graph.host, | ||
| 17 | }), | ||
| 18 | }); | ||
| 19 | |||
| 20 | // Arg | ||
| 21 | { | ||
| 22 | const run = b.addRunArtifact(exe); | ||
| 23 | step.dependOn(&run.step); | ||
| 24 | run.addArg("arg1"); | ||
| 25 | run.expectStdErrEqual("arg1\n"); | ||
| 26 | } | ||
| 27 | |||
| 28 | // Args | ||
| 29 | { | ||
| 30 | const run = b.addRunArtifact(exe); | ||
| 31 | step.dependOn(&run.step); | ||
| 32 | run.addArgs(&.{ "arg1", "arg2" }); | ||
| 33 | run.expectStdErrEqual("arg1\narg2\n"); | ||
| 34 | } | ||
| 35 | |||
| 36 | // Artifact Args | ||
| 37 | { | ||
| 38 | // Absolute | ||
| 39 | { | ||
| 40 | const run = b.addRunArtifact(exe); | ||
| 41 | step.dependOn(&run.step); | ||
| 42 | _ = run.addArtifactArg2(exe, .{ .prefix = "path^", .make_absolute = true, .suffix = "$" }); | ||
| 43 | run.expectStdErrMatch("abs exe"); | ||
| 44 | } | ||
| 45 | // Relative | ||
| 46 | { | ||
| 47 | const run = b.addRunArtifact(exe); | ||
| 48 | step.dependOn(&run.step); | ||
| 49 | _ = run.addArtifactArg2(exe, .{ .prefix = "path^", .make_absolute = false, .suffix = "$" }); | ||
| 50 | run.expectStdErrMatch("exe\n"); | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | // File Args | ||
| 55 | { | ||
| 56 | const write_files = b.addWriteFiles(); | ||
| 57 | const file = write_files.add("file", ""); | ||
| 58 | |||
| 59 | // Absolute | ||
| 60 | { | ||
| 61 | const run = b.addRunArtifact(exe); | ||
| 62 | step.dependOn(&run.step); | ||
| 63 | _ = run.addFileArg2(file, .{ .prefix = "path^", .make_absolute = true, .suffix = "$" }); | ||
| 64 | run.expectStdErrEqual("abs file\n"); | ||
| 65 | } | ||
| 66 | // Relative | ||
| 67 | { | ||
| 68 | const run = b.addRunArtifact(exe); | ||
| 69 | step.dependOn(&run.step); | ||
| 70 | _ = run.addFileArg2(file, .{ .prefix = "path^", .make_absolute = false, .suffix = "$" }); | ||
| 71 | run.expectStdErrMatch("file\n"); | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | // File Content | ||
| 76 | { | ||
| 77 | const write_files = b.addWriteFiles(); | ||
| 78 | const file = write_files.add("file", "foo bar baz"); | ||
| 79 | |||
| 80 | const run = b.addRunArtifact(exe); | ||
| 81 | step.dependOn(&run.step); | ||
| 82 | _ = run.addFileContentArg2(file, .{ .prefix = "content-prefix ", .suffix = " content-suffix" }); | ||
| 83 | run.expectStdErrEqual("content-prefix foo bar baz content-suffix\n"); | ||
| 84 | } | ||
| 85 | |||
| 86 | // Output File Args | ||
| 87 | { | ||
| 88 | // Absolute | ||
| 89 | { | ||
| 90 | const run = b.addRunArtifact(exe); | ||
| 91 | step.dependOn(&run.step); | ||
| 92 | _ = run.addOutputFileArg2("output-file", .{ .prefix = "path^", .make_absolute = true, .suffix = "$" }); | ||
| 93 | run.expectStdErrEqual("abs output-file\n"); | ||
| 94 | } | ||
| 95 | // Relative | ||
| 96 | { | ||
| 97 | const run = b.addRunArtifact(exe); | ||
| 98 | step.dependOn(&run.step); | ||
| 99 | _ = run.addOutputFileArg2("output-file", .{ .prefix = "path^", .make_absolute = false, .suffix = "$" }); | ||
| 100 | run.expectStdErrMatch("output-file\n"); | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | // Output Directory Args | ||
| 105 | { | ||
| 106 | // Absolute | ||
| 107 | { | ||
| 108 | const run = b.addRunArtifact(exe); | ||
| 109 | step.dependOn(&run.step); | ||
| 110 | _ = run.addOutputDirectoryArg2("output-dir", .{ .prefix = "path^", .make_absolute = true, .suffix = "$" }); | ||
| 111 | run.expectStdErrEqual("abs output-dir\n"); | ||
| 112 | } | ||
| 113 | // Relative | ||
| 114 | { | ||
| 115 | const run = b.addRunArtifact(exe); | ||
| 116 | step.dependOn(&run.step); | ||
| 117 | _ = run.addOutputDirectoryArg2("output-dir", .{ .prefix = "path^", .make_absolute = false, .suffix = "$" }); | ||
| 118 | run.expectStdErrMatch("output-dir\n"); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | // Directory Args | ||
| 123 | { | ||
| 124 | const write_files = b.addWriteFiles(); | ||
| 125 | const directory = try write_files.getDirectory().join(b.graph.arena, "dir"); | ||
| 126 | |||
| 127 | // Absolute | ||
| 128 | { | ||
| 129 | const run = b.addRunArtifact(exe); | ||
| 130 | step.dependOn(&run.step); | ||
| 131 | _ = run.addDirectoryArg2(directory, .{ .prefix = "path^", .make_absolute = true, .suffix = "$" }); | ||
| 132 | run.expectStdErrEqual("abs dir\n"); | ||
| 133 | } | ||
| 134 | // Relative | ||
| 135 | { | ||
| 136 | const run = b.addRunArtifact(exe); | ||
| 137 | step.dependOn(&run.step); | ||
| 138 | _ = run.addDirectoryArg2(directory, .{ .prefix = "path^", .make_absolute = false, .suffix = "$" }); | ||
| 139 | run.expectStdErrMatch("dir\n"); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 143 | // Dep File Args | ||
| 144 | { | ||
| 145 | // Absolute | ||
| 146 | { | ||
| 147 | const run = b.addRunArtifact(exe); | ||
| 148 | step.dependOn(&run.step); | ||
| 149 | _ = run.addDepFileOutputArg2("deps.d", .{ .prefix = "path^", .make_absolute = true, .suffix = "$" }); | ||
| 150 | run.expectStdErrEqual("abs deps.d\n"); | ||
| 151 | } | ||
| 152 | // Relative | ||
| 153 | { | ||
| 154 | const run = b.addRunArtifact(exe); | ||
| 155 | step.dependOn(&run.step); | ||
| 156 | _ = run.addDepFileOutputArg2("deps.d", .{ .prefix = "path^", .make_absolute = false, .suffix = "$" }); | ||
| 157 | run.expectStdErrMatch("deps.d\n"); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
test/standalone/run_args/main.zig created+32| ... | @@ -0,0 +1,32 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn main(init: std.process.Init) !void { | ||
| 4 | const io = init.io; | ||
| 5 | const arena = init.arena.allocator(); | ||
| 6 | |||
| 7 | var iter = try init.minimal.args.iterateAllocator(arena); | ||
| 8 | std.debug.assert(iter.skip()); | ||
| 9 | while (iter.next()) |arg| { | ||
| 10 | const path_prefix = "path^"; | ||
| 11 | const path_suffix = "$"; | ||
| 12 | if (std.mem.startsWith(u8, arg, path_prefix) and std.mem.endsWith(u8, arg, path_suffix)) { | ||
| 13 | // If we're a path, log whether we're absolute or relative, and log the basename | ||
| 14 | const path = arg[path_prefix.len..][0 .. arg.len - path_prefix.len - path_suffix.len]; | ||
| 15 | if (std.fs.path.isAbsolute(path)) { | ||
| 16 | std.debug.print("abs ", .{}); | ||
| 17 | } else { | ||
| 18 | std.debug.print("rel ", .{}); | ||
| 19 | } | ||
| 20 | std.debug.print("{s}\n", .{std.fs.path.basename(path)}); | ||
| 21 | |||
| 22 | // Create an empty dep file if necessary | ||
| 23 | if (std.mem.endsWith(u8, path, ".d")) { | ||
| 24 | const file = try std.Io.Dir.cwd().createFile(io, path, .{}); | ||
| 25 | defer file.close(io); | ||
| 26 | } | ||
| 27 | } else { | ||
| 28 | // If it's not a path, log the arg as is | ||
| 29 | std.debug.print("{s}\n", .{arg}); | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||