authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-05-08 19:36:11-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-05-08 19:36:11-07:00
log6bc0cef607e2007234d04f369dac7e5e382b0aad
tree422000c3e569f16e60bd9ade44bac0e1f8aabda1
parent5c9eb408167672f1389c6fe58bb7851be80204de
parentdee9f82f69db0d034251b844e0bc4083a1b25fdd
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19826 from jacobly0/outdirarg

Run: add output directory arguments

63 files changed, 1611 insertions(+), 1430 deletions(-)

doc/langref/Assembly Syntax Explained.zig +36-36
...@@ -15,44 +15,44 @@ pub fn syscall1(number: usize, arg1: usize) usize {...@@ -15,44 +15,44 @@ pub fn syscall1(number: usize, arg1: usize) usize {
15 // the below code, this is not used. A literal `%` can be15 // the below code, this is not used. A literal `%` can be
16 // obtained by escaping it with a double percent: `%%`.16 // obtained by escaping it with a double percent: `%%`.
17 // Often multiline string syntax comes in handy here.17 // Often multiline string syntax comes in handy here.
18 \\syscall18 \\syscall
19 // Next is the output. It is possible in the future Zig will19 // Next is the output. It is possible in the future Zig will
20 // support multiple outputs, depending on how20 // support multiple outputs, depending on how
21 // https://github.com/ziglang/zig/issues/215 is resolved.21 // https://github.com/ziglang/zig/issues/215 is resolved.
22 // It is allowed for there to be no outputs, in which case22 // It is allowed for there to be no outputs, in which case
23 // this colon would be directly followed by the colon for the inputs.23 // this colon would be directly followed by the colon for the inputs.
24 :24 :
25 // This specifies the name to be used in `%[ret]` syntax in25 // This specifies the name to be used in `%[ret]` syntax in
26 // the above assembly string. This example does not use it,26 // the above assembly string. This example does not use it,
27 // but the syntax is mandatory.27 // but the syntax is mandatory.
28 [ret]28 [ret]
29 // Next is the output constraint string. This feature is still29 // Next is the output constraint string. This feature is still
30 // considered unstable in Zig, and so LLVM/GCC documentation30 // considered unstable in Zig, and so LLVM/GCC documentation
31 // must be used to understand the semantics.31 // must be used to understand the semantics.
32 // http://releases.llvm.org/10.0.0/docs/LangRef.html#inline-asm-constraint-string32 // http://releases.llvm.org/10.0.0/docs/LangRef.html#inline-asm-constraint-string
33 // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html33 // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
34 // In this example, the constraint string means "the result value of34 // In this example, the constraint string means "the result value of
35 // this inline assembly instruction is whatever is in $rax".35 // this inline assembly instruction is whatever is in $rax".
36 "={rax}"36 "={rax}"
37 // Next is either a value binding, or `->` and then a type. The37 // Next is either a value binding, or `->` and then a type. The
38 // type is the result type of the inline assembly expression.38 // type is the result type of the inline assembly expression.
39 // If it is a value binding, then `%[ret]` syntax would be used39 // If it is a value binding, then `%[ret]` syntax would be used
40 // to refer to the register bound to the value.40 // to refer to the register bound to the value.
41 (-> usize),41 (-> usize),
42 // Next is the list of inputs.42 // Next is the list of inputs.
43 // The constraint for these inputs means, "when the assembly code is43 // The constraint for these inputs means, "when the assembly code is
44 // executed, $rax shall have the value of `number` and $rdi shall have44 // executed, $rax shall have the value of `number` and $rdi shall have
45 // the value of `arg1`". Any number of input parameters is allowed,45 // the value of `arg1`". Any number of input parameters is allowed,
46 // including none.46 // including none.
47 : [number] "{rax}" (number),47 : [number] "{rax}" (number),
48 [arg1] "{rdi}" (arg1),48 [arg1] "{rdi}" (arg1),
49 // Next is the list of clobbers. These declare a set of registers whose49 // Next is the list of clobbers. These declare a set of registers whose
50 // values will not be preserved by the execution of this assembly code.50 // values will not be preserved by the execution of this assembly code.
51 // These do not include output or input registers. The special clobber51 // These do not include output or input registers. The special clobber
52 // value of "memory" means that the assembly writes to arbitrary undeclared52 // value of "memory" means that the assembly writes to arbitrary undeclared
53 // memory locations - not only the memory pointed to by a declared indirect53 // memory locations - not only the memory pointed to by a declared indirect
54 // output. In this example we list $rcx and $r11 because it is known the54 // output. In this example we list $rcx and $r11 because it is known the
55 // kernel syscall does not preserve these registers.55 // kernel syscall does not preserve these registers.
56 : "rcx", "r11"56 : "rcx", "r11"
57 );57 );
58}58}
doc/langref/build.zig+1-1
...@@ -4,7 +4,7 @@ pub fn build(b: *std.Build) void {...@@ -4,7 +4,7 @@ pub fn build(b: *std.Build) void {
4 const optimize = b.standardOptimizeOption(.{});4 const optimize = b.standardOptimizeOption(.{});
5 const exe = b.addExecutable(.{5 const exe = b.addExecutable(.{
6 .name = "example",6 .name = "example",
7 .root_source_file = .{ .path = "example.zig" },7 .root_source_file = b.path("example.zig"),
8 .optimize = optimize,8 .optimize = optimize,
9 });9 });
10 b.default_step.dependOn(&exe.step);10 b.default_step.dependOn(&exe.step);
doc/langref/build_c.zig+2-2
...@@ -3,13 +3,13 @@ const std = @import("std");...@@ -3,13 +3,13 @@ const std = @import("std");
3pub fn build(b: *std.Build) void {3pub fn build(b: *std.Build) void {
4 const lib = b.addSharedLibrary(.{4 const lib = b.addSharedLibrary(.{
5 .name = "mathtest",5 .name = "mathtest",
6 .root_source_file = .{ .path = "mathtest.zig" },6 .root_source_file = b.path("mathtest.zig"),
7 .version = .{ .major = 1, .minor = 0, .patch = 0 },7 .version = .{ .major = 1, .minor = 0, .patch = 0 },
8 });8 });
9 const exe = b.addExecutable(.{9 const exe = b.addExecutable(.{
10 .name = "test",10 .name = "test",
11 });11 });
12 exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &.{"-std=c99"} });12 exe.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{"-std=c99"} });
13 exe.linkLibrary(lib);13 exe.linkLibrary(lib);
14 exe.linkSystemLibrary("c");14 exe.linkSystemLibrary("c");
1515
doc/langref/build_object.zig+2-2
...@@ -3,13 +3,13 @@ const std = @import("std");...@@ -3,13 +3,13 @@ const std = @import("std");
3pub fn build(b: *std.Build) void {3pub fn build(b: *std.Build) void {
4 const obj = b.addObject(.{4 const obj = b.addObject(.{
5 .name = "base64",5 .name = "base64",
6 .root_source_file = .{ .path = "base64.zig" },6 .root_source_file = b.path("base64.zig"),
7 });7 });
88
9 const exe = b.addExecutable(.{9 const exe = b.addExecutable(.{
10 .name = "test",10 .name = "test",
11 });11 });
12 exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &.{"-std=c99",} });12 exe.addCSourceFile(.{ .file = b.path("test.c"), .flags = &.{"-std=c99"} });
13 exe.addObject(obj);13 exe.addObject(obj);
14 exe.linkSystemLibrary("c");14 exe.linkSystemLibrary("c");
15 b.installArtifact(exe);15 b.installArtifact(exe);
doc/langref/checking_null_in_zig.zig+5-3
...@@ -1,11 +1,13 @@...@@ -1,11 +1,13 @@
1const Foo = struct{};1const Foo = struct {};
2fn doSomethingWithFoo(foo: *Foo) void { _ = foo; }2fn doSomethingWithFoo(foo: *Foo) void {
3 _ = foo;
4}
35
4fn doAThing(optional_foo: ?*Foo) void {6fn doAThing(optional_foo: ?*Foo) void {
5 // do some stuff7 // do some stuff
68
7 if (optional_foo) |foo| {9 if (optional_foo) |foo| {
8 doSomethingWithFoo(foo);10 doSomethingWithFoo(foo);
9 }11 }
1012
11 // do some stuff13 // do some stuff
doc/langref/doc_comments.zig+1-1
...@@ -2,7 +2,7 @@...@@ -2,7 +2,7 @@
2/// multiline doc comment).2/// multiline doc comment).
3const Timestamp = struct {3const Timestamp = struct {
4 /// The number of seconds since the epoch (this is also a doc comment).4 /// The number of seconds since the epoch (this is also a doc comment).
5 seconds: i64, // signed so we can represent pre-1970 (not a doc comment)5 seconds: i64, // signed so we can represent pre-1970 (not a doc comment)
6 /// The number of nanoseconds past the second (doc comment again).6 /// The number of nanoseconds past the second (doc comment again).
7 nanos: u32,7 nanos: u32,
88
doc/langref/enum_export.zig+3-1
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1const Foo = enum(c_int) { a, b, c };1const Foo = enum(c_int) { a, b, c };
2export fn entry(foo: Foo) void { _ = foo; }2export fn entry(foo: Foo) void {
3 _ = foo;
4}
35
4// obj6// obj
doc/langref/enum_export_error.zig+3-1
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1const Foo = enum { a, b, c };1const Foo = enum { a, b, c };
2export fn entry(foo: Foo) void { _ = foo; }2export fn entry(foo: Foo) void {
3 _ = foo;
4}
35
4// obj=parameter of type 'enum_export_error.Foo' not allowed in function with calling convention 'C'6// obj=parameter of type 'enum_export_error.Foo' not allowed in function with calling convention 'C'
doc/langref/error_union_parsing_u64.zig+3-3
...@@ -26,9 +26,9 @@ pub fn parseU64(buf: []const u8, radix: u8) !u64 {...@@ -26,9 +26,9 @@ pub fn parseU64(buf: []const u8, radix: u8) !u64 {
2626
27fn charToDigit(c: u8) u8 {27fn charToDigit(c: u8) u8 {
28 return switch (c) {28 return switch (c) {
29 '0' ... '9' => c - '0',29 '0'...'9' => c - '0',
30 'A' ... 'Z' => c - 'A' + 10,30 'A'...'Z' => c - 'A' + 10,
31 'a' ... 'z' => c - 'a' + 10,31 'a'...'z' => c - 'a' + 10,
32 else => maxInt(u8),32 else => maxInt(u8),
33 };33 };
34}34}
doc/langref/identifiers.zig+2-2
...@@ -6,8 +6,8 @@ pub extern "c" fn @"error"() void;...@@ -6,8 +6,8 @@ pub extern "c" fn @"error"() void;
6pub extern "c" fn @"fstat$INODE64"(fd: c.fd_t, buf: *c.Stat) c_int;6pub extern "c" fn @"fstat$INODE64"(fd: c.fd_t, buf: *c.Stat) c_int;
77
8const Color = enum {8const Color = enum {
9 red,9 red,
10 @"really red",10 @"really red",
11};11};
12const color: Color = .@"really red";12const color: Color = .@"really red";
1313
doc/langref/print.zig+1-1
...@@ -4,7 +4,7 @@ const a_number: i32 = 1234;...@@ -4,7 +4,7 @@ const a_number: i32 = 1234;
4const a_string = "foobar";4const a_string = "foobar";
55
6pub fn main() void {6pub fn main() void {
7 print("here is a string: '{s}' here is a number: {}\n", .{a_string, a_number});7 print("here is a string: '{s}' here is a number: {}\n", .{ a_string, a_number });
8}8}
99
10// exe=succeed10// exe=succeed
doc/langref/print_comptime-known_format.zig+1-1
...@@ -5,7 +5,7 @@ const a_string = "foobar";...@@ -5,7 +5,7 @@ const a_string = "foobar";
5const fmt = "here is a string: '{s}' here is a number: {}\n";5const fmt = "here is a string: '{s}' here is a number: {}\n";
66
7pub fn main() void {7pub fn main() void {
8 print(fmt, .{a_string, a_number});8 print(fmt, .{ a_string, a_number });
9}9}
1010
11// exe=succeed11// exe=succeed
doc/langref/single_value_error_set.zig+1-1
...@@ -1,3 +1,3 @@...@@ -1,3 +1,3 @@
1const err = (error {FileNotFound}).FileNotFound;1const err = (error{FileNotFound}).FileNotFound;
22
3// syntax3// syntax
doc/langref/string_literals.zig+10-10
...@@ -3,19 +3,19 @@ const mem = @import("std").mem; // will be used to compare bytes...@@ -3,19 +3,19 @@ const mem = @import("std").mem; // will be used to compare bytes
33
4pub fn main() void {4pub fn main() void {
5 const bytes = "hello";5 const bytes = "hello";
6 print("{}\n", .{@TypeOf(bytes)}); // *const [5:0]u86 print("{}\n", .{@TypeOf(bytes)}); // *const [5:0]u8
7 print("{d}\n", .{bytes.len}); // 57 print("{d}\n", .{bytes.len}); // 5
8 print("{c}\n", .{bytes[1]}); // 'e'8 print("{c}\n", .{bytes[1]}); // 'e'
9 print("{d}\n", .{bytes[5]}); // 09 print("{d}\n", .{bytes[5]}); // 0
10 print("{}\n", .{'e' == '\x65'}); // true10 print("{}\n", .{'e' == '\x65'}); // true
11 print("{d}\n", .{'\u{1f4a9}'}); // 12816911 print("{d}\n", .{'\u{1f4a9}'}); // 128169
12 print("{d}\n", .{'💯'}); // 12817512 print("{d}\n", .{'💯'}); // 128175
13 print("{u}\n", .{'âš¡'});13 print("{u}\n", .{'âš¡'});
14 print("{}\n", .{mem.eql(u8, "hello", "h\x65llo")}); // true14 print("{}\n", .{mem.eql(u8, "hello", "h\x65llo")}); // true
15 print("{}\n", .{mem.eql(u8, "💯", "\xf0\x9f\x92\xaf")}); // also true15 print("{}\n", .{mem.eql(u8, "💯", "\xf0\x9f\x92\xaf")}); // also true
16 const invalid_utf8 = "\xff\xfe"; // non-UTF-8 strings are possible with \xNN notation.16 const invalid_utf8 = "\xff\xfe"; // non-UTF-8 strings are possible with \xNN notation.
17 print("0x{x}\n", .{invalid_utf8[1]}); // indexing them returns individual bytes...17 print("0x{x}\n", .{invalid_utf8[1]}); // indexing them returns individual bytes...
18 print("0x{x}\n", .{"💯"[1]}); // ...as does indexing part-way through non-ASCII characters18 print("0x{x}\n", .{"💯"[1]}); // ...as does indexing part-way through non-ASCII characters
19}19}
2020
21// exe=succeed21// exe=succeed
doc/langref/test_call_builtin.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const expect = @import("std").testing.expect;1const expect = @import("std").testing.expect;
22
3test "noinline function call" {3test "noinline function call" {
4 try expect(@call(.auto, add, .{3, 9}) == 12);4 try expect(@call(.auto, add, .{ 3, 9 }) == 12);
5}5}
66
7fn add(a: i32, b: i32) i32 {7fn add(a: i32, b: i32) i32 {
doc/langref/test_coerce_error_subset_to_superset.zig+2-2
...@@ -1,12 +1,12 @@...@@ -1,12 +1,12 @@
1const std = @import("std");1const std = @import("std");
22
3const FileOpenError = error {3const FileOpenError = error{
4 AccessDenied,4 AccessDenied,
5 OutOfMemory,5 OutOfMemory,
6 FileNotFound,6 FileNotFound,
7};7};
88
9const AllocationError = error {9const AllocationError = error{
10 OutOfMemory,10 OutOfMemory,
11};11};
1212
doc/langref/test_coerce_error_superset_to_subset.zig+2-2
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1const FileOpenError = error {1const FileOpenError = error{
2 AccessDenied,2 AccessDenied,
3 OutOfMemory,3 OutOfMemory,
4 FileNotFound,4 FileNotFound,
5};5};
66
7const AllocationError = error {7const AllocationError = error{
8 OutOfMemory,8 OutOfMemory,
9};9};
1010
doc/langref/test_coerce_tuples_arrays.zig+4-4
...@@ -1,11 +1,11 @@...@@ -1,11 +1,11 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
33
4const Tuple = struct{ u8, u8 };4const Tuple = struct { u8, u8 };
5test "coercion from homogenous tuple to array" {5test "coercion from homogenous tuple to array" {
6 const tuple: Tuple = .{5, 6};6 const tuple: Tuple = .{ 5, 6 };
7 const array: [2]u8 = tuple;7 const array: [2]u8 = tuple;
8 _ = array;8 _ = array;
9}9}
1010
11// test11// test
doc/langref/test_comptime_evaluation.zig+13-7
...@@ -2,17 +2,23 @@ const expect = @import("std").testing.expect;...@@ -2,17 +2,23 @@ const expect = @import("std").testing.expect;
22
3const CmdFn = struct {3const CmdFn = struct {
4 name: []const u8,4 name: []const u8,
5 func: fn(i32) i32,5 func: fn (i32) i32,
6};6};
77
8const cmd_fns = [_]CmdFn{8const cmd_fns = [_]CmdFn{
9 CmdFn {.name = "one", .func = one},9 CmdFn{ .name = "one", .func = one },
10 CmdFn {.name = "two", .func = two},10 CmdFn{ .name = "two", .func = two },
11 CmdFn {.name = "three", .func = three},11 CmdFn{ .name = "three", .func = three },
12};12};
13fn one(value: i32) i32 { return value + 1; }13fn one(value: i32) i32 {
14fn two(value: i32) i32 { return value + 2; }14 return value + 1;
15fn three(value: i32) i32 { return value + 3; }15}
16fn two(value: i32) i32 {
17 return value + 2;
18}
19fn three(value: i32) i32 {
20 return value + 3;
21}
1622
17fn performFn(comptime prefix_char: u8, start_value: i32) i32 {23fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
18 var result: i32 = start_value;24 var result: i32 = start_value;
doc/langref/test_errdefer_loop.zig+1-3
...@@ -1,9 +1,7 @@...@@ -1,9 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const Allocator = std.mem.Allocator;2const Allocator = std.mem.Allocator;
33
4const Foo = struct {4const Foo = struct { data: *u32 };
5 data: *u32
6};
75
8fn getData() !u32 {6fn getData() !u32 {
9 return 666;7 return 666;
doc/langref/test_errdefer_loop_leak.zig+2-4
...@@ -1,9 +1,7 @@...@@ -1,9 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const Allocator = std.mem.Allocator;2const Allocator = std.mem.Allocator;
33
4const Foo = struct {4const Foo = struct { data: *u32 };
5 data: *u32
6};
75
8fn getData() !u32 {6fn getData() !u32 {
9 return 666;7 return 666;
...@@ -19,7 +17,7 @@ fn genFoos(allocator: Allocator, num: usize) ![]Foo {...@@ -19,7 +17,7 @@ fn genFoos(allocator: Allocator, num: usize) ![]Foo {
19 errdefer allocator.destroy(foo.data);17 errdefer allocator.destroy(foo.data);
2018
21 // The data for the first 3 foos will be leaked19 // The data for the first 3 foos will be leaked
22 if(i >= 3) return error.TooManyFoos;20 if (i >= 3) return error.TooManyFoos;
2321
24 foo.data.* = try getData();22 foo.data.* = try getData();
25 }23 }
doc/langref/test_for.zig+2-2
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const expect = @import("std").testing.expect;1const expect = @import("std").testing.expect;
22
3test "for basics" {3test "for basics" {
4 const items = [_]i32 { 4, 5, 3, 4, 0 };4 const items = [_]i32{ 4, 5, 3, 4, 0 };
5 var sum: i32 = 0;5 var sum: i32 = 0;
66
7 // For loops iterate over slices and arrays.7 // For loops iterate over slices and arrays.
...@@ -31,7 +31,7 @@ test "for basics" {...@@ -31,7 +31,7 @@ test "for basics" {
3131
32 // To iterate over consecutive integers, use the range syntax.32 // To iterate over consecutive integers, use the range syntax.
33 // Unbounded range is always a compile error.33 // Unbounded range is always a compile error.
34 var sum3 : usize = 0;34 var sum3: usize = 0;
35 for (0..5) |i| {35 for (0..5) |i| {
36 sum3 += i;36 sum3 += i;
37 }37 }
doc/langref/test_functions.zig+7-3
...@@ -14,7 +14,9 @@ fn add(a: i8, b: i8) i8 {...@@ -14,7 +14,9 @@ fn add(a: i8, b: i8) i8 {
1414
15// The export specifier makes a function externally visible in the generated15// The export specifier makes a function externally visible in the generated
16// object file, and makes it use the C ABI.16// object file, and makes it use the C ABI.
17export fn sub(a: i8, b: i8) i8 { return a - b; }17export fn sub(a: i8, b: i8) i8 {
18 return a - b;
19}
1820
19// The extern specifier is used to declare a function that will be resolved21// The extern specifier is used to declare a function that will be resolved
20// at link time, when linking statically, or at runtime, when linking22// at link time, when linking statically, or at runtime, when linking
...@@ -39,13 +41,15 @@ fn _start() callconv(.Naked) noreturn {...@@ -39,13 +41,15 @@ fn _start() callconv(.Naked) noreturn {
3941
40// The inline calling convention forces a function to be inlined at all call sites.42// The inline calling convention forces a function to be inlined at all call sites.
41// If the function cannot be inlined, it is a compile-time error.43// If the function cannot be inlined, it is a compile-time error.
42fn shiftLeftOne(a: u32) callconv(.Inline) u32 {44inline fn shiftLeftOne(a: u32) u32 {
43 return a << 1;45 return a << 1;
44}46}
4547
46// The pub specifier allows the function to be visible when importing.48// The pub specifier allows the function to be visible when importing.
47// Another file can use @import and call sub249// Another file can use @import and call sub2
48pub fn sub2(a: i8, b: i8) i8 { return a - b; }50pub fn sub2(a: i8, b: i8) i8 {
51 return a - b;
52}
4953
50// Function pointers are prefixed with `*const `.54// Function pointers are prefixed with `*const `.
51const Call2Op = *const fn (a: i8, b: i8) i8;55const Call2Op = *const fn (a: i8, b: i8) i8;
doc/langref/test_inferred_error_sets.zig+1-1
...@@ -12,7 +12,7 @@ pub fn add_explicit(comptime T: type, a: T, b: T) Error!T {...@@ -12,7 +12,7 @@ pub fn add_explicit(comptime T: type, a: T, b: T) Error!T {
12 return ov[0];12 return ov[0];
13}13}
1414
15const Error = error {15const Error = error{
16 Overflow,16 Overflow,
17};17};
1818
doc/langref/test_inline_for.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const expect = @import("std").testing.expect;1const expect = @import("std").testing.expect;
22
3test "inline for loop" {3test "inline for loop" {
4 const nums = [_]i32{2, 4, 6};4 const nums = [_]i32{ 2, 4, 6 };
5 var sum: usize = 0;5 var sum: usize = 0;
6 inline for (nums) |i| {6 inline for (nums) |i| {
7 const T = switch (i) {7 const T = switch (i) {
doc/langref/test_inline_switch_union_tag.zig+1-1
...@@ -15,7 +15,7 @@ fn getNum(u: U) u32 {...@@ -15,7 +15,7 @@ fn getNum(u: U) u32 {
15 return @intFromFloat(num);15 return @intFromFloat(num);
16 }16 }
17 return num;17 return num;
18 }18 },
19 }19 }
20}20}
2121
doc/langref/test_null_terminated_array.zig+2-2
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
33
4test "0-terminated sentinel array" {4test "0-terminated sentinel array" {
5 const array = [_:0]u8 {1, 2, 3, 4};5 const array = [_:0]u8{ 1, 2, 3, 4 };
66
7 try expect(@TypeOf(array) == [4:0]u8);7 try expect(@TypeOf(array) == [4:0]u8);
8 try expect(array.len == 4);8 try expect(array.len == 4);
...@@ -11,7 +11,7 @@ test "0-terminated sentinel array" {...@@ -11,7 +11,7 @@ test "0-terminated sentinel array" {
1111
12test "extra 0s in 0-terminated sentinel array" {12test "extra 0s in 0-terminated sentinel array" {
13 // The sentinel value may appear earlier, but does not influence the compile-time 'len'.13 // The sentinel value may appear earlier, but does not influence the compile-time 'len'.
14 const array = [_:0]u8 {1, 0, 0, 4};14 const array = [_:0]u8{ 1, 0, 0, 4 };
1515
16 try expect(@TypeOf(array) == [4:0]u8);16 try expect(@TypeOf(array) == [4:0]u8);
17 try expect(array.len == 4);17 try expect(array.len == 4);
doc/langref/test_struct_result.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
33
4const Point = struct {x: i32, y: i32};4const Point = struct { x: i32, y: i32 };
55
6test "anonymous struct literal" {6test "anonymous struct literal" {
7 const pt: Point = .{7 const pt: Point = .{
doc/langref/test_structs.zig+7-8
...@@ -13,15 +13,14 @@ const Point2 = packed struct {...@@ -13,15 +13,14 @@ const Point2 = packed struct {
13 y: f32,13 y: f32,
14};14};
1515
16
17// Declare an instance of a struct.16// Declare an instance of a struct.
18const p = Point {17const p = Point{
19 .x = 0.12,18 .x = 0.12,
20 .y = 0.34,19 .y = 0.34,
21};20};
2221
23// Maybe we're not ready to fill out some of the fields.22// Maybe we're not ready to fill out some of the fields.
24var p2 = Point {23var p2 = Point{
25 .x = 0.12,24 .x = 0.12,
26 .y = undefined,25 .y = undefined,
27};26};
...@@ -35,7 +34,7 @@ const Vec3 = struct {...@@ -35,7 +34,7 @@ const Vec3 = struct {
35 z: f32,34 z: f32,
3635
37 pub fn init(x: f32, y: f32, z: f32) Vec3 {36 pub fn init(x: f32, y: f32, z: f32) Vec3 {
38 return Vec3 {37 return Vec3{
39 .x = x,38 .x = x,
40 .y = y,39 .y = y,
41 .z = z,40 .z = z,
...@@ -69,7 +68,7 @@ test "struct namespaced variable" {...@@ -69,7 +68,7 @@ test "struct namespaced variable" {
69 try expect(@sizeOf(Empty) == 0);68 try expect(@sizeOf(Empty) == 0);
7069
71 // you can still instantiate an empty struct70 // you can still instantiate an empty struct
72 const does_nothing = Empty {};71 const does_nothing = Empty{};
7372
74 _ = does_nothing;73 _ = does_nothing;
75}74}
...@@ -81,7 +80,7 @@ fn setYBasedOnX(x: *f32, y: f32) void {...@@ -81,7 +80,7 @@ fn setYBasedOnX(x: *f32, y: f32) void {
81 point.y = y;80 point.y = y;
82}81}
83test "field parent pointer" {82test "field parent pointer" {
84 var point = Point {83 var point = Point{
85 .x = 0.1234,84 .x = 0.1234,
86 .y = 0.5678,85 .y = 0.5678,
87 };86 };
...@@ -100,8 +99,8 @@ fn LinkedList(comptime T: type) type {...@@ -100,8 +99,8 @@ fn LinkedList(comptime T: type) type {
100 };99 };
101100
102 first: ?*Node,101 first: ?*Node,
103 last: ?*Node,102 last: ?*Node,
104 len: usize,103 len: usize,
105 };104 };
106}105}
107106
doc/langref/test_switch_non-exhaustive.zig+1-2
...@@ -12,8 +12,7 @@ test "switch on non-exhaustive enum" {...@@ -12,8 +12,7 @@ test "switch on non-exhaustive enum" {
12 const number = Number.one;12 const number = Number.one;
13 const result = switch (number) {13 const result = switch (number) {
14 .one => true,14 .one => true,
15 .two,15 .two, .three => false,
16 .three => false,
17 _ => false,16 _ => false,
18 };17 };
19 try expect(result);18 try expect(result);
doc/langref/test_unresolved_comptime_value.zig+1-4
...@@ -5,10 +5,7 @@ test "try to pass a runtime type" {...@@ -5,10 +5,7 @@ test "try to pass a runtime type" {
5 foo(false);5 foo(false);
6}6}
7fn foo(condition: bool) void {7fn foo(condition: bool) void {
8 const result = max(8 const result = max(if (condition) f32 else u64, 1234, 5678);
9 if (condition) f32 else u64,
10 1234,
11 5678);
12 _ = result;9 _ = result;
13}10}
1411
doc/langref/test_while_continue_expression.zig+4-1
...@@ -9,7 +9,10 @@ test "while loop continue expression" {...@@ -9,7 +9,10 @@ test "while loop continue expression" {
9test "while loop continue expression, more complicated" {9test "while loop continue expression, more complicated" {
10 var i: usize = 1;10 var i: usize = 1;
11 var j: usize = 1;11 var j: usize = 1;
12 while (i * j < 2000) : ({ i *= 2; j *= 3; }) {12 while (i * j < 2000) : ({
13 i *= 2;
14 j *= 3;
15 }) {
13 const my_ij = i * j;16 const my_ij = i * j;
14 try expect(my_ij < 2000);17 try expect(my_ij < 2000);
15 }18 }
doc/langref/values.zig+3-1
...@@ -39,7 +39,9 @@ pub fn main() void {...@@ -39,7 +39,9 @@ pub fn main() void {
39 var number_or_error: anyerror!i32 = error.ArgNotFound;39 var number_or_error: anyerror!i32 = error.ArgNotFound;
4040
41 print("\nerror union 1\ntype: {}\nvalue: {!}\n", .{41 print("\nerror union 1\ntype: {}\nvalue: {!}\n", .{
42 @TypeOf(number_or_error), number_or_error, });42 @TypeOf(number_or_error),
43 number_or_error,
44 });
4345
44 number_or_error = 1234;46 number_or_error = 1234;
4547
lib/std/Build.zig+266-265
...@@ -13,8 +13,7 @@ const Allocator = mem.Allocator;...@@ -13,8 +13,7 @@ const Allocator = mem.Allocator;
13const Target = std.Target;13const Target = std.Target;
14const process = std.process;14const process = std.process;
15const EnvMap = std.process.EnvMap;15const EnvMap = std.process.EnvMap;
16const fmt_lib = std.fmt;16const File = fs.File;
17const File = std.fs.File;
18const Sha256 = std.crypto.hash.sha2.Sha256;17const Sha256 = std.crypto.hash.sha2.Sha256;
19const Build = @This();18const Build = @This();
2019
...@@ -149,15 +148,14 @@ const InitializedDepKey = struct {...@@ -149,15 +148,14 @@ const InitializedDepKey = struct {
149const InitializedDepContext = struct {148const InitializedDepContext = struct {
150 allocator: Allocator,149 allocator: Allocator,
151150
152 pub fn hash(self: @This(), k: InitializedDepKey) u64 {151 pub fn hash(ctx: @This(), k: InitializedDepKey) u64 {
153 var hasher = std.hash.Wyhash.init(0);152 var hasher = std.hash.Wyhash.init(0);
154 hasher.update(k.build_root_string);153 hasher.update(k.build_root_string);
155 hashUserInputOptionsMap(self.allocator, k.user_input_options, &hasher);154 hashUserInputOptionsMap(ctx.allocator, k.user_input_options, &hasher);
156 return hasher.final();155 return hasher.final();
157 }156 }
158157
159 pub fn eql(self: @This(), lhs: InitializedDepKey, rhs: InitializedDepKey) bool {158 pub fn eql(_: @This(), lhs: InitializedDepKey, rhs: InitializedDepKey) bool {
160 _ = self;
161 if (!std.mem.eql(u8, lhs.build_root_string, rhs.build_root_string))159 if (!std.mem.eql(u8, lhs.build_root_string, rhs.build_root_string))
162 return false;160 return false;
163161
...@@ -229,7 +227,7 @@ const TypeId = enum {...@@ -229,7 +227,7 @@ const TypeId = enum {
229};227};
230228
231const TopLevelStep = struct {229const TopLevelStep = struct {
232 pub const base_id = .top_level;230 pub const base_id: Step.Id = .top_level;
233231
234 step: Step,232 step: Step,
235 description: []const u8,233 description: []const u8,
...@@ -251,8 +249,8 @@ pub fn create(...@@ -251,8 +249,8 @@ pub fn create(
251 const initialized_deps = try arena.create(InitializedDepMap);249 const initialized_deps = try arena.create(InitializedDepMap);
252 initialized_deps.* = InitializedDepMap.initContext(arena, .{ .allocator = arena });250 initialized_deps.* = InitializedDepMap.initContext(arena, .{ .allocator = arena });
253251
254 const self = try arena.create(Build);252 const b = try arena.create(Build);
255 self.* = .{253 b.* = .{
256 .graph = graph,254 .graph = graph,
257 .build_root = build_root,255 .build_root = build_root,
258 .cache_root = cache_root,256 .cache_root = cache_root,
...@@ -280,17 +278,17 @@ pub fn create(...@@ -280,17 +278,17 @@ pub fn create(
280 .installed_files = ArrayList(InstalledFile).init(arena),278 .installed_files = ArrayList(InstalledFile).init(arena),
281 .install_tls = .{279 .install_tls = .{
282 .step = Step.init(.{280 .step = Step.init(.{
283 .id = .top_level,281 .id = TopLevelStep.base_id,
284 .name = "install",282 .name = "install",
285 .owner = self,283 .owner = b,
286 }),284 }),
287 .description = "Copy build artifacts to prefix path",285 .description = "Copy build artifacts to prefix path",
288 },286 },
289 .uninstall_tls = .{287 .uninstall_tls = .{
290 .step = Step.init(.{288 .step = Step.init(.{
291 .id = .top_level,289 .id = TopLevelStep.base_id,
292 .name = "uninstall",290 .name = "uninstall",
293 .owner = self,291 .owner = b,
294 .makeFn = makeUninstall,292 .makeFn = makeUninstall,
295 }),293 }),
296 .description = "Remove build artifacts from prefix path",294 .description = "Remove build artifacts from prefix path",
...@@ -306,10 +304,10 @@ pub fn create(...@@ -306,10 +304,10 @@ pub fn create(
306 .available_deps = available_deps,304 .available_deps = available_deps,
307 .release_mode = .off,305 .release_mode = .off,
308 };306 };
309 try self.top_level_steps.put(arena, self.install_tls.step.name, &self.install_tls);307 try b.top_level_steps.put(arena, b.install_tls.step.name, &b.install_tls);
310 try self.top_level_steps.put(arena, self.uninstall_tls.step.name, &self.uninstall_tls);308 try b.top_level_steps.put(arena, b.uninstall_tls.step.name, &b.uninstall_tls);
311 self.default_step = &self.install_tls.step;309 b.default_step = &b.install_tls.step;
312 return self;310 return b;
313}311}
314312
315fn createChild(313fn createChild(
...@@ -340,7 +338,7 @@ fn createChildOnly(...@@ -340,7 +338,7 @@ fn createChildOnly(
340 .allocator = allocator,338 .allocator = allocator,
341 .install_tls = .{339 .install_tls = .{
342 .step = Step.init(.{340 .step = Step.init(.{
343 .id = .top_level,341 .id = TopLevelStep.base_id,
344 .name = "install",342 .name = "install",
345 .owner = child,343 .owner = child,
346 }),344 }),
...@@ -348,7 +346,7 @@ fn createChildOnly(...@@ -348,7 +346,7 @@ fn createChildOnly(
348 },346 },
349 .uninstall_tls = .{347 .uninstall_tls = .{
350 .step = Step.init(.{348 .step = Step.init(.{
351 .id = .top_level,349 .id = TopLevelStep.base_id,
352 .name = "uninstall",350 .name = "uninstall",
353 .owner = child,351 .owner = child,
354 .makeFn = makeUninstall,352 .makeFn = makeUninstall,
...@@ -498,8 +496,8 @@ const OrderedUserValue = union(enum) {...@@ -498,8 +496,8 @@ const OrderedUserValue = union(enum) {
498 }496 }
499 };497 };
500498
501 fn hash(self: OrderedUserValue, hasher: *std.hash.Wyhash) void {499 fn hash(val: OrderedUserValue, hasher: *std.hash.Wyhash) void {
502 switch (self) {500 switch (val) {
503 .flag => {},501 .flag => {},
504 .scalar => |scalar| hasher.update(scalar),502 .scalar => |scalar| hasher.update(scalar),
505 // lists are already ordered503 // lists are already ordered
...@@ -541,9 +539,9 @@ const OrderedUserInputOption = struct {...@@ -541,9 +539,9 @@ const OrderedUserInputOption = struct {
541 value: OrderedUserValue,539 value: OrderedUserValue,
542 used: bool,540 used: bool,
543541
544 fn hash(self: OrderedUserInputOption, hasher: *std.hash.Wyhash) void {542 fn hash(opt: OrderedUserInputOption, hasher: *std.hash.Wyhash) void {
545 hasher.update(self.name);543 hasher.update(opt.name);
546 self.value.hash(hasher);544 opt.value.hash(hasher);
547 }545 }
548546
549 fn fromUnordered(allocator: Allocator, user_input_option: UserInputOption) OrderedUserInputOption {547 fn fromUnordered(allocator: Allocator, user_input_option: UserInputOption) OrderedUserInputOption {
...@@ -593,38 +591,38 @@ fn determineAndApplyInstallPrefix(b: *Build) !void {...@@ -593,38 +591,38 @@ fn determineAndApplyInstallPrefix(b: *Build) !void {
593}591}
594592
595/// This function is intended to be called by lib/build_runner.zig, not a build.zig file.593/// This function is intended to be called by lib/build_runner.zig, not a build.zig file.
596pub fn resolveInstallPrefix(self: *Build, install_prefix: ?[]const u8, dir_list: DirList) void {594pub fn resolveInstallPrefix(b: *Build, install_prefix: ?[]const u8, dir_list: DirList) void {
597 if (self.dest_dir) |dest_dir| {595 if (b.dest_dir) |dest_dir| {
598 self.install_prefix = install_prefix orelse "/usr";596 b.install_prefix = install_prefix orelse "/usr";
599 self.install_path = self.pathJoin(&.{ dest_dir, self.install_prefix });597 b.install_path = b.pathJoin(&.{ dest_dir, b.install_prefix });
600 } else {598 } else {
601 self.install_prefix = install_prefix orelse599 b.install_prefix = install_prefix orelse
602 (self.build_root.join(self.allocator, &.{"zig-out"}) catch @panic("unhandled error"));600 (b.build_root.join(b.allocator, &.{"zig-out"}) catch @panic("unhandled error"));
603 self.install_path = self.install_prefix;601 b.install_path = b.install_prefix;
604 }602 }
605603
606 var lib_list = [_][]const u8{ self.install_path, "lib" };604 var lib_list = [_][]const u8{ b.install_path, "lib" };
607 var exe_list = [_][]const u8{ self.install_path, "bin" };605 var exe_list = [_][]const u8{ b.install_path, "bin" };
608 var h_list = [_][]const u8{ self.install_path, "include" };606 var h_list = [_][]const u8{ b.install_path, "include" };
609607
610 if (dir_list.lib_dir) |dir| {608 if (dir_list.lib_dir) |dir| {
611 if (fs.path.isAbsolute(dir)) lib_list[0] = self.dest_dir orelse "";609 if (fs.path.isAbsolute(dir)) lib_list[0] = b.dest_dir orelse "";
612 lib_list[1] = dir;610 lib_list[1] = dir;
613 }611 }
614612
615 if (dir_list.exe_dir) |dir| {613 if (dir_list.exe_dir) |dir| {
616 if (fs.path.isAbsolute(dir)) exe_list[0] = self.dest_dir orelse "";614 if (fs.path.isAbsolute(dir)) exe_list[0] = b.dest_dir orelse "";
617 exe_list[1] = dir;615 exe_list[1] = dir;
618 }616 }
619617
620 if (dir_list.include_dir) |dir| {618 if (dir_list.include_dir) |dir| {
621 if (fs.path.isAbsolute(dir)) h_list[0] = self.dest_dir orelse "";619 if (fs.path.isAbsolute(dir)) h_list[0] = b.dest_dir orelse "";
622 h_list[1] = dir;620 h_list[1] = dir;
623 }621 }
624622
625 self.lib_dir = self.pathJoin(&lib_list);623 b.lib_dir = b.pathJoin(&lib_list);
626 self.exe_dir = self.pathJoin(&exe_list);624 b.exe_dir = b.pathJoin(&exe_list);
627 self.h_dir = self.pathJoin(&h_list);625 b.h_dir = b.pathJoin(&h_list);
628}626}
629627
630/// Create a set of key-value pairs that can be converted into a Zig source628/// Create a set of key-value pairs that can be converted into a Zig source
...@@ -632,8 +630,8 @@ pub fn resolveInstallPrefix(self: *Build, install_prefix: ?[]const u8, dir_list:...@@ -632,8 +630,8 @@ pub fn resolveInstallPrefix(self: *Build, install_prefix: ?[]const u8, dir_list:
632/// In other words, this provides a way to expose build.zig values to Zig630/// In other words, this provides a way to expose build.zig values to Zig
633/// source code with `@import`.631/// source code with `@import`.
634/// Related: `Module.addOptions`.632/// Related: `Module.addOptions`.
635pub fn addOptions(self: *Build) *Step.Options {633pub fn addOptions(b: *Build) *Step.Options {
636 return Step.Options.create(self);634 return Step.Options.create(b);
637}635}
638636
639pub const ExecutableOptions = struct {637pub const ExecutableOptions = struct {
...@@ -959,9 +957,9 @@ pub fn createModule(b: *Build, options: Module.CreateOptions) *Module {...@@ -959,9 +957,9 @@ pub fn createModule(b: *Build, options: Module.CreateOptions) *Module {
959/// `addArgs`, and `addArtifactArg`.957/// `addArgs`, and `addArtifactArg`.
960/// Be careful using this function, as it introduces a system dependency.958/// Be careful using this function, as it introduces a system dependency.
961/// To run an executable built with zig build, see `Step.Compile.run`.959/// To run an executable built with zig build, see `Step.Compile.run`.
962pub fn addSystemCommand(self: *Build, argv: []const []const u8) *Step.Run {960pub fn addSystemCommand(b: *Build, argv: []const []const u8) *Step.Run {
963 assert(argv.len >= 1);961 assert(argv.len >= 1);
964 const run_step = Step.Run.create(self, self.fmt("run {s}", .{argv[0]}));962 const run_step = Step.Run.create(b, b.fmt("run {s}", .{argv[0]}));
965 run_step.addArgs(argv);963 run_step.addArgs(argv);
966 return run_step;964 return run_step;
967}965}
...@@ -1002,20 +1000,20 @@ pub fn addConfigHeader(...@@ -1002,20 +1000,20 @@ pub fn addConfigHeader(
1002}1000}
10031001
1004/// Allocator.dupe without the need to handle out of memory.1002/// Allocator.dupe without the need to handle out of memory.
1005pub fn dupe(self: *Build, bytes: []const u8) []u8 {1003pub fn dupe(b: *Build, bytes: []const u8) []u8 {
1006 return self.allocator.dupe(u8, bytes) catch @panic("OOM");1004 return b.allocator.dupe(u8, bytes) catch @panic("OOM");
1007}1005}
10081006
1009/// Duplicates an array of strings without the need to handle out of memory.1007/// Duplicates an array of strings without the need to handle out of memory.
1010pub fn dupeStrings(self: *Build, strings: []const []const u8) [][]u8 {1008pub fn dupeStrings(b: *Build, strings: []const []const u8) [][]u8 {
1011 const array = self.allocator.alloc([]u8, strings.len) catch @panic("OOM");1009 const array = b.allocator.alloc([]u8, strings.len) catch @panic("OOM");
1012 for (array, strings) |*dest, source| dest.* = self.dupe(source);1010 for (array, strings) |*dest, source| dest.* = b.dupe(source);
1013 return array;1011 return array;
1014}1012}
10151013
1016/// Duplicates a path and converts all slashes to the OS's canonical path separator.1014/// Duplicates a path and converts all slashes to the OS's canonical path separator.
1017pub fn dupePath(self: *Build, bytes: []const u8) []u8 {1015pub fn dupePath(b: *Build, bytes: []const u8) []u8 {
1018 const the_copy = self.dupe(bytes);1016 const the_copy = b.dupe(bytes);
1019 for (the_copy) |*byte| {1017 for (the_copy) |*byte| {
1020 switch (byte.*) {1018 switch (byte.*) {
1021 '/', '\\' => byte.* = fs.path.sep,1019 '/', '\\' => byte.* = fs.path.sep,
...@@ -1025,8 +1023,8 @@ pub fn dupePath(self: *Build, bytes: []const u8) []u8 {...@@ -1025,8 +1023,8 @@ pub fn dupePath(self: *Build, bytes: []const u8) []u8 {
1025 return the_copy;1023 return the_copy;
1026}1024}
10271025
1028pub fn addWriteFile(self: *Build, file_path: []const u8, data: []const u8) *Step.WriteFile {1026pub fn addWriteFile(b: *Build, file_path: []const u8, data: []const u8) *Step.WriteFile {
1029 const write_file_step = self.addWriteFiles();1027 const write_file_step = b.addWriteFiles();
1030 _ = write_file_step.add(file_path, data);1028 _ = write_file_step.add(file_path, data);
1031 return write_file_step;1029 return write_file_step;
1032}1030}
...@@ -1041,34 +1039,34 @@ pub fn addWriteFiles(b: *Build) *Step.WriteFile {...@@ -1041,34 +1039,34 @@ pub fn addWriteFiles(b: *Build) *Step.WriteFile {
1041 return Step.WriteFile.create(b);1039 return Step.WriteFile.create(b);
1042}1040}
10431041
1044pub fn addRemoveDirTree(self: *Build, dir_path: []const u8) *Step.RemoveDir {1042pub fn addRemoveDirTree(b: *Build, dir_path: []const u8) *Step.RemoveDir {
1045 return Step.RemoveDir.create(self, dir_path);1043 return Step.RemoveDir.create(b, dir_path);
1046}1044}
10471045
1048pub fn addFmt(b: *Build, options: Step.Fmt.Options) *Step.Fmt {1046pub fn addFmt(b: *Build, options: Step.Fmt.Options) *Step.Fmt {
1049 return Step.Fmt.create(b, options);1047 return Step.Fmt.create(b, options);
1050}1048}
10511049
1052pub fn addTranslateC(self: *Build, options: Step.TranslateC.Options) *Step.TranslateC {1050pub fn addTranslateC(b: *Build, options: Step.TranslateC.Options) *Step.TranslateC {
1053 return Step.TranslateC.create(self, options);1051 return Step.TranslateC.create(b, options);
1054}1052}
10551053
1056pub fn getInstallStep(self: *Build) *Step {1054pub fn getInstallStep(b: *Build) *Step {
1057 return &self.install_tls.step;1055 return &b.install_tls.step;
1058}1056}
10591057
1060pub fn getUninstallStep(self: *Build) *Step {1058pub fn getUninstallStep(b: *Build) *Step {
1061 return &self.uninstall_tls.step;1059 return &b.uninstall_tls.step;
1062}1060}
10631061
1064fn makeUninstall(uninstall_step: *Step, prog_node: *std.Progress.Node) anyerror!void {1062fn makeUninstall(uninstall_step: *Step, prog_node: *std.Progress.Node) anyerror!void {
1065 _ = prog_node;1063 _ = prog_node;
1066 const uninstall_tls: *TopLevelStep = @fieldParentPtr("step", uninstall_step);1064 const uninstall_tls: *TopLevelStep = @fieldParentPtr("step", uninstall_step);
1067 const self: *Build = @fieldParentPtr("uninstall_tls", uninstall_tls);1065 const b: *Build = @fieldParentPtr("uninstall_tls", uninstall_tls);
10681066
1069 for (self.installed_files.items) |installed_file| {1067 for (b.installed_files.items) |installed_file| {
1070 const full_path = self.getInstallPath(installed_file.dir, installed_file.path);1068 const full_path = b.getInstallPath(installed_file.dir, installed_file.path);
1071 if (self.verbose) {1069 if (b.verbose) {
1072 log.info("rm {s}", .{full_path});1070 log.info("rm {s}", .{full_path});
1073 }1071 }
1074 fs.cwd().deleteTree(full_path) catch {};1072 fs.cwd().deleteTree(full_path) catch {};
...@@ -1082,13 +1080,13 @@ fn makeUninstall(uninstall_step: *Step, prog_node: *std.Progress.Node) anyerror!...@@ -1082,13 +1080,13 @@ fn makeUninstall(uninstall_step: *Step, prog_node: *std.Progress.Node) anyerror!
1082/// When a project depends on a Zig package as a dependency, it programmatically sets1080/// When a project depends on a Zig package as a dependency, it programmatically sets
1083/// these options when calling the dependency's build.zig script as a function.1081/// these options when calling the dependency's build.zig script as a function.
1084/// `null` is returned when an option is left to default.1082/// `null` is returned when an option is left to default.
1085pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_raw: []const u8) ?T {1083pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw: []const u8) ?T {
1086 const name = self.dupe(name_raw);1084 const name = b.dupe(name_raw);
1087 const description = self.dupe(description_raw);1085 const description = b.dupe(description_raw);
1088 const type_id = comptime typeToEnum(T);1086 const type_id = comptime typeToEnum(T);
1089 const enum_options = if (type_id == .@"enum") blk: {1087 const enum_options = if (type_id == .@"enum") blk: {
1090 const fields = comptime std.meta.fields(T);1088 const fields = comptime std.meta.fields(T);
1091 var options = ArrayList([]const u8).initCapacity(self.allocator, fields.len) catch @panic("OOM");1089 var options = ArrayList([]const u8).initCapacity(b.allocator, fields.len) catch @panic("OOM");
10921090
1093 inline for (fields) |field| {1091 inline for (fields) |field| {
1094 options.appendAssumeCapacity(field.name);1092 options.appendAssumeCapacity(field.name);
...@@ -1102,12 +1100,12 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1102,12 +1100,12 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1102 .description = description,1100 .description = description,
1103 .enum_options = enum_options,1101 .enum_options = enum_options,
1104 };1102 };
1105 if ((self.available_options_map.fetchPut(name, available_option) catch @panic("OOM")) != null) {1103 if ((b.available_options_map.fetchPut(name, available_option) catch @panic("OOM")) != null) {
1106 panic("Option '{s}' declared twice", .{name});1104 panic("Option '{s}' declared twice", .{name});
1107 }1105 }
1108 self.available_options_list.append(available_option) catch @panic("OOM");1106 b.available_options_list.append(available_option) catch @panic("OOM");
11091107
1110 const option_ptr = self.user_input_options.getPtr(name) orelse return null;1108 const option_ptr = b.user_input_options.getPtr(name) orelse return null;
1111 option_ptr.used = true;1109 option_ptr.used = true;
1112 switch (type_id) {1110 switch (type_id) {
1113 .bool => switch (option_ptr.value) {1111 .bool => switch (option_ptr.value) {
...@@ -1119,7 +1117,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1119,7 +1117,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1119 return false;1117 return false;
1120 } else {1118 } else {
1121 log.err("Expected -D{s} to be a boolean, but received '{s}'", .{ name, s });1119 log.err("Expected -D{s} to be a boolean, but received '{s}'", .{ name, s });
1122 self.markInvalidUserInput();1120 b.markInvalidUserInput();
1123 return null;1121 return null;
1124 }1122 }
1125 },1123 },
...@@ -1127,7 +1125,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1127,7 +1125,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1127 log.err("Expected -D{s} to be a boolean, but received a {s}.", .{1125 log.err("Expected -D{s} to be a boolean, but received a {s}.", .{
1128 name, @tagName(option_ptr.value),1126 name, @tagName(option_ptr.value),
1129 });1127 });
1130 self.markInvalidUserInput();1128 b.markInvalidUserInput();
1131 return null;1129 return null;
1132 },1130 },
1133 },1131 },
...@@ -1136,19 +1134,19 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1136,19 +1134,19 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1136 log.err("Expected -D{s} to be an integer, but received a {s}.", .{1134 log.err("Expected -D{s} to be an integer, but received a {s}.", .{
1137 name, @tagName(option_ptr.value),1135 name, @tagName(option_ptr.value),
1138 });1136 });
1139 self.markInvalidUserInput();1137 b.markInvalidUserInput();
1140 return null;1138 return null;
1141 },1139 },
1142 .scalar => |s| {1140 .scalar => |s| {
1143 const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) {1141 const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) {
1144 error.Overflow => {1142 error.Overflow => {
1145 log.err("-D{s} value {s} cannot fit into type {s}.", .{ name, s, @typeName(T) });1143 log.err("-D{s} value {s} cannot fit into type {s}.", .{ name, s, @typeName(T) });
1146 self.markInvalidUserInput();1144 b.markInvalidUserInput();
1147 return null;1145 return null;
1148 },1146 },
1149 else => {1147 else => {
1150 log.err("Expected -D{s} to be an integer of type {s}.", .{ name, @typeName(T) });1148 log.err("Expected -D{s} to be an integer of type {s}.", .{ name, @typeName(T) });
1151 self.markInvalidUserInput();1149 b.markInvalidUserInput();
1152 return null;1150 return null;
1153 },1151 },
1154 };1152 };
...@@ -1160,13 +1158,13 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1160,13 +1158,13 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1160 log.err("Expected -D{s} to be a float, but received a {s}.", .{1158 log.err("Expected -D{s} to be a float, but received a {s}.", .{
1161 name, @tagName(option_ptr.value),1159 name, @tagName(option_ptr.value),
1162 });1160 });
1163 self.markInvalidUserInput();1161 b.markInvalidUserInput();
1164 return null;1162 return null;
1165 },1163 },
1166 .scalar => |s| {1164 .scalar => |s| {
1167 const n = std.fmt.parseFloat(T, s) catch {1165 const n = std.fmt.parseFloat(T, s) catch {
1168 log.err("Expected -D{s} to be a float of type {s}.", .{ name, @typeName(T) });1166 log.err("Expected -D{s} to be a float of type {s}.", .{ name, @typeName(T) });
1169 self.markInvalidUserInput();1167 b.markInvalidUserInput();
1170 return null;1168 return null;
1171 };1169 };
1172 return n;1170 return n;
...@@ -1177,7 +1175,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1177,7 +1175,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1177 log.err("Expected -D{s} to be an enum, but received a {s}.", .{1175 log.err("Expected -D{s} to be an enum, but received a {s}.", .{
1178 name, @tagName(option_ptr.value),1176 name, @tagName(option_ptr.value),
1179 });1177 });
1180 self.markInvalidUserInput();1178 b.markInvalidUserInput();
1181 return null;1179 return null;
1182 },1180 },
1183 .scalar => |s| {1181 .scalar => |s| {
...@@ -1185,7 +1183,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1185,7 +1183,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1185 return enum_lit;1183 return enum_lit;
1186 } else {1184 } else {
1187 log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(T) });1185 log.err("Expected -D{s} to be of type {s}.", .{ name, @typeName(T) });
1188 self.markInvalidUserInput();1186 b.markInvalidUserInput();
1189 return null;1187 return null;
1190 }1188 }
1191 },1189 },
...@@ -1195,7 +1193,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1195,7 +1193,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1195 log.err("Expected -D{s} to be a string, but received a {s}.", .{1193 log.err("Expected -D{s} to be a string, but received a {s}.", .{
1196 name, @tagName(option_ptr.value),1194 name, @tagName(option_ptr.value),
1197 });1195 });
1198 self.markInvalidUserInput();1196 b.markInvalidUserInput();
1199 return null;1197 return null;
1200 },1198 },
1201 .scalar => |s| return s,1199 .scalar => |s| return s,
...@@ -1205,7 +1203,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1205,7 +1203,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1205 log.err("Expected -D{s} to be an enum, but received a {s}.", .{1203 log.err("Expected -D{s} to be an enum, but received a {s}.", .{
1206 name, @tagName(option_ptr.value),1204 name, @tagName(option_ptr.value),
1207 });1205 });
1208 self.markInvalidUserInput();1206 b.markInvalidUserInput();
1209 return null;1207 return null;
1210 },1208 },
1211 .scalar => |s| {1209 .scalar => |s| {
...@@ -1213,7 +1211,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1213,7 +1211,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1213 return build_id;1211 return build_id;
1214 } else |err| {1212 } else |err| {
1215 log.err("unable to parse option '-D{s}': {s}", .{ name, @errorName(err) });1213 log.err("unable to parse option '-D{s}': {s}", .{ name, @errorName(err) });
1216 self.markInvalidUserInput();1214 b.markInvalidUserInput();
1217 return null;1215 return null;
1218 }1216 }
1219 },1217 },
...@@ -1223,28 +1221,28 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_...@@ -1223,28 +1221,28 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
1223 log.err("Expected -D{s} to be a list, but received a {s}.", .{1221 log.err("Expected -D{s} to be a list, but received a {s}.", .{
1224 name, @tagName(option_ptr.value),1222 name, @tagName(option_ptr.value),
1225 });1223 });
1226 self.markInvalidUserInput();1224 b.markInvalidUserInput();
1227 return null;1225 return null;
1228 },1226 },
1229 .scalar => |s| {1227 .scalar => |s| {
1230 return self.allocator.dupe([]const u8, &[_][]const u8{s}) catch @panic("OOM");1228 return b.allocator.dupe([]const u8, &[_][]const u8{s}) catch @panic("OOM");
1231 },1229 },
1232 .list => |lst| return lst.items,1230 .list => |lst| return lst.items,
1233 },1231 },
1234 }1232 }
1235}1233}
12361234
1237pub fn step(self: *Build, name: []const u8, description: []const u8) *Step {1235pub fn step(b: *Build, name: []const u8, description: []const u8) *Step {
1238 const step_info = self.allocator.create(TopLevelStep) catch @panic("OOM");1236 const step_info = b.allocator.create(TopLevelStep) catch @panic("OOM");
1239 step_info.* = .{1237 step_info.* = .{
1240 .step = Step.init(.{1238 .step = Step.init(.{
1241 .id = .top_level,1239 .id = TopLevelStep.base_id,
1242 .name = name,1240 .name = name,
1243 .owner = self,1241 .owner = b,
1244 }),1242 }),
1245 .description = self.dupe(description),1243 .description = b.dupe(description),
1246 };1244 };
1247 const gop = self.top_level_steps.getOrPut(self.allocator, name) catch @panic("OOM");1245 const gop = b.top_level_steps.getOrPut(b.allocator, name) catch @panic("OOM");
1248 if (gop.found_existing) std.debug.panic("A top-level step with name \"{s}\" already exists", .{name});1246 if (gop.found_existing) std.debug.panic("A top-level step with name \"{s}\" already exists", .{name});
12491247
1250 gop.key_ptr.* = step_info.step.name;1248 gop.key_ptr.* = step_info.step.name;
...@@ -1406,10 +1404,10 @@ pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs...@@ -1406,10 +1404,10 @@ pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs
1406 return args.default_target;1404 return args.default_target;
1407}1405}
14081406
1409pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const u8) !bool {1407pub fn addUserInputOption(b: *Build, name_raw: []const u8, value_raw: []const u8) !bool {
1410 const name = self.dupe(name_raw);1408 const name = b.dupe(name_raw);
1411 const value = self.dupe(value_raw);1409 const value = b.dupe(value_raw);
1412 const gop = try self.user_input_options.getOrPut(name);1410 const gop = try b.user_input_options.getOrPut(name);
1413 if (!gop.found_existing) {1411 if (!gop.found_existing) {
1414 gop.value_ptr.* = UserInputOption{1412 gop.value_ptr.* = UserInputOption{
1415 .name = name,1413 .name = name,
...@@ -1423,10 +1421,10 @@ pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const...@@ -1423,10 +1421,10 @@ pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const
1423 switch (gop.value_ptr.value) {1421 switch (gop.value_ptr.value) {
1424 .scalar => |s| {1422 .scalar => |s| {
1425 // turn it into a list1423 // turn it into a list
1426 var list = ArrayList([]const u8).init(self.allocator);1424 var list = ArrayList([]const u8).init(b.allocator);
1427 try list.append(s);1425 try list.append(s);
1428 try list.append(value);1426 try list.append(value);
1429 try self.user_input_options.put(name, .{1427 try b.user_input_options.put(name, .{
1430 .name = name,1428 .name = name,
1431 .value = .{ .list = list },1429 .value = .{ .list = list },
1432 .used = false,1430 .used = false,
...@@ -1435,7 +1433,7 @@ pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const...@@ -1435,7 +1433,7 @@ pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const
1435 .list => |*list| {1433 .list => |*list| {
1436 // append to the list1434 // append to the list
1437 try list.append(value);1435 try list.append(value);
1438 try self.user_input_options.put(name, .{1436 try b.user_input_options.put(name, .{
1439 .name = name,1437 .name = name,
1440 .value = .{ .list = list.* },1438 .value = .{ .list = list.* },
1441 .used = false,1439 .used = false,
...@@ -1454,9 +1452,9 @@ pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const...@@ -1454,9 +1452,9 @@ pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const
1454 return false;1452 return false;
1455}1453}
14561454
1457pub fn addUserInputFlag(self: *Build, name_raw: []const u8) !bool {1455pub fn addUserInputFlag(b: *Build, name_raw: []const u8) !bool {
1458 const name = self.dupe(name_raw);1456 const name = b.dupe(name_raw);
1459 const gop = try self.user_input_options.getOrPut(name);1457 const gop = try b.user_input_options.getOrPut(name);
1460 if (!gop.found_existing) {1458 if (!gop.found_existing) {
1461 gop.value_ptr.* = .{1459 gop.value_ptr.* = .{
1462 .name = name,1460 .name = name,
...@@ -1498,8 +1496,8 @@ fn typeToEnum(comptime T: type) TypeId {...@@ -1498,8 +1496,8 @@ fn typeToEnum(comptime T: type) TypeId {
1498 };1496 };
1499}1497}
15001498
1501fn markInvalidUserInput(self: *Build) void {1499fn markInvalidUserInput(b: *Build) void {
1502 self.invalid_user_input = true;1500 b.invalid_user_input = true;
1503}1501}
15041502
1505pub fn validateUserInputDidItFail(b: *Build) bool {1503pub fn validateUserInputDidItFail(b: *Build) bool {
...@@ -1532,18 +1530,18 @@ fn printCmd(ally: Allocator, cwd: ?[]const u8, argv: []const []const u8) void {...@@ -1532,18 +1530,18 @@ fn printCmd(ally: Allocator, cwd: ?[]const u8, argv: []const []const u8) void {
1532/// This creates the install step and adds it to the dependencies of the1530/// This creates the install step and adds it to the dependencies of the
1533/// top-level install step, using all the default options.1531/// top-level install step, using all the default options.
1534/// See `addInstallArtifact` for a more flexible function.1532/// See `addInstallArtifact` for a more flexible function.
1535pub fn installArtifact(self: *Build, artifact: *Step.Compile) void {1533pub fn installArtifact(b: *Build, artifact: *Step.Compile) void {
1536 self.getInstallStep().dependOn(&self.addInstallArtifact(artifact, .{}).step);1534 b.getInstallStep().dependOn(&b.addInstallArtifact(artifact, .{}).step);
1537}1535}
15381536
1539/// This merely creates the step; it does not add it to the dependencies of the1537/// This merely creates the step; it does not add it to the dependencies of the
1540/// top-level install step.1538/// top-level install step.
1541pub fn addInstallArtifact(1539pub fn addInstallArtifact(
1542 self: *Build,1540 b: *Build,
1543 artifact: *Step.Compile,1541 artifact: *Step.Compile,
1544 options: Step.InstallArtifact.Options,1542 options: Step.InstallArtifact.Options,
1545) *Step.InstallArtifact {1543) *Step.InstallArtifact {
1546 return Step.InstallArtifact.create(self, artifact, options);1544 return Step.InstallArtifact.create(b, artifact, options);
1547}1545}
15481546
1549///`dest_rel_path` is relative to prefix path1547///`dest_rel_path` is relative to prefix path
...@@ -1590,16 +1588,16 @@ pub fn addInstallHeaderFile(b: *Build, source: LazyPath, dest_rel_path: []const...@@ -1590,16 +1588,16 @@ pub fn addInstallHeaderFile(b: *Build, source: LazyPath, dest_rel_path: []const
1590}1588}
15911589
1592pub fn addInstallFileWithDir(1590pub fn addInstallFileWithDir(
1593 self: *Build,1591 b: *Build,
1594 source: LazyPath,1592 source: LazyPath,
1595 install_dir: InstallDir,1593 install_dir: InstallDir,
1596 dest_rel_path: []const u8,1594 dest_rel_path: []const u8,
1597) *Step.InstallFile {1595) *Step.InstallFile {
1598 return Step.InstallFile.create(self, source, install_dir, dest_rel_path);1596 return Step.InstallFile.create(b, source, install_dir, dest_rel_path);
1599}1597}
16001598
1601pub fn addInstallDirectory(self: *Build, options: Step.InstallDir.Options) *Step.InstallDir {1599pub fn addInstallDirectory(b: *Build, options: Step.InstallDir.Options) *Step.InstallDir {
1602 return Step.InstallDir.create(self, options);1600 return Step.InstallDir.create(b, options);
1603}1601}
16041602
1605pub fn addCheckFile(1603pub fn addCheckFile(
...@@ -1611,16 +1609,16 @@ pub fn addCheckFile(...@@ -1611,16 +1609,16 @@ pub fn addCheckFile(
1611}1609}
16121610
1613/// deprecated: https://github.com/ziglang/zig/issues/149431611/// deprecated: https://github.com/ziglang/zig/issues/14943
1614pub fn pushInstalledFile(self: *Build, dir: InstallDir, dest_rel_path: []const u8) void {1612pub fn pushInstalledFile(b: *Build, dir: InstallDir, dest_rel_path: []const u8) void {
1615 const file = InstalledFile{1613 const file = InstalledFile{
1616 .dir = dir,1614 .dir = dir,
1617 .path = dest_rel_path,1615 .path = dest_rel_path,
1618 };1616 };
1619 self.installed_files.append(file.dupe(self)) catch @panic("OOM");1617 b.installed_files.append(file.dupe(b)) catch @panic("OOM");
1620}1618}
16211619
1622pub fn truncateFile(self: *Build, dest_path: []const u8) !void {1620pub fn truncateFile(b: *Build, dest_path: []const u8) !void {
1623 if (self.verbose) {1621 if (b.verbose) {
1624 log.info("truncate {s}", .{dest_path});1622 log.info("truncate {s}", .{dest_path});
1625 }1623 }
1626 const cwd = fs.cwd();1624 const cwd = fs.cwd();
...@@ -1652,50 +1650,54 @@ pub fn path(b: *Build, sub_path: []const u8) LazyPath {...@@ -1652,50 +1650,54 @@ pub fn path(b: *Build, sub_path: []const u8) LazyPath {
1652/// This is low-level implementation details of the build system, not meant to1650/// This is low-level implementation details of the build system, not meant to
1653/// be called by users' build scripts. Even in the build system itself it is a1651/// be called by users' build scripts. Even in the build system itself it is a
1654/// code smell to call this function.1652/// code smell to call this function.
1655pub fn pathFromRoot(b: *Build, p: []const u8) []u8 {1653pub fn pathFromRoot(b: *Build, sub_path: []const u8) []u8 {
1656 return fs.path.resolve(b.allocator, &.{ b.build_root.path orelse ".", p }) catch @panic("OOM");1654 return b.pathResolve(&.{ b.build_root.path orelse ".", sub_path });
1657}1655}
16581656
1659fn pathFromCwd(b: *Build, p: []const u8) []u8 {1657fn pathFromCwd(b: *Build, sub_path: []const u8) []u8 {
1660 const cwd = process.getCwdAlloc(b.allocator) catch @panic("OOM");1658 const cwd = process.getCwdAlloc(b.allocator) catch @panic("OOM");
1661 return fs.path.resolve(b.allocator, &.{ cwd, p }) catch @panic("OOM");1659 return b.pathResolve(&.{ cwd, sub_path });
1660}
1661
1662pub fn pathJoin(b: *Build, paths: []const []const u8) []u8 {
1663 return fs.path.join(b.allocator, paths) catch @panic("OOM");
1662}1664}
16631665
1664pub fn pathJoin(self: *Build, paths: []const []const u8) []u8 {1666pub fn pathResolve(b: *Build, paths: []const []const u8) []u8 {
1665 return fs.path.join(self.allocator, paths) catch @panic("OOM");1667 return fs.path.resolve(b.allocator, paths) catch @panic("OOM");
1666}1668}
16671669
1668pub fn fmt(self: *Build, comptime format: []const u8, args: anytype) []u8 {1670pub fn fmt(b: *Build, comptime format: []const u8, args: anytype) []u8 {
1669 return fmt_lib.allocPrint(self.allocator, format, args) catch @panic("OOM");1671 return std.fmt.allocPrint(b.allocator, format, args) catch @panic("OOM");
1670}1672}
16711673
1672pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 {1674pub fn findProgram(b: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 {
1673 // TODO report error for ambiguous situations1675 // TODO report error for ambiguous situations
1674 const exe_extension = self.host.result.exeFileExt();1676 const exe_extension = b.host.result.exeFileExt();
1675 for (self.search_prefixes.items) |search_prefix| {1677 for (b.search_prefixes.items) |search_prefix| {
1676 for (names) |name| {1678 for (names) |name| {
1677 if (fs.path.isAbsolute(name)) {1679 if (fs.path.isAbsolute(name)) {
1678 return name;1680 return name;
1679 }1681 }
1680 const full_path = self.pathJoin(&.{1682 const full_path = b.pathJoin(&.{
1681 search_prefix,1683 search_prefix,
1682 "bin",1684 "bin",
1683 self.fmt("{s}{s}", .{ name, exe_extension }),1685 b.fmt("{s}{s}", .{ name, exe_extension }),
1684 });1686 });
1685 return fs.realpathAlloc(self.allocator, full_path) catch continue;1687 return fs.realpathAlloc(b.allocator, full_path) catch continue;
1686 }1688 }
1687 }1689 }
1688 if (self.graph.env_map.get("PATH")) |PATH| {1690 if (b.graph.env_map.get("PATH")) |PATH| {
1689 for (names) |name| {1691 for (names) |name| {
1690 if (fs.path.isAbsolute(name)) {1692 if (fs.path.isAbsolute(name)) {
1691 return name;1693 return name;
1692 }1694 }
1693 var it = mem.tokenizeScalar(u8, PATH, fs.path.delimiter);1695 var it = mem.tokenizeScalar(u8, PATH, fs.path.delimiter);
1694 while (it.next()) |p| {1696 while (it.next()) |p| {
1695 const full_path = self.pathJoin(&.{1697 const full_path = b.pathJoin(&.{
1696 p, self.fmt("{s}{s}", .{ name, exe_extension }),1698 p, b.fmt("{s}{s}", .{ name, exe_extension }),
1697 });1699 });
1698 return fs.realpathAlloc(self.allocator, full_path) catch continue;1700 return fs.realpathAlloc(b.allocator, full_path) catch continue;
1699 }1701 }
1700 }1702 }
1701 }1703 }
...@@ -1704,17 +1706,17 @@ pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []con...@@ -1704,17 +1706,17 @@ pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []con
1704 return name;1706 return name;
1705 }1707 }
1706 for (paths) |p| {1708 for (paths) |p| {
1707 const full_path = self.pathJoin(&.{1709 const full_path = b.pathJoin(&.{
1708 p, self.fmt("{s}{s}", .{ name, exe_extension }),1710 p, b.fmt("{s}{s}", .{ name, exe_extension }),
1709 });1711 });
1710 return fs.realpathAlloc(self.allocator, full_path) catch continue;1712 return fs.realpathAlloc(b.allocator, full_path) catch continue;
1711 }1713 }
1712 }1714 }
1713 return error.FileNotFound;1715 return error.FileNotFound;
1714}1716}
17151717
1716pub fn runAllowFail(1718pub fn runAllowFail(
1717 self: *Build,1719 b: *Build,
1718 argv: []const []const u8,1720 argv: []const []const u8,
1719 out_code: *u8,1721 out_code: *u8,
1720 stderr_behavior: std.ChildProcess.StdIo,1722 stderr_behavior: std.ChildProcess.StdIo,
...@@ -1725,18 +1727,18 @@ pub fn runAllowFail(...@@ -1725,18 +1727,18 @@ pub fn runAllowFail(
1725 return error.ExecNotSupported;1727 return error.ExecNotSupported;
17261728
1727 const max_output_size = 400 * 1024;1729 const max_output_size = 400 * 1024;
1728 var child = std.ChildProcess.init(argv, self.allocator);1730 var child = std.ChildProcess.init(argv, b.allocator);
1729 child.stdin_behavior = .Ignore;1731 child.stdin_behavior = .Ignore;
1730 child.stdout_behavior = .Pipe;1732 child.stdout_behavior = .Pipe;
1731 child.stderr_behavior = stderr_behavior;1733 child.stderr_behavior = stderr_behavior;
1732 child.env_map = &self.graph.env_map;1734 child.env_map = &b.graph.env_map;
17331735
1734 try child.spawn();1736 try child.spawn();
17351737
1736 const stdout = child.stdout.?.reader().readAllAlloc(self.allocator, max_output_size) catch {1738 const stdout = child.stdout.?.reader().readAllAlloc(b.allocator, max_output_size) catch {
1737 return error.ReadFailure;1739 return error.ReadFailure;
1738 };1740 };
1739 errdefer self.allocator.free(stdout);1741 errdefer b.allocator.free(stdout);
17401742
1741 const term = try child.wait();1743 const term = try child.wait();
1742 switch (term) {1744 switch (term) {
...@@ -1779,19 +1781,16 @@ pub fn addSearchPrefix(b: *Build, search_prefix: []const u8) void {...@@ -1779,19 +1781,16 @@ pub fn addSearchPrefix(b: *Build, search_prefix: []const u8) void {
1779 b.search_prefixes.append(b.allocator, b.dupePath(search_prefix)) catch @panic("OOM");1781 b.search_prefixes.append(b.allocator, b.dupePath(search_prefix)) catch @panic("OOM");
1780}1782}
17811783
1782pub fn getInstallPath(self: *Build, dir: InstallDir, dest_rel_path: []const u8) []const u8 {1784pub fn getInstallPath(b: *Build, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
1783 assert(!fs.path.isAbsolute(dest_rel_path)); // Install paths must be relative to the prefix1785 assert(!fs.path.isAbsolute(dest_rel_path)); // Install paths must be relative to the prefix
1784 const base_dir = switch (dir) {1786 const base_dir = switch (dir) {
1785 .prefix => self.install_path,1787 .prefix => b.install_path,
1786 .bin => self.exe_dir,1788 .bin => b.exe_dir,
1787 .lib => self.lib_dir,1789 .lib => b.lib_dir,
1788 .header => self.h_dir,1790 .header => b.h_dir,
1789 .custom => |p| self.pathJoin(&.{ self.install_path, p }),1791 .custom => |p| b.pathJoin(&.{ b.install_path, p }),
1790 };1792 };
1791 return fs.path.resolve(1793 return b.pathResolve(&.{ base_dir, dest_rel_path });
1792 self.allocator,
1793 &[_][]const u8{ base_dir, dest_rel_path },
1794 ) catch @panic("OOM");
1795}1794}
17961795
1797pub const Dependency = struct {1796pub const Dependency = struct {
...@@ -2092,11 +2091,11 @@ pub const GeneratedFile = struct {...@@ -2092,11 +2091,11 @@ pub const GeneratedFile = struct {
2092 /// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards.2091 /// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards.
2093 path: ?[]const u8 = null,2092 path: ?[]const u8 = null,
20942093
2095 pub fn getPath(self: GeneratedFile) []const u8 {2094 pub fn getPath(gen: GeneratedFile) []const u8 {
2096 return self.path orelse std.debug.panic(2095 return gen.step.owner.pathFromRoot(gen.path orelse std.debug.panic(
2097 "getPath() was called on a GeneratedFile that wasn't built yet. Is there a missing Step dependency on step '{s}'?",2096 "getPath() was called on a GeneratedFile that wasn't built yet. Is there a missing Step dependency on step '{s}'?",
2098 .{self.step.name},2097 .{gen.step.name},
2099 );2098 ));
2100 }2099 }
2101};2100};
21022101
...@@ -2132,28 +2131,23 @@ test dirnameAllowEmpty {...@@ -2132,28 +2131,23 @@ test dirnameAllowEmpty {
21322131
2133/// A reference to an existing or future path.2132/// A reference to an existing or future path.
2134pub const LazyPath = union(enum) {2133pub const LazyPath = union(enum) {
2135 /// Deprecated; use the `path` function instead.
2136 path: []const u8,
2137
2138 /// A source file path relative to build root.2134 /// A source file path relative to build root.
2139 src_path: struct {2135 src_path: struct {
2140 owner: *std.Build,2136 owner: *std.Build,
2141 sub_path: []const u8,2137 sub_path: []const u8,
2142 },2138 },
21432139
2144 /// A file that is generated by an interface. Those files usually are2140 generated: struct {
2145 /// not available until built by a build step.2141 file: *const GeneratedFile,
2146 generated: *const GeneratedFile,
2147
2148 /// One of the parent directories of a file generated by an interface.
2149 /// The path is not available until built by a build step.
2150 generated_dirname: struct {
2151 generated: *const GeneratedFile,
21522142
2153 /// The number of parent directories to go up.2143 /// The number of parent directories to go up.
2154 /// 0 means the directory of the generated file,2144 /// 0 means the generated file itself.
2155 /// 1 means the parent of that directory, and so on.2145 /// 1 means the directory of the generated file.
2156 up: usize,2146 /// 2 means the parent of that directory, and so on.
2147 up: usize = 0,
2148
2149 /// Applied after `up`.
2150 sub_path: []const u8 = "",
2157 },2151 },
21582152
2159 /// An absolute path or a path relative to the current working directory of2153 /// An absolute path or a path relative to the current working directory of
...@@ -2169,12 +2163,6 @@ pub const LazyPath = union(enum) {...@@ -2169,12 +2163,6 @@ pub const LazyPath = union(enum) {
2169 sub_path: []const u8,2163 sub_path: []const u8,
2170 },2164 },
21712165
2172 /// Deprecated. Call `path` instead.
2173 pub fn relative(p: []const u8) LazyPath {
2174 std.log.warn("deprecated. call std.Build.path instead", .{});
2175 return .{ .path = p };
2176 }
2177
2178 /// Returns a lazy path referring to the directory containing this path.2166 /// Returns a lazy path referring to the directory containing this path.
2179 ///2167 ///
2180 /// The dirname is not allowed to escape the logical root for underlying path.2168 /// The dirname is not allowed to escape the logical root for underlying path.
...@@ -2182,10 +2170,8 @@ pub const LazyPath = union(enum) {...@@ -2182,10 +2170,8 @@ pub const LazyPath = union(enum) {
2182 /// the dirname is not allowed to traverse outside of the build root.2170 /// the dirname is not allowed to traverse outside of the build root.
2183 /// Similarly, if the path is a generated file inside zig-cache,2171 /// Similarly, if the path is a generated file inside zig-cache,
2184 /// the dirname is not allowed to traverse outside of zig-cache.2172 /// the dirname is not allowed to traverse outside of zig-cache.
2185 pub fn dirname(self: LazyPath) LazyPath {2173 pub fn dirname(lazy_path: LazyPath) LazyPath {
2186 return switch (self) {2174 return switch (lazy_path) {
2187 .generated => |gen| .{ .generated_dirname = .{ .generated = gen, .up = 0 } },
2188 .generated_dirname => |gen| .{ .generated_dirname = .{ .generated = gen.generated, .up = gen.up + 1 } },
2189 .src_path => |sp| .{ .src_path = .{2175 .src_path => |sp| .{ .src_path = .{
2190 .owner = sp.owner,2176 .owner = sp.owner,
2191 .sub_path = dirnameAllowEmpty(sp.sub_path) orelse {2177 .sub_path = dirnameAllowEmpty(sp.sub_path) orelse {
...@@ -2193,20 +2179,23 @@ pub const LazyPath = union(enum) {...@@ -2193,20 +2179,23 @@ pub const LazyPath = union(enum) {
2193 @panic("misconfigured build script");2179 @panic("misconfigured build script");
2194 },2180 },
2195 } },2181 } },
2196 .path => |p| .{2182 .generated => |generated| .{ .generated = if (dirnameAllowEmpty(generated.sub_path)) |sub_dirname| .{
2197 .path = dirnameAllowEmpty(p) orelse {2183 .file = generated.file,
2198 dumpBadDirnameHelp(null, null, "dirname() attempted to traverse outside the build root\n", .{}) catch {};2184 .up = generated.up,
2199 @panic("misconfigured build script");2185 .sub_path = sub_dirname,
2200 },2186 } else .{
2201 },2187 .file = generated.file,
2202 .cwd_relative => |p| .{2188 .up = generated.up + 1,
2203 .cwd_relative = dirnameAllowEmpty(p) orelse {2189 .sub_path = "",
2190 } },
2191 .cwd_relative => |rel_path| .{
2192 .cwd_relative = dirnameAllowEmpty(rel_path) orelse {
2204 // If we get null, it means one of two things:2193 // If we get null, it means one of two things:
2205 // - p was absolute, and is now root2194 // - rel_path was absolute, and is now root
2206 // - p was relative, and is now ""2195 // - rel_path was relative, and is now ""
2207 // In either case, the build script tried to go too far2196 // In either case, the build script tried to go too far
2208 // and we should panic.2197 // and we should panic.
2209 if (fs.path.isAbsolute(p)) {2198 if (fs.path.isAbsolute(rel_path)) {
2210 dumpBadDirnameHelp(null, null,2199 dumpBadDirnameHelp(null, null,
2211 \\dirname() attempted to traverse outside the root.2200 \\dirname() attempted to traverse outside the root.
2212 \\No more directories left to go up.2201 \\No more directories left to go up.
...@@ -2235,31 +2224,50 @@ pub const LazyPath = union(enum) {...@@ -2235,31 +2224,50 @@ pub const LazyPath = union(enum) {
2235 };2224 };
2236 }2225 }
22372226
2227 pub fn path(lazy_path: LazyPath, b: *Build, sub_path: []const u8) LazyPath {
2228 return switch (lazy_path) {
2229 .src_path => |src| .{ .src_path = .{
2230 .owner = src.owner,
2231 .sub_path = b.pathResolve(&.{ src.sub_path, sub_path }),
2232 } },
2233 .generated => |gen| .{ .generated = .{
2234 .file = gen.file,
2235 .up = gen.up,
2236 .sub_path = b.pathResolve(&.{ gen.sub_path, sub_path }),
2237 } },
2238 .cwd_relative => |cwd_relative| .{
2239 .cwd_relative = b.pathResolve(&.{ cwd_relative, sub_path }),
2240 },
2241 .dependency => |dep| .{ .dependency = .{
2242 .dependency = dep.dependency,
2243 .sub_path = b.pathResolve(&.{ dep.sub_path, sub_path }),
2244 } },
2245 };
2246 }
2247
2238 /// Returns a string that can be shown to represent the file source.2248 /// Returns a string that can be shown to represent the file source.
2239 /// Either returns the path or `"generated"`.2249 /// Either returns the path, `"generated"`, or `"dependency"`.
2240 pub fn getDisplayName(self: LazyPath) []const u8 {2250 pub fn getDisplayName(lazy_path: LazyPath) []const u8 {
2241 return switch (self) {2251 return switch (lazy_path) {
2242 .src_path => |sp| sp.sub_path,2252 .src_path => |sp| sp.sub_path,
2243 .path, .cwd_relative => |p| p,2253 .cwd_relative => |p| p,
2244 .generated => "generated",2254 .generated => "generated",
2245 .generated_dirname => "generated",
2246 .dependency => "dependency",2255 .dependency => "dependency",
2247 };2256 };
2248 }2257 }
22492258
2250 /// Adds dependencies this file source implies to the given step.2259 /// Adds dependencies this file source implies to the given step.
2251 pub fn addStepDependencies(self: LazyPath, other_step: *Step) void {2260 pub fn addStepDependencies(lazy_path: LazyPath, other_step: *Step) void {
2252 switch (self) {2261 switch (lazy_path) {
2253 .src_path, .path, .cwd_relative, .dependency => {},2262 .src_path, .cwd_relative, .dependency => {},
2254 .generated => |gen| other_step.dependOn(gen.step),2263 .generated => |gen| other_step.dependOn(gen.file.step),
2255 .generated_dirname => |gen| other_step.dependOn(gen.generated.step),
2256 }2264 }
2257 }2265 }
22582266
2259 /// Returns an absolute path.2267 /// Returns an absolute path.
2260 /// Intended to be used during the make phase only.2268 /// Intended to be used during the make phase only.
2261 pub fn getPath(self: LazyPath, src_builder: *Build) []const u8 {2269 pub fn getPath(lazy_path: LazyPath, src_builder: *Build) []const u8 {
2262 return getPath2(self, src_builder, null);2270 return getPath2(lazy_path, src_builder, null);
2263 }2271 }
22642272
2265 /// Returns an absolute path.2273 /// Returns an absolute path.
...@@ -2267,56 +2275,52 @@ pub const LazyPath = union(enum) {...@@ -2267,56 +2275,52 @@ pub const LazyPath = union(enum) {
2267 ///2275 ///
2268 /// `asking_step` is only used for debugging purposes; it's the step being2276 /// `asking_step` is only used for debugging purposes; it's the step being
2269 /// run that is asking for the path.2277 /// run that is asking for the path.
2270 pub fn getPath2(self: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 {2278 pub fn getPath2(lazy_path: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 {
2271 switch (self) {2279 switch (lazy_path) {
2272 .path => |p| return src_builder.pathFromRoot(p),
2273 .src_path => |sp| return sp.owner.pathFromRoot(sp.sub_path),2280 .src_path => |sp| return sp.owner.pathFromRoot(sp.sub_path),
2274 .cwd_relative => |p| return src_builder.pathFromCwd(p),2281 .cwd_relative => |p| return src_builder.pathFromCwd(p),
2275 .generated => |gen| return gen.path orelse {2282 .generated => |gen| {
2276 std.debug.getStderrMutex().lock();2283 var file_path: []const u8 = gen.file.step.owner.pathFromRoot(gen.file.path orelse {
2277 const stderr = std.io.getStdErr();2284 std.debug.getStderrMutex().lock();
2278 dumpBadGetPathHelp(gen.step, stderr, src_builder, asking_step) catch {};2285 const stderr = std.io.getStdErr();
2279 @panic("misconfigured build script");2286 dumpBadGetPathHelp(gen.file.step, stderr, src_builder, asking_step) catch {};
2280 },2287 std.debug.getStderrMutex().unlock();
2281 .generated_dirname => |gen| {2288 @panic("misconfigured build script");
2282 const cache_root_path = src_builder.cache_root.path orelse2289 });
2283 (src_builder.cache_root.join(src_builder.allocator, &.{"."}) catch @panic("OOM"));2290
22842291 if (gen.up > 0) {
2285 const gen_step = gen.generated.step;2292 const cache_root_path = src_builder.cache_root.path orelse
2286 var p = getPath2(LazyPath{ .generated = gen.generated }, src_builder, asking_step);2293 (src_builder.cache_root.join(src_builder.allocator, &.{"."}) catch @panic("OOM"));
2287 var i: usize = 0;2294
2288 while (i <= gen.up) : (i += 1) {2295 for (0..gen.up) |_| {
2289 // path is absolute.2296 if (mem.eql(u8, file_path, cache_root_path)) {
2290 // dirname will return null only if we're at root.2297 // If we hit the cache root and there's still more to go,
2291 // Typically, we'll stop well before that at the cache root.2298 // the script attempted to go too far.
2292 p = fs.path.dirname(p) orelse {2299 dumpBadDirnameHelp(gen.file.step, asking_step,
2293 dumpBadDirnameHelp(gen_step, asking_step,2300 \\dirname() attempted to traverse outside the cache root.
2294 \\dirname() reached root.2301 \\This is not allowed.
2295 \\No more directories left to go up.2302 \\
2296 \\2303 , .{}) catch {};
2297 , .{}) catch {};2304 @panic("misconfigured build script");
2298 @panic("misconfigured build script");2305 }
2299 };2306
23002307 // path is absolute.
2301 if (mem.eql(u8, p, cache_root_path) and i < gen.up) {2308 // dirname will return null only if we're at root.
2302 // If we hit the cache root and there's still more to go,2309 // Typically, we'll stop well before that at the cache root.
2303 // the script attempted to go too far.2310 file_path = fs.path.dirname(file_path) orelse {
2304 dumpBadDirnameHelp(gen_step, asking_step,2311 dumpBadDirnameHelp(gen.file.step, asking_step,
2305 \\dirname() attempted to traverse outside the cache root.2312 \\dirname() reached root.
2306 \\This is not allowed.2313 \\No more directories left to go up.
2307 \\2314 \\
2308 , .{}) catch {};2315 , .{}) catch {};
2309 @panic("misconfigured build script");2316 @panic("misconfigured build script");
2317 };
2310 }2318 }
2311 }2319 }
2312 return p;2320
2313 },2321 return src_builder.pathResolve(&.{ file_path, gen.sub_path });
2314 .dependency => |dep| {
2315 return dep.dependency.builder.pathJoin(&[_][]const u8{
2316 dep.dependency.builder.build_root.path.?,
2317 dep.sub_path,
2318 });
2319 },2322 },
2323 .dependency => |dep| return dep.dependency.builder.pathFromRoot(dep.sub_path),
2320 }2324 }
2321 }2325 }
23222326
...@@ -2324,21 +2328,18 @@ pub const LazyPath = union(enum) {...@@ -2324,21 +2328,18 @@ pub const LazyPath = union(enum) {
2324 ///2328 ///
2325 /// The `b` parameter is only used for its allocator. All *Build instances2329 /// The `b` parameter is only used for its allocator. All *Build instances
2326 /// share the same allocator.2330 /// share the same allocator.
2327 pub fn dupe(self: LazyPath, b: *Build) LazyPath {2331 pub fn dupe(lazy_path: LazyPath, b: *Build) LazyPath {
2328 return switch (self) {2332 return switch (lazy_path) {
2329 .src_path => |sp| .{ .src_path = .{2333 .src_path => |sp| .{ .src_path = .{
2330 .owner = sp.owner,2334 .owner = sp.owner,
2331 .sub_path = sp.owner.dupePath(sp.sub_path),2335 .sub_path = sp.owner.dupePath(sp.sub_path),
2332 } },2336 } },
2333 .path => |p| .{ .path = b.dupePath(p) },
2334 .cwd_relative => |p| .{ .cwd_relative = b.dupePath(p) },2337 .cwd_relative => |p| .{ .cwd_relative = b.dupePath(p) },
2335 .generated => |gen| .{ .generated = gen },2338 .generated => |gen| .{ .generated = .{
2336 .generated_dirname => |gen| .{2339 .file = gen.file,
2337 .generated_dirname = .{2340 .up = gen.up,
2338 .generated = gen.generated,2341 .sub_path = b.dupePath(gen.sub_path),
2339 .up = gen.up,2342 } },
2340 },
2341 },
2342 .dependency => |dep| .{ .dependency = dep },2343 .dependency => |dep| .{ .dependency = dep },
2343 };2344 };
2344 }2345 }
...@@ -2425,11 +2426,11 @@ pub const InstallDir = union(enum) {...@@ -2425,11 +2426,11 @@ pub const InstallDir = union(enum) {
2425 custom: []const u8,2426 custom: []const u8,
24262427
2427 /// Duplicates the install directory including the path if set to custom.2428 /// Duplicates the install directory including the path if set to custom.
2428 pub fn dupe(self: InstallDir, builder: *Build) InstallDir {2429 pub fn dupe(dir: InstallDir, builder: *Build) InstallDir {
2429 if (self == .custom) {2430 if (dir == .custom) {
2430 return .{ .custom = builder.dupe(self.custom) };2431 return .{ .custom = builder.dupe(dir.custom) };
2431 } else {2432 } else {
2432 return self;2433 return dir;
2433 }2434 }
2434 }2435 }
2435};2436};
...@@ -2439,10 +2440,10 @@ pub const InstalledFile = struct {...@@ -2439,10 +2440,10 @@ pub const InstalledFile = struct {
2439 path: []const u8,2440 path: []const u8,
24402441
2441 /// Duplicates the installed file path and directory.2442 /// Duplicates the installed file path and directory.
2442 pub fn dupe(self: InstalledFile, builder: *Build) InstalledFile {2443 pub fn dupe(file: InstalledFile, builder: *Build) InstalledFile {
2443 return .{2444 return .{
2444 .dir = self.dir.dupe(builder),2445 .dir = file.dir.dupe(builder),
2445 .path = builder.dupe(self.path),2446 .path = builder.dupe(file.path),
2446 };2447 };
2447 }2448 }
2448};2449};
lib/std/Build/Module.zig+13-18
...@@ -89,10 +89,10 @@ pub const CSourceFile = struct {...@@ -89,10 +89,10 @@ pub const CSourceFile = struct {
89 file: LazyPath,89 file: LazyPath,
90 flags: []const []const u8 = &.{},90 flags: []const []const u8 = &.{},
9191
92 pub fn dupe(self: CSourceFile, b: *std.Build) CSourceFile {92 pub fn dupe(file: CSourceFile, b: *std.Build) CSourceFile {
93 return .{93 return .{
94 .file = self.file.dupe(b),94 .file = file.file.dupe(b),
95 .flags = b.dupeStrings(self.flags),95 .flags = b.dupeStrings(file.flags),
96 };96 };
97 }97 }
98};98};
...@@ -115,12 +115,12 @@ pub const RcSourceFile = struct {...@@ -115,12 +115,12 @@ pub const RcSourceFile = struct {
115 /// as `/I <resolved path>`.115 /// as `/I <resolved path>`.
116 include_paths: []const LazyPath = &.{},116 include_paths: []const LazyPath = &.{},
117117
118 pub fn dupe(self: RcSourceFile, b: *std.Build) RcSourceFile {118 pub fn dupe(file: RcSourceFile, b: *std.Build) RcSourceFile {
119 const include_paths = b.allocator.alloc(LazyPath, self.include_paths.len) catch @panic("OOM");119 const include_paths = b.allocator.alloc(LazyPath, file.include_paths.len) catch @panic("OOM");
120 for (include_paths, self.include_paths) |*dest, lazy_path| dest.* = lazy_path.dupe(b);120 for (include_paths, file.include_paths) |*dest, lazy_path| dest.* = lazy_path.dupe(b);
121 return .{121 return .{
122 .file = self.file.dupe(b),122 .file = file.file.dupe(b),
123 .flags = b.dupeStrings(self.flags),123 .flags = b.dupeStrings(file.flags),
124 .include_paths = include_paths,124 .include_paths = include_paths,
125 };125 };
126 }126 }
...@@ -665,24 +665,19 @@ pub fn appendZigProcessFlags(...@@ -665,24 +665,19 @@ pub fn appendZigProcessFlags(
665 for (m.include_dirs.items) |include_dir| {665 for (m.include_dirs.items) |include_dir| {
666 switch (include_dir) {666 switch (include_dir) {
667 .path => |include_path| {667 .path => |include_path| {
668 try zig_args.append("-I");668 try zig_args.appendSlice(&.{ "-I", include_path.getPath2(b, asking_step) });
669 try zig_args.append(include_path.getPath(b));
670 },669 },
671 .path_system => |include_path| {670 .path_system => |include_path| {
672 try zig_args.append("-isystem");671 try zig_args.appendSlice(&.{ "-isystem", include_path.getPath2(b, asking_step) });
673 try zig_args.append(include_path.getPath(b));
674 },672 },
675 .path_after => |include_path| {673 .path_after => |include_path| {
676 try zig_args.append("-idirafter");674 try zig_args.appendSlice(&.{ "-idirafter", include_path.getPath2(b, asking_step) });
677 try zig_args.append(include_path.getPath(b));
678 },675 },
679 .framework_path => |include_path| {676 .framework_path => |include_path| {
680 try zig_args.append("-F");677 try zig_args.appendSlice(&.{ "-F", include_path.getPath2(b, asking_step) });
681 try zig_args.append(include_path.getPath2(b, asking_step));
682 },678 },
683 .framework_path_system => |include_path| {679 .framework_path_system => |include_path| {
684 try zig_args.append("-iframework");680 try zig_args.appendSlice(&.{ "-iframework", include_path.getPath2(b, asking_step) });
685 try zig_args.append(include_path.getPath2(b, asking_step));
686 },681 },
687 .other_step => |other| {682 .other_step => |other| {
688 if (other.generated_h) |header| {683 if (other.generated_h) |header| {
lib/std/Build/Step.zig+3-3
...@@ -58,7 +58,7 @@ pub const TestResults = struct {...@@ -58,7 +58,7 @@ pub const TestResults = struct {
58 }58 }
59};59};
6060
61pub const MakeFn = *const fn (self: *Step, prog_node: *std.Progress.Node) anyerror!void;61pub const MakeFn = *const fn (step: *Step, prog_node: *std.Progress.Node) anyerror!void;
6262
63pub const State = enum {63pub const State = enum {
64 precheck_unstarted,64 precheck_unstarted,
...@@ -201,8 +201,8 @@ pub fn make(s: *Step, prog_node: *std.Progress.Node) error{ MakeFailed, MakeSkip...@@ -201,8 +201,8 @@ pub fn make(s: *Step, prog_node: *std.Progress.Node) error{ MakeFailed, MakeSkip
201 }201 }
202}202}
203203
204pub fn dependOn(self: *Step, other: *Step) void {204pub fn dependOn(step: *Step, other: *Step) void {
205 self.dependencies.append(other) catch @panic("OOM");205 step.dependencies.append(other) catch @panic("OOM");
206}206}
207207
208pub fn getStackTrace(s: *Step) ?std.builtin.StackTrace {208pub fn getStackTrace(s: *Step) ?std.builtin.StackTrace {
lib/std/Build/Step/CheckFile.zig+13-13
...@@ -14,7 +14,7 @@ expected_exact: ?[]const u8,...@@ -14,7 +14,7 @@ expected_exact: ?[]const u8,
14source: std.Build.LazyPath,14source: std.Build.LazyPath,
15max_bytes: usize = 20 * 1024 * 1024,15max_bytes: usize = 20 * 1024 * 1024,
1616
17pub const base_id = .check_file;17pub const base_id: Step.Id = .check_file;
1818
19pub const Options = struct {19pub const Options = struct {
20 expected_matches: []const []const u8 = &.{},20 expected_matches: []const []const u8 = &.{},
...@@ -26,10 +26,10 @@ pub fn create(...@@ -26,10 +26,10 @@ pub fn create(
26 source: std.Build.LazyPath,26 source: std.Build.LazyPath,
27 options: Options,27 options: Options,
28) *CheckFile {28) *CheckFile {
29 const self = owner.allocator.create(CheckFile) catch @panic("OOM");29 const check_file = owner.allocator.create(CheckFile) catch @panic("OOM");
30 self.* = .{30 check_file.* = .{
31 .step = Step.init(.{31 .step = Step.init(.{
32 .id = .check_file,32 .id = base_id,
33 .name = "CheckFile",33 .name = "CheckFile",
34 .owner = owner,34 .owner = owner,
35 .makeFn = make,35 .makeFn = make,
...@@ -38,27 +38,27 @@ pub fn create(...@@ -38,27 +38,27 @@ pub fn create(
38 .expected_matches = owner.dupeStrings(options.expected_matches),38 .expected_matches = owner.dupeStrings(options.expected_matches),
39 .expected_exact = options.expected_exact,39 .expected_exact = options.expected_exact,
40 };40 };
41 self.source.addStepDependencies(&self.step);41 check_file.source.addStepDependencies(&check_file.step);
42 return self;42 return check_file;
43}43}
4444
45pub fn setName(self: *CheckFile, name: []const u8) void {45pub fn setName(check_file: *CheckFile, name: []const u8) void {
46 self.step.name = name;46 check_file.step.name = name;
47}47}
4848
49fn make(step: *Step, prog_node: *std.Progress.Node) !void {49fn make(step: *Step, prog_node: *std.Progress.Node) !void {
50 _ = prog_node;50 _ = prog_node;
51 const b = step.owner;51 const b = step.owner;
52 const self: *CheckFile = @fieldParentPtr("step", step);52 const check_file: *CheckFile = @fieldParentPtr("step", step);
5353
54 const src_path = self.source.getPath(b);54 const src_path = check_file.source.getPath2(b, step);
55 const contents = fs.cwd().readFileAlloc(b.allocator, src_path, self.max_bytes) catch |err| {55 const contents = fs.cwd().readFileAlloc(b.allocator, src_path, check_file.max_bytes) catch |err| {
56 return step.fail("unable to read '{s}': {s}", .{56 return step.fail("unable to read '{s}': {s}", .{
57 src_path, @errorName(err),57 src_path, @errorName(err),
58 });58 });
59 };59 };
6060
61 for (self.expected_matches) |expected_match| {61 for (check_file.expected_matches) |expected_match| {
62 if (mem.indexOf(u8, contents, expected_match) == null) {62 if (mem.indexOf(u8, contents, expected_match) == null) {
63 return step.fail(63 return step.fail(
64 \\64 \\
...@@ -71,7 +71,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -71,7 +71,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
71 }71 }
72 }72 }
7373
74 if (self.expected_exact) |expected_exact| {74 if (check_file.expected_exact) |expected_exact| {
75 if (!mem.eql(u8, expected_exact, contents)) {75 if (!mem.eql(u8, expected_exact, contents)) {
76 return step.fail(76 return step.fail(
77 \\77 \\
lib/std/Build/Step/CheckObject.zig+107-107
...@@ -12,7 +12,7 @@ const CheckObject = @This();...@@ -12,7 +12,7 @@ const CheckObject = @This();
12const Allocator = mem.Allocator;12const Allocator = mem.Allocator;
13const Step = std.Build.Step;13const Step = std.Build.Step;
1414
15pub const base_id = .check_object;15pub const base_id: Step.Id = .check_object;
1616
17step: Step,17step: Step,
18source: std.Build.LazyPath,18source: std.Build.LazyPath,
...@@ -26,10 +26,10 @@ pub fn create(...@@ -26,10 +26,10 @@ pub fn create(
26 obj_format: std.Target.ObjectFormat,26 obj_format: std.Target.ObjectFormat,
27) *CheckObject {27) *CheckObject {
28 const gpa = owner.allocator;28 const gpa = owner.allocator;
29 const self = gpa.create(CheckObject) catch @panic("OOM");29 const check_object = gpa.create(CheckObject) catch @panic("OOM");
30 self.* = .{30 check_object.* = .{
31 .step = Step.init(.{31 .step = Step.init(.{
32 .id = .check_file,32 .id = base_id,
33 .name = "CheckObject",33 .name = "CheckObject",
34 .owner = owner,34 .owner = owner,
35 .makeFn = make,35 .makeFn = make,
...@@ -38,8 +38,8 @@ pub fn create(...@@ -38,8 +38,8 @@ pub fn create(
38 .checks = std.ArrayList(Check).init(gpa),38 .checks = std.ArrayList(Check).init(gpa),
39 .obj_format = obj_format,39 .obj_format = obj_format,
40 };40 };
41 self.source.addStepDependencies(&self.step);41 check_object.source.addStepDependencies(&check_object.step);
42 return self;42 return check_object;
43}43}
4444
45const SearchPhrase = struct {45const SearchPhrase = struct {
...@@ -268,36 +268,36 @@ const Check = struct {...@@ -268,36 +268,36 @@ const Check = struct {
268 return check;268 return check;
269 }269 }
270270
271 fn extract(self: *Check, phrase: SearchPhrase) void {271 fn extract(check: *Check, phrase: SearchPhrase) void {
272 self.actions.append(.{272 check.actions.append(.{
273 .tag = .extract,273 .tag = .extract,
274 .phrase = phrase,274 .phrase = phrase,
275 }) catch @panic("OOM");275 }) catch @panic("OOM");
276 }276 }
277277
278 fn exact(self: *Check, phrase: SearchPhrase) void {278 fn exact(check: *Check, phrase: SearchPhrase) void {
279 self.actions.append(.{279 check.actions.append(.{
280 .tag = .exact,280 .tag = .exact,
281 .phrase = phrase,281 .phrase = phrase,
282 }) catch @panic("OOM");282 }) catch @panic("OOM");
283 }283 }
284284
285 fn contains(self: *Check, phrase: SearchPhrase) void {285 fn contains(check: *Check, phrase: SearchPhrase) void {
286 self.actions.append(.{286 check.actions.append(.{
287 .tag = .contains,287 .tag = .contains,
288 .phrase = phrase,288 .phrase = phrase,
289 }) catch @panic("OOM");289 }) catch @panic("OOM");
290 }290 }
291291
292 fn notPresent(self: *Check, phrase: SearchPhrase) void {292 fn notPresent(check: *Check, phrase: SearchPhrase) void {
293 self.actions.append(.{293 check.actions.append(.{
294 .tag = .not_present,294 .tag = .not_present,
295 .phrase = phrase,295 .phrase = phrase,
296 }) catch @panic("OOM");296 }) catch @panic("OOM");
297 }297 }
298298
299 fn computeCmp(self: *Check, phrase: SearchPhrase, expected: ComputeCompareExpected) void {299 fn computeCmp(check: *Check, phrase: SearchPhrase, expected: ComputeCompareExpected) void {
300 self.actions.append(.{300 check.actions.append(.{
301 .tag = .compute_cmp,301 .tag = .compute_cmp,
302 .phrase = phrase,302 .phrase = phrase,
303 .expected = expected,303 .expected = expected,
...@@ -328,246 +328,246 @@ const Check = struct {...@@ -328,246 +328,246 @@ const Check = struct {
328};328};
329329
330/// Creates a new empty sequence of actions.330/// Creates a new empty sequence of actions.
331fn checkStart(self: *CheckObject, kind: Check.Kind) void {331fn checkStart(check_object: *CheckObject, kind: Check.Kind) void {
332 const new_check = Check.create(self.step.owner.allocator, kind);332 const check = Check.create(check_object.step.owner.allocator, kind);
333 self.checks.append(new_check) catch @panic("OOM");333 check_object.checks.append(check) catch @panic("OOM");
334}334}
335335
336/// Adds an exact match phrase to the latest created Check.336/// Adds an exact match phrase to the latest created Check.
337pub fn checkExact(self: *CheckObject, phrase: []const u8) void {337pub fn checkExact(check_object: *CheckObject, phrase: []const u8) void {
338 self.checkExactInner(phrase, null);338 check_object.checkExactInner(phrase, null);
339}339}
340340
341/// Like `checkExact()` but takes an additional argument `LazyPath` which will be341/// Like `checkExact()` but takes an additional argument `LazyPath` which will be
342/// resolved to a full search query in `make()`.342/// resolved to a full search query in `make()`.
343pub fn checkExactPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {343pub fn checkExactPath(check_object: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
344 self.checkExactInner(phrase, lazy_path);344 check_object.checkExactInner(phrase, lazy_path);
345}345}
346346
347fn checkExactInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {347fn checkExactInner(check_object: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
348 assert(self.checks.items.len > 0);348 assert(check_object.checks.items.len > 0);
349 const last = &self.checks.items[self.checks.items.len - 1];349 const last = &check_object.checks.items[check_object.checks.items.len - 1];
350 last.exact(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });350 last.exact(.{ .string = check_object.step.owner.dupe(phrase), .lazy_path = lazy_path });
351}351}
352352
353/// Adds a fuzzy match phrase to the latest created Check.353/// Adds a fuzzy match phrase to the latest created Check.
354pub fn checkContains(self: *CheckObject, phrase: []const u8) void {354pub fn checkContains(check_object: *CheckObject, phrase: []const u8) void {
355 self.checkContainsInner(phrase, null);355 check_object.checkContainsInner(phrase, null);
356}356}
357357
358/// Like `checkContains()` but takes an additional argument `lazy_path` which will be358/// Like `checkContains()` but takes an additional argument `lazy_path` which will be
359/// resolved to a full search query in `make()`.359/// resolved to a full search query in `make()`.
360pub fn checkContainsPath(360pub fn checkContainsPath(
361 self: *CheckObject,361 check_object: *CheckObject,
362 phrase: []const u8,362 phrase: []const u8,
363 lazy_path: std.Build.LazyPath,363 lazy_path: std.Build.LazyPath,
364) void {364) void {
365 self.checkContainsInner(phrase, lazy_path);365 check_object.checkContainsInner(phrase, lazy_path);
366}366}
367367
368fn checkContainsInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {368fn checkContainsInner(check_object: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
369 assert(self.checks.items.len > 0);369 assert(check_object.checks.items.len > 0);
370 const last = &self.checks.items[self.checks.items.len - 1];370 const last = &check_object.checks.items[check_object.checks.items.len - 1];
371 last.contains(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });371 last.contains(.{ .string = check_object.step.owner.dupe(phrase), .lazy_path = lazy_path });
372}372}
373373
374/// Adds an exact match phrase with variable extractor to the latest created Check.374/// Adds an exact match phrase with variable extractor to the latest created Check.
375pub fn checkExtract(self: *CheckObject, phrase: []const u8) void {375pub fn checkExtract(check_object: *CheckObject, phrase: []const u8) void {
376 self.checkExtractInner(phrase, null);376 check_object.checkExtractInner(phrase, null);
377}377}
378378
379/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be379/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be
380/// resolved to a full search query in `make()`.380/// resolved to a full search query in `make()`.
381pub fn checkExtractLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {381pub fn checkExtractLazyPath(check_object: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
382 self.checkExtractInner(phrase, lazy_path);382 check_object.checkExtractInner(phrase, lazy_path);
383}383}
384384
385fn checkExtractInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {385fn checkExtractInner(check_object: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
386 assert(self.checks.items.len > 0);386 assert(check_object.checks.items.len > 0);
387 const last = &self.checks.items[self.checks.items.len - 1];387 const last = &check_object.checks.items[check_object.checks.items.len - 1];
388 last.extract(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });388 last.extract(.{ .string = check_object.step.owner.dupe(phrase), .lazy_path = lazy_path });
389}389}
390390
391/// Adds another searched phrase to the latest created Check391/// Adds another searched phrase to the latest created Check
392/// however ensures there is no matching phrase in the output.392/// however ensures there is no matching phrase in the output.
393pub fn checkNotPresent(self: *CheckObject, phrase: []const u8) void {393pub fn checkNotPresent(check_object: *CheckObject, phrase: []const u8) void {
394 self.checkNotPresentInner(phrase, null);394 check_object.checkNotPresentInner(phrase, null);
395}395}
396396
397/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be397/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be
398/// resolved to a full search query in `make()`.398/// resolved to a full search query in `make()`.
399pub fn checkNotPresentLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {399pub fn checkNotPresentLazyPath(check_object: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
400 self.checkNotPresentInner(phrase, lazy_path);400 check_object.checkNotPresentInner(phrase, lazy_path);
401}401}
402402
403fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {403fn checkNotPresentInner(check_object: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
404 assert(self.checks.items.len > 0);404 assert(check_object.checks.items.len > 0);
405 const last = &self.checks.items[self.checks.items.len - 1];405 const last = &check_object.checks.items[check_object.checks.items.len - 1];
406 last.notPresent(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });406 last.notPresent(.{ .string = check_object.step.owner.dupe(phrase), .lazy_path = lazy_path });
407}407}
408408
409/// Creates a new check checking in the file headers (section, program headers, etc.).409/// Creates a new check checking in the file headers (section, program headers, etc.).
410pub fn checkInHeaders(self: *CheckObject) void {410pub fn checkInHeaders(check_object: *CheckObject) void {
411 self.checkStart(.headers);411 check_object.checkStart(.headers);
412}412}
413413
414/// Creates a new check checking specifically symbol table parsed and dumped from the object414/// Creates a new check checking specifically symbol table parsed and dumped from the object
415/// file.415/// file.
416pub fn checkInSymtab(self: *CheckObject) void {416pub fn checkInSymtab(check_object: *CheckObject) void {
417 const label = switch (self.obj_format) {417 const label = switch (check_object.obj_format) {
418 .macho => MachODumper.symtab_label,418 .macho => MachODumper.symtab_label,
419 .elf => ElfDumper.symtab_label,419 .elf => ElfDumper.symtab_label,
420 .wasm => WasmDumper.symtab_label,420 .wasm => WasmDumper.symtab_label,
421 .coff => @panic("TODO symtab for coff"),421 .coff => @panic("TODO symtab for coff"),
422 else => @panic("TODO other file formats"),422 else => @panic("TODO other file formats"),
423 };423 };
424 self.checkStart(.symtab);424 check_object.checkStart(.symtab);
425 self.checkExact(label);425 check_object.checkExact(label);
426}426}
427427
428/// Creates a new check checking specifically dyld rebase opcodes contents parsed and dumped428/// Creates a new check checking specifically dyld rebase opcodes contents parsed and dumped
429/// from the object file.429/// from the object file.
430/// This check is target-dependent and applicable to MachO only.430/// This check is target-dependent and applicable to MachO only.
431pub fn checkInDyldRebase(self: *CheckObject) void {431pub fn checkInDyldRebase(check_object: *CheckObject) void {
432 const label = switch (self.obj_format) {432 const label = switch (check_object.obj_format) {
433 .macho => MachODumper.dyld_rebase_label,433 .macho => MachODumper.dyld_rebase_label,
434 else => @panic("Unsupported target platform"),434 else => @panic("Unsupported target platform"),
435 };435 };
436 self.checkStart(.dyld_rebase);436 check_object.checkStart(.dyld_rebase);
437 self.checkExact(label);437 check_object.checkExact(label);
438}438}
439439
440/// Creates a new check checking specifically dyld bind opcodes contents parsed and dumped440/// Creates a new check checking specifically dyld bind opcodes contents parsed and dumped
441/// from the object file.441/// from the object file.
442/// This check is target-dependent and applicable to MachO only.442/// This check is target-dependent and applicable to MachO only.
443pub fn checkInDyldBind(self: *CheckObject) void {443pub fn checkInDyldBind(check_object: *CheckObject) void {
444 const label = switch (self.obj_format) {444 const label = switch (check_object.obj_format) {
445 .macho => MachODumper.dyld_bind_label,445 .macho => MachODumper.dyld_bind_label,
446 else => @panic("Unsupported target platform"),446 else => @panic("Unsupported target platform"),
447 };447 };
448 self.checkStart(.dyld_bind);448 check_object.checkStart(.dyld_bind);
449 self.checkExact(label);449 check_object.checkExact(label);
450}450}
451451
452/// Creates a new check checking specifically dyld weak bind opcodes contents parsed and dumped452/// Creates a new check checking specifically dyld weak bind opcodes contents parsed and dumped
453/// from the object file.453/// from the object file.
454/// This check is target-dependent and applicable to MachO only.454/// This check is target-dependent and applicable to MachO only.
455pub fn checkInDyldWeakBind(self: *CheckObject) void {455pub fn checkInDyldWeakBind(check_object: *CheckObject) void {
456 const label = switch (self.obj_format) {456 const label = switch (check_object.obj_format) {
457 .macho => MachODumper.dyld_weak_bind_label,457 .macho => MachODumper.dyld_weak_bind_label,
458 else => @panic("Unsupported target platform"),458 else => @panic("Unsupported target platform"),
459 };459 };
460 self.checkStart(.dyld_weak_bind);460 check_object.checkStart(.dyld_weak_bind);
461 self.checkExact(label);461 check_object.checkExact(label);
462}462}
463463
464/// Creates a new check checking specifically dyld lazy bind opcodes contents parsed and dumped464/// Creates a new check checking specifically dyld lazy bind opcodes contents parsed and dumped
465/// from the object file.465/// from the object file.
466/// This check is target-dependent and applicable to MachO only.466/// This check is target-dependent and applicable to MachO only.
467pub fn checkInDyldLazyBind(self: *CheckObject) void {467pub fn checkInDyldLazyBind(check_object: *CheckObject) void {
468 const label = switch (self.obj_format) {468 const label = switch (check_object.obj_format) {
469 .macho => MachODumper.dyld_lazy_bind_label,469 .macho => MachODumper.dyld_lazy_bind_label,
470 else => @panic("Unsupported target platform"),470 else => @panic("Unsupported target platform"),
471 };471 };
472 self.checkStart(.dyld_lazy_bind);472 check_object.checkStart(.dyld_lazy_bind);
473 self.checkExact(label);473 check_object.checkExact(label);
474}474}
475475
476/// Creates a new check checking specifically exports info contents parsed and dumped476/// Creates a new check checking specifically exports info contents parsed and dumped
477/// from the object file.477/// from the object file.
478/// This check is target-dependent and applicable to MachO only.478/// This check is target-dependent and applicable to MachO only.
479pub fn checkInExports(self: *CheckObject) void {479pub fn checkInExports(check_object: *CheckObject) void {
480 const label = switch (self.obj_format) {480 const label = switch (check_object.obj_format) {
481 .macho => MachODumper.exports_label,481 .macho => MachODumper.exports_label,
482 else => @panic("Unsupported target platform"),482 else => @panic("Unsupported target platform"),
483 };483 };
484 self.checkStart(.exports);484 check_object.checkStart(.exports);
485 self.checkExact(label);485 check_object.checkExact(label);
486}486}
487487
488/// Creates a new check checking specifically indirect symbol table parsed and dumped488/// Creates a new check checking specifically indirect symbol table parsed and dumped
489/// from the object file.489/// from the object file.
490/// This check is target-dependent and applicable to MachO only.490/// This check is target-dependent and applicable to MachO only.
491pub fn checkInIndirectSymtab(self: *CheckObject) void {491pub fn checkInIndirectSymtab(check_object: *CheckObject) void {
492 const label = switch (self.obj_format) {492 const label = switch (check_object.obj_format) {
493 .macho => MachODumper.indirect_symtab_label,493 .macho => MachODumper.indirect_symtab_label,
494 else => @panic("Unsupported target platform"),494 else => @panic("Unsupported target platform"),
495 };495 };
496 self.checkStart(.indirect_symtab);496 check_object.checkStart(.indirect_symtab);
497 self.checkExact(label);497 check_object.checkExact(label);
498}498}
499499
500/// Creates a new check checking specifically dynamic symbol table parsed and dumped from the object500/// Creates a new check checking specifically dynamic symbol table parsed and dumped from the object
501/// file.501/// file.
502/// This check is target-dependent and applicable to ELF only.502/// This check is target-dependent and applicable to ELF only.
503pub fn checkInDynamicSymtab(self: *CheckObject) void {503pub fn checkInDynamicSymtab(check_object: *CheckObject) void {
504 const label = switch (self.obj_format) {504 const label = switch (check_object.obj_format) {
505 .elf => ElfDumper.dynamic_symtab_label,505 .elf => ElfDumper.dynamic_symtab_label,
506 else => @panic("Unsupported target platform"),506 else => @panic("Unsupported target platform"),
507 };507 };
508 self.checkStart(.dynamic_symtab);508 check_object.checkStart(.dynamic_symtab);
509 self.checkExact(label);509 check_object.checkExact(label);
510}510}
511511
512/// Creates a new check checking specifically dynamic section parsed and dumped from the object512/// Creates a new check checking specifically dynamic section parsed and dumped from the object
513/// file.513/// file.
514/// This check is target-dependent and applicable to ELF only.514/// This check is target-dependent and applicable to ELF only.
515pub fn checkInDynamicSection(self: *CheckObject) void {515pub fn checkInDynamicSection(check_object: *CheckObject) void {
516 const label = switch (self.obj_format) {516 const label = switch (check_object.obj_format) {
517 .elf => ElfDumper.dynamic_section_label,517 .elf => ElfDumper.dynamic_section_label,
518 else => @panic("Unsupported target platform"),518 else => @panic("Unsupported target platform"),
519 };519 };
520 self.checkStart(.dynamic_section);520 check_object.checkStart(.dynamic_section);
521 self.checkExact(label);521 check_object.checkExact(label);
522}522}
523523
524/// Creates a new check checking specifically symbol table parsed and dumped from the archive524/// Creates a new check checking specifically symbol table parsed and dumped from the archive
525/// file.525/// file.
526pub fn checkInArchiveSymtab(self: *CheckObject) void {526pub fn checkInArchiveSymtab(check_object: *CheckObject) void {
527 const label = switch (self.obj_format) {527 const label = switch (check_object.obj_format) {
528 .elf => ElfDumper.archive_symtab_label,528 .elf => ElfDumper.archive_symtab_label,
529 else => @panic("TODO other file formats"),529 else => @panic("TODO other file formats"),
530 };530 };
531 self.checkStart(.archive_symtab);531 check_object.checkStart(.archive_symtab);
532 self.checkExact(label);532 check_object.checkExact(label);
533}533}
534534
535pub fn dumpSection(self: *CheckObject, name: [:0]const u8) void {535pub fn dumpSection(check_object: *CheckObject, name: [:0]const u8) void {
536 const new_check = Check.dumpSection(self.step.owner.allocator, name);536 const check = Check.dumpSection(check_object.step.owner.allocator, name);
537 self.checks.append(new_check) catch @panic("OOM");537 check_object.checks.append(check) catch @panic("OOM");
538}538}
539539
540/// Creates a new standalone, singular check which allows running simple binary operations540/// Creates a new standalone, singular check which allows running simple binary operations
541/// on the extracted variables. It will then compare the reduced program with the value of541/// on the extracted variables. It will then compare the reduced program with the value of
542/// the expected variable.542/// the expected variable.
543pub fn checkComputeCompare(543pub fn checkComputeCompare(
544 self: *CheckObject,544 check_object: *CheckObject,
545 program: []const u8,545 program: []const u8,
546 expected: ComputeCompareExpected,546 expected: ComputeCompareExpected,
547) void {547) void {
548 var new_check = Check.create(self.step.owner.allocator, .compute_compare);548 var check = Check.create(check_object.step.owner.allocator, .compute_compare);
549 new_check.computeCmp(.{ .string = self.step.owner.dupe(program) }, expected);549 check.computeCmp(.{ .string = check_object.step.owner.dupe(program) }, expected);
550 self.checks.append(new_check) catch @panic("OOM");550 check_object.checks.append(check) catch @panic("OOM");
551}551}
552552
553fn make(step: *Step, prog_node: *std.Progress.Node) !void {553fn make(step: *Step, prog_node: *std.Progress.Node) !void {
554 _ = prog_node;554 _ = prog_node;
555 const b = step.owner;555 const b = step.owner;
556 const gpa = b.allocator;556 const gpa = b.allocator;
557 const self: *CheckObject = @fieldParentPtr("step", step);557 const check_object: *CheckObject = @fieldParentPtr("step", step);
558558
559 const src_path = self.source.getPath(b);559 const src_path = check_object.source.getPath2(b, step);
560 const contents = fs.cwd().readFileAllocOptions(560 const contents = fs.cwd().readFileAllocOptions(
561 gpa,561 gpa,
562 src_path,562 src_path,
563 self.max_bytes,563 check_object.max_bytes,
564 null,564 null,
565 @alignOf(u64),565 @alignOf(u64),
566 null,566 null,
567 ) catch |err| return step.fail("unable to read '{s}': {s}", .{ src_path, @errorName(err) });567 ) catch |err| return step.fail("unable to read '{s}': {s}", .{ src_path, @errorName(err) });
568568
569 var vars = std.StringHashMap(u64).init(gpa);569 var vars = std.StringHashMap(u64).init(gpa);
570 for (self.checks.items) |chk| {570 for (check_object.checks.items) |chk| {
571 if (chk.kind == .compute_compare) {571 if (chk.kind == .compute_compare) {
572 assert(chk.actions.items.len == 1);572 assert(chk.actions.items.len == 1);
573 const act = chk.actions.items[0];573 const act = chk.actions.items[0];
...@@ -587,7 +587,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -587,7 +587,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
587 continue;587 continue;
588 }588 }
589589
590 const output = switch (self.obj_format) {590 const output = switch (check_object.obj_format) {
591 .macho => try MachODumper.parseAndDump(step, chk, contents),591 .macho => try MachODumper.parseAndDump(step, chk, contents),
592 .elf => try ElfDumper.parseAndDump(step, chk, contents),592 .elf => try ElfDumper.parseAndDump(step, chk, contents),
593 .coff => return step.fail("TODO coff parser", .{}),593 .coff => return step.fail("TODO coff parser", .{}),
...@@ -1597,8 +1597,8 @@ const MachODumper = struct {...@@ -1597,8 +1597,8 @@ const MachODumper = struct {
1597 },1597 },
1598 },1598 },
15991599
1600 inline fn rankByTag(self: Export) u3 {1600 inline fn rankByTag(@"export": Export) u3 {
1601 return switch (self.tag) {1601 return switch (@"export".tag) {
1602 .@"export" => 1,1602 .@"export" => 1,
1603 .reexport => 2,1603 .reexport => 2,
1604 .stub_resolver => 3,1604 .stub_resolver => 3,
lib/std/Build/Step/Compile.zig+352-355
...@@ -263,10 +263,10 @@ pub const HeaderInstallation = union(enum) {...@@ -263,10 +263,10 @@ pub const HeaderInstallation = union(enum) {
263 source: LazyPath,263 source: LazyPath,
264 dest_rel_path: []const u8,264 dest_rel_path: []const u8,
265265
266 pub fn dupe(self: File, b: *std.Build) File {266 pub fn dupe(file: File, b: *std.Build) File {
267 return .{267 return .{
268 .source = self.source.dupe(b),268 .source = file.source.dupe(b),
269 .dest_rel_path = b.dupePath(self.dest_rel_path),269 .dest_rel_path = b.dupePath(file.dest_rel_path),
270 };270 };
271 }271 }
272 };272 };
...@@ -284,31 +284,31 @@ pub const HeaderInstallation = union(enum) {...@@ -284,31 +284,31 @@ pub const HeaderInstallation = union(enum) {
284 /// `exclude_extensions` takes precedence over `include_extensions`.284 /// `exclude_extensions` takes precedence over `include_extensions`.
285 include_extensions: ?[]const []const u8 = &.{".h"},285 include_extensions: ?[]const []const u8 = &.{".h"},
286286
287 pub fn dupe(self: Directory.Options, b: *std.Build) Directory.Options {287 pub fn dupe(opts: Directory.Options, b: *std.Build) Directory.Options {
288 return .{288 return .{
289 .exclude_extensions = b.dupeStrings(self.exclude_extensions),289 .exclude_extensions = b.dupeStrings(opts.exclude_extensions),
290 .include_extensions = if (self.include_extensions) |incs| b.dupeStrings(incs) else null,290 .include_extensions = if (opts.include_extensions) |incs| b.dupeStrings(incs) else null,
291 };291 };
292 }292 }
293 };293 };
294294
295 pub fn dupe(self: Directory, b: *std.Build) Directory {295 pub fn dupe(dir: Directory, b: *std.Build) Directory {
296 return .{296 return .{
297 .source = self.source.dupe(b),297 .source = dir.source.dupe(b),
298 .dest_rel_path = b.dupePath(self.dest_rel_path),298 .dest_rel_path = b.dupePath(dir.dest_rel_path),
299 .options = self.options.dupe(b),299 .options = dir.options.dupe(b),
300 };300 };
301 }301 }
302 };302 };
303303
304 pub fn getSource(self: HeaderInstallation) LazyPath {304 pub fn getSource(installation: HeaderInstallation) LazyPath {
305 return switch (self) {305 return switch (installation) {
306 inline .file, .directory => |x| x.source,306 inline .file, .directory => |x| x.source,
307 };307 };
308 }308 }
309309
310 pub fn dupe(self: HeaderInstallation, b: *std.Build) HeaderInstallation {310 pub fn dupe(installation: HeaderInstallation, b: *std.Build) HeaderInstallation {
311 return switch (self) {311 return switch (installation) {
312 .file => |f| .{ .file = f.dupe(b) },312 .file => |f| .{ .file = f.dupe(b) },
313 .directory => |d| .{ .directory = d.dupe(b) },313 .directory => |d| .{ .directory = d.dupe(b) },
314 };314 };
...@@ -354,8 +354,8 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -354,8 +354,8 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
354 .version = options.version,354 .version = options.version,
355 }) catch @panic("OOM");355 }) catch @panic("OOM");
356356
357 const self = owner.allocator.create(Compile) catch @panic("OOM");357 const compile = owner.allocator.create(Compile) catch @panic("OOM");
358 self.* = .{358 compile.* = .{
359 .root_module = undefined,359 .root_module = undefined,
360 .verbose_link = false,360 .verbose_link = false,
361 .verbose_cc = false,361 .verbose_cc = false,
...@@ -398,57 +398,57 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -398,57 +398,57 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
398 .use_lld = options.use_lld,398 .use_lld = options.use_lld,
399 };399 };
400400
401 self.root_module.init(owner, options.root_module, self);401 compile.root_module.init(owner, options.root_module, compile);
402402
403 if (options.zig_lib_dir) |lp| {403 if (options.zig_lib_dir) |lp| {
404 self.zig_lib_dir = lp.dupe(self.step.owner);404 compile.zig_lib_dir = lp.dupe(compile.step.owner);
405 lp.addStepDependencies(&self.step);405 lp.addStepDependencies(&compile.step);
406 }406 }
407407
408 if (options.test_runner) |lp| {408 if (options.test_runner) |lp| {
409 self.test_runner = lp.dupe(self.step.owner);409 compile.test_runner = lp.dupe(compile.step.owner);
410 lp.addStepDependencies(&self.step);410 lp.addStepDependencies(&compile.step);
411 }411 }
412412
413 // Only the PE/COFF format has a Resource Table which is where the manifest413 // Only the PE/COFF format has a Resource Table which is where the manifest
414 // gets embedded, so for any other target the manifest file is just ignored.414 // gets embedded, so for any other target the manifest file is just ignored.
415 if (target.ofmt == .coff) {415 if (target.ofmt == .coff) {
416 if (options.win32_manifest) |lp| {416 if (options.win32_manifest) |lp| {
417 self.win32_manifest = lp.dupe(self.step.owner);417 compile.win32_manifest = lp.dupe(compile.step.owner);
418 lp.addStepDependencies(&self.step);418 lp.addStepDependencies(&compile.step);
419 }419 }
420 }420 }
421421
422 if (self.kind == .lib) {422 if (compile.kind == .lib) {
423 if (self.linkage != null and self.linkage.? == .static) {423 if (compile.linkage != null and compile.linkage.? == .static) {
424 self.out_lib_filename = self.out_filename;424 compile.out_lib_filename = compile.out_filename;
425 } else if (self.version) |version| {425 } else if (compile.version) |version| {
426 if (target.isDarwin()) {426 if (target.isDarwin()) {
427 self.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{427 compile.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{
428 self.name,428 compile.name,
429 version.major,429 version.major,
430 });430 });
431 self.name_only_filename = owner.fmt("lib{s}.dylib", .{self.name});431 compile.name_only_filename = owner.fmt("lib{s}.dylib", .{compile.name});
432 self.out_lib_filename = self.out_filename;432 compile.out_lib_filename = compile.out_filename;
433 } else if (target.os.tag == .windows) {433 } else if (target.os.tag == .windows) {
434 self.out_lib_filename = owner.fmt("{s}.lib", .{self.name});434 compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name});
435 } else {435 } else {
436 self.major_only_filename = owner.fmt("lib{s}.so.{d}", .{ self.name, version.major });436 compile.major_only_filename = owner.fmt("lib{s}.so.{d}", .{ compile.name, version.major });
437 self.name_only_filename = owner.fmt("lib{s}.so", .{self.name});437 compile.name_only_filename = owner.fmt("lib{s}.so", .{compile.name});
438 self.out_lib_filename = self.out_filename;438 compile.out_lib_filename = compile.out_filename;
439 }439 }
440 } else {440 } else {
441 if (target.isDarwin()) {441 if (target.isDarwin()) {
442 self.out_lib_filename = self.out_filename;442 compile.out_lib_filename = compile.out_filename;
443 } else if (target.os.tag == .windows) {443 } else if (target.os.tag == .windows) {
444 self.out_lib_filename = owner.fmt("{s}.lib", .{self.name});444 compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name});
445 } else {445 } else {
446 self.out_lib_filename = self.out_filename;446 compile.out_lib_filename = compile.out_filename;
447 }447 }
448 }448 }
449 }449 }
450450
451 return self;451 return compile;
452}452}
453453
454/// Marks the specified header for installation alongside this artifact.454/// Marks the specified header for installation alongside this artifact.
...@@ -545,38 +545,38 @@ pub fn addObjCopy(cs: *Compile, options: Step.ObjCopy.Options) *Step.ObjCopy {...@@ -545,38 +545,38 @@ pub fn addObjCopy(cs: *Compile, options: Step.ObjCopy.Options) *Step.ObjCopy {
545 return b.addObjCopy(cs.getEmittedBin(), copy);545 return b.addObjCopy(cs.getEmittedBin(), copy);
546}546}
547547
548pub fn checkObject(self: *Compile) *Step.CheckObject {548pub fn checkObject(compile: *Compile) *Step.CheckObject {
549 return Step.CheckObject.create(self.step.owner, self.getEmittedBin(), self.rootModuleTarget().ofmt);549 return Step.CheckObject.create(compile.step.owner, compile.getEmittedBin(), compile.rootModuleTarget().ofmt);
550}550}
551551
552/// deprecated: use `setLinkerScript`552/// deprecated: use `setLinkerScript`
553pub const setLinkerScriptPath = setLinkerScript;553pub const setLinkerScriptPath = setLinkerScript;
554554
555pub fn setLinkerScript(self: *Compile, source: LazyPath) void {555pub fn setLinkerScript(compile: *Compile, source: LazyPath) void {
556 const b = self.step.owner;556 const b = compile.step.owner;
557 self.linker_script = source.dupe(b);557 compile.linker_script = source.dupe(b);
558 source.addStepDependencies(&self.step);558 source.addStepDependencies(&compile.step);
559}559}
560560
561pub fn setVersionScript(self: *Compile, source: LazyPath) void {561pub fn setVersionScript(compile: *Compile, source: LazyPath) void {
562 const b = self.step.owner;562 const b = compile.step.owner;
563 self.version_script = source.dupe(b);563 compile.version_script = source.dupe(b);
564 source.addStepDependencies(&self.step);564 source.addStepDependencies(&compile.step);
565}565}
566566
567pub fn forceUndefinedSymbol(self: *Compile, symbol_name: []const u8) void {567pub fn forceUndefinedSymbol(compile: *Compile, symbol_name: []const u8) void {
568 const b = self.step.owner;568 const b = compile.step.owner;
569 self.force_undefined_symbols.put(b.dupe(symbol_name), {}) catch @panic("OOM");569 compile.force_undefined_symbols.put(b.dupe(symbol_name), {}) catch @panic("OOM");
570}570}
571571
572/// Returns whether the library, executable, or object depends on a particular system library.572/// Returns whether the library, executable, or object depends on a particular system library.
573/// Includes transitive dependencies.573/// Includes transitive dependencies.
574pub fn dependsOnSystemLibrary(self: *const Compile, name: []const u8) bool {574pub fn dependsOnSystemLibrary(compile: *const Compile, name: []const u8) bool {
575 var is_linking_libc = false;575 var is_linking_libc = false;
576 var is_linking_libcpp = false;576 var is_linking_libcpp = false;
577577
578 var it = self.root_module.iterateDependencies(self, true);578 var dep_it = compile.root_module.iterateDependencies(compile, true);
579 while (it.next()) |module| {579 while (dep_it.next()) |module| {
580 for (module.link_objects.items) |link_object| {580 for (module.link_objects.items) |link_object| {
581 switch (link_object) {581 switch (link_object) {
582 .system_lib => |lib| if (mem.eql(u8, lib.name, name)) return true,582 .system_lib => |lib| if (mem.eql(u8, lib.name, name)) return true,
...@@ -587,31 +587,31 @@ pub fn dependsOnSystemLibrary(self: *const Compile, name: []const u8) bool {...@@ -587,31 +587,31 @@ pub fn dependsOnSystemLibrary(self: *const Compile, name: []const u8) bool {
587 is_linking_libcpp = is_linking_libcpp or module.link_libcpp == true;587 is_linking_libcpp = is_linking_libcpp or module.link_libcpp == true;
588 }588 }
589589
590 if (self.rootModuleTarget().is_libc_lib_name(name)) {590 if (compile.rootModuleTarget().is_libc_lib_name(name)) {
591 return is_linking_libc;591 return is_linking_libc;
592 }592 }
593593
594 if (self.rootModuleTarget().is_libcpp_lib_name(name)) {594 if (compile.rootModuleTarget().is_libcpp_lib_name(name)) {
595 return is_linking_libcpp;595 return is_linking_libcpp;
596 }596 }
597597
598 return false;598 return false;
599}599}
600600
601pub fn isDynamicLibrary(self: *const Compile) bool {601pub fn isDynamicLibrary(compile: *const Compile) bool {
602 return self.kind == .lib and self.linkage == .dynamic;602 return compile.kind == .lib and compile.linkage == .dynamic;
603}603}
604604
605pub fn isStaticLibrary(self: *const Compile) bool {605pub fn isStaticLibrary(compile: *const Compile) bool {
606 return self.kind == .lib and self.linkage != .dynamic;606 return compile.kind == .lib and compile.linkage != .dynamic;
607}607}
608608
609pub fn isDll(self: *Compile) bool {609pub fn isDll(compile: *Compile) bool {
610 return self.isDynamicLibrary() and self.rootModuleTarget().os.tag == .windows;610 return compile.isDynamicLibrary() and compile.rootModuleTarget().os.tag == .windows;
611}611}
612612
613pub fn producesPdbFile(self: *Compile) bool {613pub fn producesPdbFile(compile: *Compile) bool {
614 const target = self.rootModuleTarget();614 const target = compile.rootModuleTarget();
615 // TODO: Is this right? Isn't PDB for *any* PE/COFF file?615 // TODO: Is this right? Isn't PDB for *any* PE/COFF file?
616 // TODO: just share this logic with the compiler, silly!616 // TODO: just share this logic with the compiler, silly!
617 switch (target.os.tag) {617 switch (target.os.tag) {
...@@ -619,24 +619,24 @@ pub fn producesPdbFile(self: *Compile) bool {...@@ -619,24 +619,24 @@ pub fn producesPdbFile(self: *Compile) bool {
619 else => return false,619 else => return false,
620 }620 }
621 if (target.ofmt == .c) return false;621 if (target.ofmt == .c) return false;
622 if (self.root_module.strip == true or622 if (compile.root_module.strip == true or
623 (self.root_module.strip == null and self.root_module.optimize == .ReleaseSmall))623 (compile.root_module.strip == null and compile.root_module.optimize == .ReleaseSmall))
624 {624 {
625 return false;625 return false;
626 }626 }
627 return self.isDynamicLibrary() or self.kind == .exe or self.kind == .@"test";627 return compile.isDynamicLibrary() or compile.kind == .exe or compile.kind == .@"test";
628}628}
629629
630pub fn producesImplib(self: *Compile) bool {630pub fn producesImplib(compile: *Compile) bool {
631 return self.isDll();631 return compile.isDll();
632}632}
633633
634pub fn linkLibC(self: *Compile) void {634pub fn linkLibC(compile: *Compile) void {
635 self.root_module.link_libc = true;635 compile.root_module.link_libc = true;
636}636}
637637
638pub fn linkLibCpp(self: *Compile) void {638pub fn linkLibCpp(compile: *Compile) void {
639 self.root_module.link_libcpp = true;639 compile.root_module.link_libcpp = true;
640}640}
641641
642/// Deprecated. Use `c.root_module.addCMacro`.642/// Deprecated. Use `c.root_module.addCMacro`.
...@@ -651,8 +651,8 @@ const PkgConfigResult = struct {...@@ -651,8 +651,8 @@ const PkgConfigResult = struct {
651651
652/// Run pkg-config for the given library name and parse the output, returning the arguments652/// Run pkg-config for the given library name and parse the output, returning the arguments
653/// that should be passed to zig to link the given library.653/// that should be passed to zig to link the given library.
654fn runPkgConfig(self: *Compile, lib_name: []const u8) !PkgConfigResult {654fn runPkgConfig(compile: *Compile, lib_name: []const u8) !PkgConfigResult {
655 const b = self.step.owner;655 const b = compile.step.owner;
656 const pkg_name = match: {656 const pkg_name = match: {
657 // First we have to map the library name to pkg config name. Unfortunately,657 // First we have to map the library name to pkg config name. Unfortunately,
658 // there are several examples where this is not straightforward:658 // there are several examples where this is not straightforward:
...@@ -717,30 +717,30 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) !PkgConfigResult {...@@ -717,30 +717,30 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) !PkgConfigResult {
717 var zig_libs = ArrayList([]const u8).init(b.allocator);717 var zig_libs = ArrayList([]const u8).init(b.allocator);
718 defer zig_libs.deinit();718 defer zig_libs.deinit();
719719
720 var it = mem.tokenizeAny(u8, stdout, " \r\n\t");720 var arg_it = mem.tokenizeAny(u8, stdout, " \r\n\t");
721 while (it.next()) |tok| {721 while (arg_it.next()) |arg| {
722 if (mem.eql(u8, tok, "-I")) {722 if (mem.eql(u8, arg, "-I")) {
723 const dir = it.next() orelse return error.PkgConfigInvalidOutput;723 const dir = arg_it.next() orelse return error.PkgConfigInvalidOutput;
724 try zig_cflags.appendSlice(&[_][]const u8{ "-I", dir });724 try zig_cflags.appendSlice(&[_][]const u8{ "-I", dir });
725 } else if (mem.startsWith(u8, tok, "-I")) {725 } else if (mem.startsWith(u8, arg, "-I")) {
726 try zig_cflags.append(tok);726 try zig_cflags.append(arg);
727 } else if (mem.eql(u8, tok, "-L")) {727 } else if (mem.eql(u8, arg, "-L")) {
728 const dir = it.next() orelse return error.PkgConfigInvalidOutput;728 const dir = arg_it.next() orelse return error.PkgConfigInvalidOutput;
729 try zig_libs.appendSlice(&[_][]const u8{ "-L", dir });729 try zig_libs.appendSlice(&[_][]const u8{ "-L", dir });
730 } else if (mem.startsWith(u8, tok, "-L")) {730 } else if (mem.startsWith(u8, arg, "-L")) {
731 try zig_libs.append(tok);731 try zig_libs.append(arg);
732 } else if (mem.eql(u8, tok, "-l")) {732 } else if (mem.eql(u8, arg, "-l")) {
733 const lib = it.next() orelse return error.PkgConfigInvalidOutput;733 const lib = arg_it.next() orelse return error.PkgConfigInvalidOutput;
734 try zig_libs.appendSlice(&[_][]const u8{ "-l", lib });734 try zig_libs.appendSlice(&[_][]const u8{ "-l", lib });
735 } else if (mem.startsWith(u8, tok, "-l")) {735 } else if (mem.startsWith(u8, arg, "-l")) {
736 try zig_libs.append(tok);736 try zig_libs.append(arg);
737 } else if (mem.eql(u8, tok, "-D")) {737 } else if (mem.eql(u8, arg, "-D")) {
738 const macro = it.next() orelse return error.PkgConfigInvalidOutput;738 const macro = arg_it.next() orelse return error.PkgConfigInvalidOutput;
739 try zig_cflags.appendSlice(&[_][]const u8{ "-D", macro });739 try zig_cflags.appendSlice(&[_][]const u8{ "-D", macro });
740 } else if (mem.startsWith(u8, tok, "-D")) {740 } else if (mem.startsWith(u8, arg, "-D")) {
741 try zig_cflags.append(tok);741 try zig_cflags.append(arg);
742 } else if (b.debug_pkg_config) {742 } else if (b.debug_pkg_config) {
743 return self.step.fail("unknown pkg-config flag '{s}'", .{tok});743 return compile.step.fail("unknown pkg-config flag '{s}'", .{arg});
744 }744 }
745 }745 }
746746
...@@ -750,16 +750,16 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) !PkgConfigResult {...@@ -750,16 +750,16 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) !PkgConfigResult {
750 };750 };
751}751}
752752
753pub fn linkSystemLibrary(self: *Compile, name: []const u8) void {753pub fn linkSystemLibrary(compile: *Compile, name: []const u8) void {
754 return self.root_module.linkSystemLibrary(name, .{});754 return compile.root_module.linkSystemLibrary(name, .{});
755}755}
756756
757pub fn linkSystemLibrary2(757pub fn linkSystemLibrary2(
758 self: *Compile,758 compile: *Compile,
759 name: []const u8,759 name: []const u8,
760 options: Module.LinkSystemLibraryOptions,760 options: Module.LinkSystemLibraryOptions,
761) void {761) void {
762 return self.root_module.linkSystemLibrary(name, options);762 return compile.root_module.linkSystemLibrary(name, options);
763}763}
764764
765pub fn linkFramework(c: *Compile, name: []const u8) void {765pub fn linkFramework(c: *Compile, name: []const u8) void {
...@@ -777,155 +777,153 @@ pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {...@@ -777,155 +777,153 @@ pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {
777}777}
778778
779/// Handy when you have many C/C++ source files and want them all to have the same flags.779/// Handy when you have many C/C++ source files and want them all to have the same flags.
780pub fn addCSourceFiles(self: *Compile, options: Module.AddCSourceFilesOptions) void {780pub fn addCSourceFiles(compile: *Compile, options: Module.AddCSourceFilesOptions) void {
781 self.root_module.addCSourceFiles(options);781 compile.root_module.addCSourceFiles(options);
782}782}
783783
784pub fn addCSourceFile(self: *Compile, source: Module.CSourceFile) void {784pub fn addCSourceFile(compile: *Compile, source: Module.CSourceFile) void {
785 self.root_module.addCSourceFile(source);785 compile.root_module.addCSourceFile(source);
786}786}
787787
788/// Resource files must have the extension `.rc`.788/// Resource files must have the extension `.rc`.
789/// Can be called regardless of target. The .rc file will be ignored789/// Can be called regardless of target. The .rc file will be ignored
790/// if the target object format does not support embedded resources.790/// if the target object format does not support embedded resources.
791pub fn addWin32ResourceFile(self: *Compile, source: Module.RcSourceFile) void {791pub fn addWin32ResourceFile(compile: *Compile, source: Module.RcSourceFile) void {
792 self.root_module.addWin32ResourceFile(source);792 compile.root_module.addWin32ResourceFile(source);
793}793}
794794
795pub fn setVerboseLink(self: *Compile, value: bool) void {795pub fn setVerboseLink(compile: *Compile, value: bool) void {
796 self.verbose_link = value;796 compile.verbose_link = value;
797}797}
798798
799pub fn setVerboseCC(self: *Compile, value: bool) void {799pub fn setVerboseCC(compile: *Compile, value: bool) void {
800 self.verbose_cc = value;800 compile.verbose_cc = value;
801}801}
802802
803pub fn setLibCFile(self: *Compile, libc_file: ?LazyPath) void {803pub fn setLibCFile(compile: *Compile, libc_file: ?LazyPath) void {
804 const b = self.step.owner;804 const b = compile.step.owner;
805 self.libc_file = if (libc_file) |f| f.dupe(b) else null;805 compile.libc_file = if (libc_file) |f| f.dupe(b) else null;
806}806}
807807
808fn getEmittedFileGeneric(self: *Compile, output_file: *?*GeneratedFile) LazyPath {808fn getEmittedFileGeneric(compile: *Compile, output_file: *?*GeneratedFile) LazyPath {
809 if (output_file.*) |g| {809 if (output_file.*) |file| return .{ .generated = .{ .file = file } };
810 return .{ .generated = g };810 const arena = compile.step.owner.allocator;
811 }
812 const arena = self.step.owner.allocator;
813 const generated_file = arena.create(GeneratedFile) catch @panic("OOM");811 const generated_file = arena.create(GeneratedFile) catch @panic("OOM");
814 generated_file.* = .{ .step = &self.step };812 generated_file.* = .{ .step = &compile.step };
815 output_file.* = generated_file;813 output_file.* = generated_file;
816 return .{ .generated = generated_file };814 return .{ .generated = .{ .file = generated_file } };
817}815}
818816
819/// Returns the path to the directory that contains the emitted binary file.817/// Returns the path to the directory that contains the emitted binary file.
820pub fn getEmittedBinDirectory(self: *Compile) LazyPath {818pub fn getEmittedBinDirectory(compile: *Compile) LazyPath {
821 _ = self.getEmittedBin();819 _ = compile.getEmittedBin();
822 return self.getEmittedFileGeneric(&self.emit_directory);820 return compile.getEmittedFileGeneric(&compile.emit_directory);
823}821}
824822
825/// Returns the path to the generated executable, library or object file.823/// Returns the path to the generated executable, library or object file.
826/// To run an executable built with zig build, use `run`, or create an install step and invoke it.824/// To run an executable built with zig build, use `run`, or create an install step and invoke it.
827pub fn getEmittedBin(self: *Compile) LazyPath {825pub fn getEmittedBin(compile: *Compile) LazyPath {
828 return self.getEmittedFileGeneric(&self.generated_bin);826 return compile.getEmittedFileGeneric(&compile.generated_bin);
829}827}
830828
831/// Returns the path to the generated import library.829/// Returns the path to the generated import library.
832/// This function can only be called for libraries.830/// This function can only be called for libraries.
833pub fn getEmittedImplib(self: *Compile) LazyPath {831pub fn getEmittedImplib(compile: *Compile) LazyPath {
834 assert(self.kind == .lib);832 assert(compile.kind == .lib);
835 return self.getEmittedFileGeneric(&self.generated_implib);833 return compile.getEmittedFileGeneric(&compile.generated_implib);
836}834}
837835
838/// Returns the path to the generated header file.836/// Returns the path to the generated header file.
839/// This function can only be called for libraries or objects.837/// This function can only be called for libraries or objects.
840pub fn getEmittedH(self: *Compile) LazyPath {838pub fn getEmittedH(compile: *Compile) LazyPath {
841 assert(self.kind != .exe and self.kind != .@"test");839 assert(compile.kind != .exe and compile.kind != .@"test");
842 return self.getEmittedFileGeneric(&self.generated_h);840 return compile.getEmittedFileGeneric(&compile.generated_h);
843}841}
844842
845/// Returns the generated PDB file.843/// Returns the generated PDB file.
846/// If the compilation does not produce a PDB file, this causes a FileNotFound error844/// If the compilation does not produce a PDB file, this causes a FileNotFound error
847/// at build time.845/// at build time.
848pub fn getEmittedPdb(self: *Compile) LazyPath {846pub fn getEmittedPdb(compile: *Compile) LazyPath {
849 _ = self.getEmittedBin();847 _ = compile.getEmittedBin();
850 return self.getEmittedFileGeneric(&self.generated_pdb);848 return compile.getEmittedFileGeneric(&compile.generated_pdb);
851}849}
852850
853/// Returns the path to the generated documentation directory.851/// Returns the path to the generated documentation directory.
854pub fn getEmittedDocs(self: *Compile) LazyPath {852pub fn getEmittedDocs(compile: *Compile) LazyPath {
855 return self.getEmittedFileGeneric(&self.generated_docs);853 return compile.getEmittedFileGeneric(&compile.generated_docs);
856}854}
857855
858/// Returns the path to the generated assembly code.856/// Returns the path to the generated assembly code.
859pub fn getEmittedAsm(self: *Compile) LazyPath {857pub fn getEmittedAsm(compile: *Compile) LazyPath {
860 return self.getEmittedFileGeneric(&self.generated_asm);858 return compile.getEmittedFileGeneric(&compile.generated_asm);
861}859}
862860
863/// Returns the path to the generated LLVM IR.861/// Returns the path to the generated LLVM IR.
864pub fn getEmittedLlvmIr(self: *Compile) LazyPath {862pub fn getEmittedLlvmIr(compile: *Compile) LazyPath {
865 return self.getEmittedFileGeneric(&self.generated_llvm_ir);863 return compile.getEmittedFileGeneric(&compile.generated_llvm_ir);
866}864}
867865
868/// Returns the path to the generated LLVM BC.866/// Returns the path to the generated LLVM BC.
869pub fn getEmittedLlvmBc(self: *Compile) LazyPath {867pub fn getEmittedLlvmBc(compile: *Compile) LazyPath {
870 return self.getEmittedFileGeneric(&self.generated_llvm_bc);868 return compile.getEmittedFileGeneric(&compile.generated_llvm_bc);
871}869}
872870
873pub fn addAssemblyFile(self: *Compile, source: LazyPath) void {871pub fn addAssemblyFile(compile: *Compile, source: LazyPath) void {
874 self.root_module.addAssemblyFile(source);872 compile.root_module.addAssemblyFile(source);
875}873}
876874
877pub fn addObjectFile(self: *Compile, source: LazyPath) void {875pub fn addObjectFile(compile: *Compile, source: LazyPath) void {
878 self.root_module.addObjectFile(source);876 compile.root_module.addObjectFile(source);
879}877}
880878
881pub fn addObject(self: *Compile, object: *Compile) void {879pub fn addObject(compile: *Compile, object: *Compile) void {
882 self.root_module.addObject(object);880 compile.root_module.addObject(object);
883}881}
884882
885pub fn linkLibrary(self: *Compile, library: *Compile) void {883pub fn linkLibrary(compile: *Compile, library: *Compile) void {
886 self.root_module.linkLibrary(library);884 compile.root_module.linkLibrary(library);
887}885}
888886
889pub fn addAfterIncludePath(self: *Compile, lazy_path: LazyPath) void {887pub fn addAfterIncludePath(compile: *Compile, lazy_path: LazyPath) void {
890 self.root_module.addAfterIncludePath(lazy_path);888 compile.root_module.addAfterIncludePath(lazy_path);
891}889}
892890
893pub fn addSystemIncludePath(self: *Compile, lazy_path: LazyPath) void {891pub fn addSystemIncludePath(compile: *Compile, lazy_path: LazyPath) void {
894 self.root_module.addSystemIncludePath(lazy_path);892 compile.root_module.addSystemIncludePath(lazy_path);
895}893}
896894
897pub fn addIncludePath(self: *Compile, lazy_path: LazyPath) void {895pub fn addIncludePath(compile: *Compile, lazy_path: LazyPath) void {
898 self.root_module.addIncludePath(lazy_path);896 compile.root_module.addIncludePath(lazy_path);
899}897}
900898
901pub fn addConfigHeader(self: *Compile, config_header: *Step.ConfigHeader) void {899pub fn addConfigHeader(compile: *Compile, config_header: *Step.ConfigHeader) void {
902 self.root_module.addConfigHeader(config_header);900 compile.root_module.addConfigHeader(config_header);
903}901}
904902
905pub fn addLibraryPath(self: *Compile, directory_path: LazyPath) void {903pub fn addLibraryPath(compile: *Compile, directory_path: LazyPath) void {
906 self.root_module.addLibraryPath(directory_path);904 compile.root_module.addLibraryPath(directory_path);
907}905}
908906
909pub fn addRPath(self: *Compile, directory_path: LazyPath) void {907pub fn addRPath(compile: *Compile, directory_path: LazyPath) void {
910 self.root_module.addRPath(directory_path);908 compile.root_module.addRPath(directory_path);
911}909}
912910
913pub fn addSystemFrameworkPath(self: *Compile, directory_path: LazyPath) void {911pub fn addSystemFrameworkPath(compile: *Compile, directory_path: LazyPath) void {
914 self.root_module.addSystemFrameworkPath(directory_path);912 compile.root_module.addSystemFrameworkPath(directory_path);
915}913}
916914
917pub fn addFrameworkPath(self: *Compile, directory_path: LazyPath) void {915pub fn addFrameworkPath(compile: *Compile, directory_path: LazyPath) void {
918 self.root_module.addFrameworkPath(directory_path);916 compile.root_module.addFrameworkPath(directory_path);
919}917}
920918
921pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void {919pub fn setExecCmd(compile: *Compile, args: []const ?[]const u8) void {
922 const b = self.step.owner;920 const b = compile.step.owner;
923 assert(self.kind == .@"test");921 assert(compile.kind == .@"test");
924 const duped_args = b.allocator.alloc(?[]u8, args.len) catch @panic("OOM");922 const duped_args = b.allocator.alloc(?[]u8, args.len) catch @panic("OOM");
925 for (args, 0..) |arg, i| {923 for (args, 0..) |arg, i| {
926 duped_args[i] = if (arg) |a| b.dupe(a) else null;924 duped_args[i] = if (arg) |a| b.dupe(a) else null;
927 }925 }
928 self.exec_cmd_args = duped_args;926 compile.exec_cmd_args = duped_args;
929}927}
930928
931const CliNamedModules = struct {929const CliNamedModules = struct {
...@@ -937,42 +935,42 @@ const CliNamedModules = struct {...@@ -937,42 +935,42 @@ const CliNamedModules = struct {
937 /// It will help here to have both a mapping from module to name and a set935 /// It will help here to have both a mapping from module to name and a set
938 /// of all the currently-used names.936 /// of all the currently-used names.
939 fn init(arena: Allocator, root_module: *Module) Allocator.Error!CliNamedModules {937 fn init(arena: Allocator, root_module: *Module) Allocator.Error!CliNamedModules {
940 var self: CliNamedModules = .{938 var compile: CliNamedModules = .{
941 .modules = .{},939 .modules = .{},
942 .names = .{},940 .names = .{},
943 };941 };
944 var it = root_module.iterateDependencies(null, false);942 var dep_it = root_module.iterateDependencies(null, false);
945 {943 {
946 const item = it.next().?;944 const item = dep_it.next().?;
947 assert(root_module == item.module);945 assert(root_module == item.module);
948 try self.modules.put(arena, root_module, {});946 try compile.modules.put(arena, root_module, {});
949 try self.names.put(arena, "root", {});947 try compile.names.put(arena, "root", {});
950 }948 }
951 while (it.next()) |item| {949 while (dep_it.next()) |item| {
952 var name = item.name;950 var name = item.name;
953 var n: usize = 0;951 var n: usize = 0;
954 while (true) {952 while (true) {
955 const gop = try self.names.getOrPut(arena, name);953 const gop = try compile.names.getOrPut(arena, name);
956 if (!gop.found_existing) {954 if (!gop.found_existing) {
957 try self.modules.putNoClobber(arena, item.module, {});955 try compile.modules.putNoClobber(arena, item.module, {});
958 break;956 break;
959 }957 }
960 name = try std.fmt.allocPrint(arena, "{s}{d}", .{ item.name, n });958 name = try std.fmt.allocPrint(arena, "{s}{d}", .{ item.name, n });
961 n += 1;959 n += 1;
962 }960 }
963 }961 }
964 return self;962 return compile;
965 }963 }
966};964};
967965
968fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) []const u8 {966fn getGeneratedFilePath(compile: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) []const u8 {
969 const maybe_path: ?*GeneratedFile = @field(self, tag_name);967 const maybe_path: ?*GeneratedFile = @field(compile, tag_name);
970968
971 const generated_file = maybe_path orelse {969 const generated_file = maybe_path orelse {
972 std.debug.getStderrMutex().lock();970 std.debug.getStderrMutex().lock();
973 const stderr = std.io.getStdErr();971 const stderr = std.io.getStdErr();
974972
975 std.Build.dumpBadGetPathHelp(&self.step, stderr, self.step.owner, asking_step) catch {};973 std.Build.dumpBadGetPathHelp(&compile.step, stderr, compile.step.owner, asking_step) catch {};
976974
977 @panic("missing emit option for " ++ tag_name);975 @panic("missing emit option for " ++ tag_name);
978 };976 };
...@@ -981,7 +979,7 @@ fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_st...@@ -981,7 +979,7 @@ fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_st
981 std.debug.getStderrMutex().lock();979 std.debug.getStderrMutex().lock();
982 const stderr = std.io.getStdErr();980 const stderr = std.io.getStdErr();
983981
984 std.Build.dumpBadGetPathHelp(&self.step, stderr, self.step.owner, asking_step) catch {};982 std.Build.dumpBadGetPathHelp(&compile.step, stderr, compile.step.owner, asking_step) catch {};
985983
986 @panic(tag_name ++ " is null. Is there a missing step dependency?");984 @panic(tag_name ++ " is null. Is there a missing step dependency?");
987 };985 };
...@@ -992,14 +990,14 @@ fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_st...@@ -992,14 +990,14 @@ fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_st
992fn make(step: *Step, prog_node: *std.Progress.Node) !void {990fn make(step: *Step, prog_node: *std.Progress.Node) !void {
993 const b = step.owner;991 const b = step.owner;
994 const arena = b.allocator;992 const arena = b.allocator;
995 const self: *Compile = @fieldParentPtr("step", step);993 const compile: *Compile = @fieldParentPtr("step", step);
996994
997 var zig_args = ArrayList([]const u8).init(arena);995 var zig_args = ArrayList([]const u8).init(arena);
998 defer zig_args.deinit();996 defer zig_args.deinit();
999997
1000 try zig_args.append(b.graph.zig_exe);998 try zig_args.append(b.graph.zig_exe);
1001999
1002 const cmd = switch (self.kind) {1000 const cmd = switch (compile.kind) {
1003 .lib => "build-lib",1001 .lib => "build-lib",
1004 .exe => "build-exe",1002 .exe => "build-exe",
1005 .obj => "build-obj",1003 .obj => "build-obj",
...@@ -1011,14 +1009,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1011,14 +1009,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1011 try zig_args.append(try std.fmt.allocPrint(arena, "-freference-trace={d}", .{some}));1009 try zig_args.append(try std.fmt.allocPrint(arena, "-freference-trace={d}", .{some}));
1012 }1010 }
10131011
1014 try addFlag(&zig_args, "llvm", self.use_llvm);1012 try addFlag(&zig_args, "llvm", compile.use_llvm);
1015 try addFlag(&zig_args, "lld", self.use_lld);1013 try addFlag(&zig_args, "lld", compile.use_lld);
10161014
1017 if (self.root_module.resolved_target.?.query.ofmt) |ofmt| {1015 if (compile.root_module.resolved_target.?.query.ofmt) |ofmt| {
1018 try zig_args.append(try std.fmt.allocPrint(arena, "-ofmt={s}", .{@tagName(ofmt)}));1016 try zig_args.append(try std.fmt.allocPrint(arena, "-ofmt={s}", .{@tagName(ofmt)}));
1019 }1017 }
10201018
1021 switch (self.entry) {1019 switch (compile.entry) {
1022 .default => {},1020 .default => {},
1023 .disabled => try zig_args.append("-fno-entry"),1021 .disabled => try zig_args.append("-fno-entry"),
1024 .enabled => try zig_args.append("-fentry"),1022 .enabled => try zig_args.append("-fentry"),
...@@ -1028,14 +1026,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1028,14 +1026,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1028 }1026 }
10291027
1030 {1028 {
1031 var it = self.force_undefined_symbols.keyIterator();1029 var symbol_it = compile.force_undefined_symbols.keyIterator();
1032 while (it.next()) |symbol_name| {1030 while (symbol_it.next()) |symbol_name| {
1033 try zig_args.append("--force_undefined");1031 try zig_args.append("--force_undefined");
1034 try zig_args.append(symbol_name.*);1032 try zig_args.append(symbol_name.*);
1035 }1033 }
1036 }1034 }
10371035
1038 if (self.stack_size) |stack_size| {1036 if (compile.stack_size) |stack_size| {
1039 try zig_args.append("--stack");1037 try zig_args.append("--stack");
1040 try zig_args.append(try std.fmt.allocPrint(arena, "{}", .{stack_size}));1038 try zig_args.append(try std.fmt.allocPrint(arena, "{}", .{stack_size}));
1041 }1039 }
...@@ -1053,47 +1051,44 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1053,47 +1051,44 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1053 var prev_preferred_link_mode: std.builtin.LinkMode = .dynamic;1051 var prev_preferred_link_mode: std.builtin.LinkMode = .dynamic;
1054 // Track the number of positional arguments so that a nice error can be1052 // Track the number of positional arguments so that a nice error can be
1055 // emitted if there is nothing to link.1053 // emitted if there is nothing to link.
1056 var total_linker_objects: usize = @intFromBool(self.root_module.root_source_file != null);1054 var total_linker_objects: usize = @intFromBool(compile.root_module.root_source_file != null);
10571055
1058 {1056 {
1059 // Fully recursive iteration including dynamic libraries to detect1057 // Fully recursive iteration including dynamic libraries to detect
1060 // libc and libc++ linkage.1058 // libc and libc++ linkage.
1061 var it = self.root_module.iterateDependencies(self, true);1059 var dep_it = compile.root_module.iterateDependencies(compile, true);
1062 while (it.next()) |key| {1060 while (dep_it.next()) |key| {
1063 if (key.module.link_libc == true) self.is_linking_libc = true;1061 if (key.module.link_libc == true) compile.is_linking_libc = true;
1064 if (key.module.link_libcpp == true) self.is_linking_libcpp = true;1062 if (key.module.link_libcpp == true) compile.is_linking_libcpp = true;
1065 }1063 }
1066 }1064 }
10671065
1068 var cli_named_modules = try CliNamedModules.init(arena, &self.root_module);1066 var cli_named_modules = try CliNamedModules.init(arena, &compile.root_module);
10691067
1070 // For this loop, don't chase dynamic libraries because their link1068 // For this loop, don't chase dynamic libraries because their link
1071 // objects are already linked.1069 // objects are already linked.
1072 var it = self.root_module.iterateDependencies(self, false);1070 var dep_it = compile.root_module.iterateDependencies(compile, false);
1073
1074 while (it.next()) |key| {
1075 const module = key.module;
1076 const compile = key.compile.?;
10771071
1072 while (dep_it.next()) |dep| {
1078 // While walking transitive dependencies, if a given link object is1073 // While walking transitive dependencies, if a given link object is
1079 // already included in a library, it should not redundantly be1074 // already included in a library, it should not redundantly be
1080 // placed on the linker line of the dependee.1075 // placed on the linker line of the dependee.
1081 const my_responsibility = compile == self;1076 const my_responsibility = dep.compile.? == compile;
1082 const already_linked = !my_responsibility and compile.isDynamicLibrary();1077 const already_linked = !my_responsibility and dep.compile.?.isDynamicLibrary();
10831078
1084 // Inherit dependencies on darwin frameworks.1079 // Inherit dependencies on darwin frameworks.
1085 if (!already_linked) {1080 if (!already_linked) {
1086 for (module.frameworks.keys(), module.frameworks.values()) |name, info| {1081 for (dep.module.frameworks.keys(), dep.module.frameworks.values()) |name, info| {
1087 try frameworks.put(arena, name, info);1082 try frameworks.put(arena, name, info);
1088 }1083 }
1089 }1084 }
10901085
1091 // Inherit dependencies on system libraries and static libraries.1086 // Inherit dependencies on system libraries and static libraries.
1092 for (module.link_objects.items) |link_object| {1087 for (dep.module.link_objects.items) |link_object| {
1093 switch (link_object) {1088 switch (link_object) {
1094 .static_path => |static_path| {1089 .static_path => |static_path| {
1095 if (my_responsibility) {1090 if (my_responsibility) {
1096 try zig_args.append(static_path.getPath2(module.owner, step));1091 try zig_args.append(static_path.getPath2(dep.module.owner, step));
1097 total_linker_objects += 1;1092 total_linker_objects += 1;
1098 }1093 }
1099 },1094 },
...@@ -1111,7 +1106,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1111,7 +1106,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
11111106
1112 if ((system_lib.search_strategy != prev_search_strategy or1107 if ((system_lib.search_strategy != prev_search_strategy or
1113 system_lib.preferred_link_mode != prev_preferred_link_mode) and1108 system_lib.preferred_link_mode != prev_preferred_link_mode) and
1114 self.linkage != .static)1109 compile.linkage != .static)
1115 {1110 {
1116 switch (system_lib.search_strategy) {1111 switch (system_lib.search_strategy) {
1117 .no_fallback => switch (system_lib.preferred_link_mode) {1112 .no_fallback => switch (system_lib.preferred_link_mode) {
...@@ -1139,7 +1134,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1139,7 +1134,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1139 switch (system_lib.use_pkg_config) {1134 switch (system_lib.use_pkg_config) {
1140 .no => try zig_args.append(b.fmt("{s}{s}", .{ prefix, system_lib.name })),1135 .no => try zig_args.append(b.fmt("{s}{s}", .{ prefix, system_lib.name })),
1141 .yes, .force => {1136 .yes, .force => {
1142 if (self.runPkgConfig(system_lib.name)) |result| {1137 if (compile.runPkgConfig(system_lib.name)) |result| {
1143 try zig_args.appendSlice(result.cflags);1138 try zig_args.appendSlice(result.cflags);
1144 try zig_args.appendSlice(result.libs);1139 try zig_args.appendSlice(result.libs);
1145 try seen_system_libs.put(arena, system_lib.name, result.cflags);1140 try seen_system_libs.put(arena, system_lib.name, result.cflags);
...@@ -1174,9 +1169,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1174,9 +1169,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1174 .exe => return step.fail("cannot link with an executable build artifact", .{}),1169 .exe => return step.fail("cannot link with an executable build artifact", .{}),
1175 .@"test" => return step.fail("cannot link with a test", .{}),1170 .@"test" => return step.fail("cannot link with a test", .{}),
1176 .obj => {1171 .obj => {
1177 const included_in_lib_or_obj = !my_responsibility and (compile.kind == .lib or compile.kind == .obj);1172 const included_in_lib_or_obj = !my_responsibility and
1173 (dep.compile.?.kind == .lib or dep.compile.?.kind == .obj);
1178 if (!already_linked and !included_in_lib_or_obj) {1174 if (!already_linked and !included_in_lib_or_obj) {
1179 try zig_args.append(other.getEmittedBin().getPath(b));1175 try zig_args.append(other.getEmittedBin().getPath2(b, step));
1180 total_linker_objects += 1;1176 total_linker_objects += 1;
1181 }1177 }
1182 },1178 },
...@@ -1184,7 +1180,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1184,7 +1180,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1184 const other_produces_implib = other.producesImplib();1180 const other_produces_implib = other.producesImplib();
1185 const other_is_static = other_produces_implib or other.isStaticLibrary();1181 const other_is_static = other_produces_implib or other.isStaticLibrary();
11861182
1187 if (self.isStaticLibrary() and other_is_static) {1183 if (compile.isStaticLibrary() and other_is_static) {
1188 // Avoid putting a static library inside a static library.1184 // Avoid putting a static library inside a static library.
1189 break :l;1185 break :l;
1190 }1186 }
...@@ -1193,15 +1189,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1193,15 +1189,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1193 // For everything else, we directly link1189 // For everything else, we directly link
1194 // against the library file.1190 // against the library file.
1195 const full_path_lib = if (other_produces_implib)1191 const full_path_lib = if (other_produces_implib)
1196 other.getGeneratedFilePath("generated_implib", &self.step)1192 other.getGeneratedFilePath("generated_implib", &compile.step)
1197 else1193 else
1198 other.getGeneratedFilePath("generated_bin", &self.step);1194 other.getGeneratedFilePath("generated_bin", &compile.step);
11991195
1200 try zig_args.append(full_path_lib);1196 try zig_args.append(full_path_lib);
1201 total_linker_objects += 1;1197 total_linker_objects += 1;
12021198
1203 if (other.linkage == .dynamic and1199 if (other.linkage == .dynamic and
1204 self.rootModuleTarget().os.tag != .windows)1200 compile.rootModuleTarget().os.tag != .windows)
1205 {1201 {
1206 if (fs.path.dirname(full_path_lib)) |dirname| {1202 if (fs.path.dirname(full_path_lib)) |dirname| {
1207 try zig_args.append("-rpath");1203 try zig_args.append("-rpath");
...@@ -1219,7 +1215,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1219,7 +1215,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1219 try zig_args.append("--");1215 try zig_args.append("--");
1220 prev_has_cflags = false;1216 prev_has_cflags = false;
1221 }1217 }
1222 try zig_args.append(asm_file.getPath2(module.owner, step));1218 try zig_args.append(asm_file.getPath2(dep.module.owner, step));
1223 total_linker_objects += 1;1219 total_linker_objects += 1;
1224 },1220 },
12251221
...@@ -1240,7 +1236,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1240,7 +1236,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1240 try zig_args.append("--");1236 try zig_args.append("--");
1241 prev_has_cflags = true;1237 prev_has_cflags = true;
1242 }1238 }
1243 try zig_args.append(c_source_file.file.getPath2(module.owner, step));1239 try zig_args.append(c_source_file.file.getPath2(dep.module.owner, step));
1244 total_linker_objects += 1;1240 total_linker_objects += 1;
1245 },1241 },
12461242
...@@ -1262,7 +1258,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1262,7 +1258,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1262 prev_has_cflags = true;1258 prev_has_cflags = true;
1263 }1259 }
12641260
1265 const root_path = c_source_files.root.getPath2(module.owner, step);1261 const root_path = c_source_files.root.getPath2(dep.module.owner, step);
1266 for (c_source_files.files) |file| {1262 for (c_source_files.files) |file| {
1267 try zig_args.append(b.pathJoin(&.{ root_path, file }));1263 try zig_args.append(b.pathJoin(&.{ root_path, file }));
1268 }1264 }
...@@ -1286,12 +1282,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1286,12 +1282,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1286 }1282 }
1287 for (rc_source_file.include_paths) |include_path| {1283 for (rc_source_file.include_paths) |include_path| {
1288 try zig_args.append("/I");1284 try zig_args.append("/I");
1289 try zig_args.append(include_path.getPath2(module.owner, step));1285 try zig_args.append(include_path.getPath2(dep.module.owner, step));
1290 }1286 }
1291 try zig_args.append("--");1287 try zig_args.append("--");
1292 prev_has_rcflags = true;1288 prev_has_rcflags = true;
1293 }1289 }
1294 try zig_args.append(rc_source_file.file.getPath2(module.owner, step));1290 try zig_args.append(rc_source_file.file.getPath2(dep.module.owner, step));
1295 total_linker_objects += 1;1291 total_linker_objects += 1;
1296 },1292 },
1297 }1293 }
...@@ -1300,20 +1296,20 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1300,20 +1296,20 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1300 // We need to emit the --mod argument here so that the above link objects1296 // We need to emit the --mod argument here so that the above link objects
1301 // have the correct parent module, but only if the module is part of1297 // have the correct parent module, but only if the module is part of
1302 // this compilation.1298 // this compilation.
1303 if (cli_named_modules.modules.getIndex(module)) |module_cli_index| {1299 if (cli_named_modules.modules.getIndex(dep.module)) |module_cli_index| {
1304 const module_cli_name = cli_named_modules.names.keys()[module_cli_index];1300 const module_cli_name = cli_named_modules.names.keys()[module_cli_index];
1305 try module.appendZigProcessFlags(&zig_args, step);1301 try dep.module.appendZigProcessFlags(&zig_args, step);
13061302
1307 // --dep arguments1303 // --dep arguments
1308 try zig_args.ensureUnusedCapacity(module.import_table.count() * 2);1304 try zig_args.ensureUnusedCapacity(dep.module.import_table.count() * 2);
1309 for (module.import_table.keys(), module.import_table.values()) |name, dep| {1305 for (dep.module.import_table.keys(), dep.module.import_table.values()) |name, import| {
1310 const dep_index = cli_named_modules.modules.getIndex(dep).?;1306 const import_index = cli_named_modules.modules.getIndex(import).?;
1311 const dep_cli_name = cli_named_modules.names.keys()[dep_index];1307 const import_cli_name = cli_named_modules.names.keys()[import_index];
1312 zig_args.appendAssumeCapacity("--dep");1308 zig_args.appendAssumeCapacity("--dep");
1313 if (std.mem.eql(u8, dep_cli_name, name)) {1309 if (std.mem.eql(u8, import_cli_name, name)) {
1314 zig_args.appendAssumeCapacity(dep_cli_name);1310 zig_args.appendAssumeCapacity(import_cli_name);
1315 } else {1311 } else {
1316 zig_args.appendAssumeCapacity(b.fmt("{s}={s}", .{ name, dep_cli_name }));1312 zig_args.appendAssumeCapacity(b.fmt("{s}={s}", .{ name, import_cli_name }));
1317 }1313 }
1318 }1314 }
13191315
...@@ -1324,10 +1320,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1324,10 +1320,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1324 // perhaps a set of linker objects, or C source files instead.1320 // perhaps a set of linker objects, or C source files instead.
1325 // Linker objects are added to the CLI globally, while C source1321 // Linker objects are added to the CLI globally, while C source
1326 // files must have a module parent.1322 // files must have a module parent.
1327 if (module.root_source_file) |lp| {1323 if (dep.module.root_source_file) |lp| {
1328 const src = lp.getPath2(module.owner, step);1324 const src = lp.getPath2(dep.module.owner, step);
1329 try zig_args.append(b.fmt("-M{s}={s}", .{ module_cli_name, src }));1325 try zig_args.append(b.fmt("-M{s}={s}", .{ module_cli_name, src }));
1330 } else if (moduleNeedsCliArg(module)) {1326 } else if (moduleNeedsCliArg(dep.module)) {
1331 try zig_args.append(b.fmt("-M{s}", .{module_cli_name}));1327 try zig_args.append(b.fmt("-M{s}", .{module_cli_name}));
1332 }1328 }
1333 }1329 }
...@@ -1348,32 +1344,32 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1348,32 +1344,32 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1348 try zig_args.append(name);1344 try zig_args.append(name);
1349 }1345 }
13501346
1351 if (self.is_linking_libcpp) {1347 if (compile.is_linking_libcpp) {
1352 try zig_args.append("-lc++");1348 try zig_args.append("-lc++");
1353 }1349 }
13541350
1355 if (self.is_linking_libc) {1351 if (compile.is_linking_libc) {
1356 try zig_args.append("-lc");1352 try zig_args.append("-lc");
1357 }1353 }
1358 }1354 }
13591355
1360 if (self.win32_manifest) |manifest_file| {1356 if (compile.win32_manifest) |manifest_file| {
1361 try zig_args.append(manifest_file.getPath(b));1357 try zig_args.append(manifest_file.getPath2(b, step));
1362 }1358 }
13631359
1364 if (self.image_base) |image_base| {1360 if (compile.image_base) |image_base| {
1365 try zig_args.append("--image-base");1361 try zig_args.append("--image-base");
1366 try zig_args.append(b.fmt("0x{x}", .{image_base}));1362 try zig_args.append(b.fmt("0x{x}", .{image_base}));
1367 }1363 }
13681364
1369 for (self.filters) |filter| {1365 for (compile.filters) |filter| {
1370 try zig_args.append("--test-filter");1366 try zig_args.append("--test-filter");
1371 try zig_args.append(filter);1367 try zig_args.append(filter);
1372 }1368 }
13731369
1374 if (self.test_runner) |test_runner| {1370 if (compile.test_runner) |test_runner| {
1375 try zig_args.append("--test-runner");1371 try zig_args.append("--test-runner");
1376 try zig_args.append(test_runner.getPath(b));1372 try zig_args.append(test_runner.getPath2(b, step));
1377 }1373 }
13781374
1379 for (b.debug_log_scopes) |log_scope| {1375 for (b.debug_log_scopes) |log_scope| {
...@@ -1389,71 +1385,71 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1389,71 +1385,71 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1389 if (b.verbose_air) try zig_args.append("--verbose-air");1385 if (b.verbose_air) try zig_args.append("--verbose-air");
1390 if (b.verbose_llvm_ir) |path| try zig_args.append(b.fmt("--verbose-llvm-ir={s}", .{path}));1386 if (b.verbose_llvm_ir) |path| try zig_args.append(b.fmt("--verbose-llvm-ir={s}", .{path}));
1391 if (b.verbose_llvm_bc) |path| try zig_args.append(b.fmt("--verbose-llvm-bc={s}", .{path}));1387 if (b.verbose_llvm_bc) |path| try zig_args.append(b.fmt("--verbose-llvm-bc={s}", .{path}));
1392 if (b.verbose_link or self.verbose_link) try zig_args.append("--verbose-link");1388 if (b.verbose_link or compile.verbose_link) try zig_args.append("--verbose-link");
1393 if (b.verbose_cc or self.verbose_cc) try zig_args.append("--verbose-cc");1389 if (b.verbose_cc or compile.verbose_cc) try zig_args.append("--verbose-cc");
1394 if (b.verbose_llvm_cpu_features) try zig_args.append("--verbose-llvm-cpu-features");1390 if (b.verbose_llvm_cpu_features) try zig_args.append("--verbose-llvm-cpu-features");
13951391
1396 if (self.generated_asm != null) try zig_args.append("-femit-asm");1392 if (compile.generated_asm != null) try zig_args.append("-femit-asm");
1397 if (self.generated_bin == null) try zig_args.append("-fno-emit-bin");1393 if (compile.generated_bin == null) try zig_args.append("-fno-emit-bin");
1398 if (self.generated_docs != null) try zig_args.append("-femit-docs");1394 if (compile.generated_docs != null) try zig_args.append("-femit-docs");
1399 if (self.generated_implib != null) try zig_args.append("-femit-implib");1395 if (compile.generated_implib != null) try zig_args.append("-femit-implib");
1400 if (self.generated_llvm_bc != null) try zig_args.append("-femit-llvm-bc");1396 if (compile.generated_llvm_bc != null) try zig_args.append("-femit-llvm-bc");
1401 if (self.generated_llvm_ir != null) try zig_args.append("-femit-llvm-ir");1397 if (compile.generated_llvm_ir != null) try zig_args.append("-femit-llvm-ir");
1402 if (self.generated_h != null) try zig_args.append("-femit-h");1398 if (compile.generated_h != null) try zig_args.append("-femit-h");
14031399
1404 try addFlag(&zig_args, "formatted-panics", self.formatted_panics);1400 try addFlag(&zig_args, "formatted-panics", compile.formatted_panics);
14051401
1406 switch (self.compress_debug_sections) {1402 switch (compile.compress_debug_sections) {
1407 .none => {},1403 .none => {},
1408 .zlib => try zig_args.append("--compress-debug-sections=zlib"),1404 .zlib => try zig_args.append("--compress-debug-sections=zlib"),
1409 .zstd => try zig_args.append("--compress-debug-sections=zstd"),1405 .zstd => try zig_args.append("--compress-debug-sections=zstd"),
1410 }1406 }
14111407
1412 if (self.link_eh_frame_hdr) {1408 if (compile.link_eh_frame_hdr) {
1413 try zig_args.append("--eh-frame-hdr");1409 try zig_args.append("--eh-frame-hdr");
1414 }1410 }
1415 if (self.link_emit_relocs) {1411 if (compile.link_emit_relocs) {
1416 try zig_args.append("--emit-relocs");1412 try zig_args.append("--emit-relocs");
1417 }1413 }
1418 if (self.link_function_sections) {1414 if (compile.link_function_sections) {
1419 try zig_args.append("-ffunction-sections");1415 try zig_args.append("-ffunction-sections");
1420 }1416 }
1421 if (self.link_data_sections) {1417 if (compile.link_data_sections) {
1422 try zig_args.append("-fdata-sections");1418 try zig_args.append("-fdata-sections");
1423 }1419 }
1424 if (self.link_gc_sections) |x| {1420 if (compile.link_gc_sections) |x| {
1425 try zig_args.append(if (x) "--gc-sections" else "--no-gc-sections");1421 try zig_args.append(if (x) "--gc-sections" else "--no-gc-sections");
1426 }1422 }
1427 if (!self.linker_dynamicbase) {1423 if (!compile.linker_dynamicbase) {
1428 try zig_args.append("--no-dynamicbase");1424 try zig_args.append("--no-dynamicbase");
1429 }1425 }
1430 if (self.linker_allow_shlib_undefined) |x| {1426 if (compile.linker_allow_shlib_undefined) |x| {
1431 try zig_args.append(if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined");1427 try zig_args.append(if (x) "-fallow-shlib-undefined" else "-fno-allow-shlib-undefined");
1432 }1428 }
1433 if (self.link_z_notext) {1429 if (compile.link_z_notext) {
1434 try zig_args.append("-z");1430 try zig_args.append("-z");
1435 try zig_args.append("notext");1431 try zig_args.append("notext");
1436 }1432 }
1437 if (!self.link_z_relro) {1433 if (!compile.link_z_relro) {
1438 try zig_args.append("-z");1434 try zig_args.append("-z");
1439 try zig_args.append("norelro");1435 try zig_args.append("norelro");
1440 }1436 }
1441 if (self.link_z_lazy) {1437 if (compile.link_z_lazy) {
1442 try zig_args.append("-z");1438 try zig_args.append("-z");
1443 try zig_args.append("lazy");1439 try zig_args.append("lazy");
1444 }1440 }
1445 if (self.link_z_common_page_size) |size| {1441 if (compile.link_z_common_page_size) |size| {
1446 try zig_args.append("-z");1442 try zig_args.append("-z");
1447 try zig_args.append(b.fmt("common-page-size={d}", .{size}));1443 try zig_args.append(b.fmt("common-page-size={d}", .{size}));
1448 }1444 }
1449 if (self.link_z_max_page_size) |size| {1445 if (compile.link_z_max_page_size) |size| {
1450 try zig_args.append("-z");1446 try zig_args.append("-z");
1451 try zig_args.append(b.fmt("max-page-size={d}", .{size}));1447 try zig_args.append(b.fmt("max-page-size={d}", .{size}));
1452 }1448 }
14531449
1454 if (self.libc_file) |libc_file| {1450 if (compile.libc_file) |libc_file| {
1455 try zig_args.append("--libc");1451 try zig_args.append("--libc");
1456 try zig_args.append(libc_file.getPath(b));1452 try zig_args.append(libc_file.getPath2(b, step));
1457 } else if (b.libc_file) |libc_file| {1453 } else if (b.libc_file) |libc_file| {
1458 try zig_args.append("--libc");1454 try zig_args.append("--libc");
1459 try zig_args.append(libc_file);1455 try zig_args.append(libc_file);
...@@ -1466,105 +1462,105 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1466,105 +1462,105 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1466 try zig_args.append(b.graph.global_cache_root.path orelse ".");1462 try zig_args.append(b.graph.global_cache_root.path orelse ".");
14671463
1468 try zig_args.append("--name");1464 try zig_args.append("--name");
1469 try zig_args.append(self.name);1465 try zig_args.append(compile.name);
14701466
1471 if (self.linkage) |some| switch (some) {1467 if (compile.linkage) |some| switch (some) {
1472 .dynamic => try zig_args.append("-dynamic"),1468 .dynamic => try zig_args.append("-dynamic"),
1473 .static => try zig_args.append("-static"),1469 .static => try zig_args.append("-static"),
1474 };1470 };
1475 if (self.kind == .lib and self.linkage != null and self.linkage.? == .dynamic) {1471 if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic) {
1476 if (self.version) |version| {1472 if (compile.version) |version| {
1477 try zig_args.append("--version");1473 try zig_args.append("--version");
1478 try zig_args.append(b.fmt("{}", .{version}));1474 try zig_args.append(b.fmt("{}", .{version}));
1479 }1475 }
14801476
1481 if (self.rootModuleTarget().isDarwin()) {1477 if (compile.rootModuleTarget().isDarwin()) {
1482 const install_name = self.install_name orelse b.fmt("@rpath/{s}{s}{s}", .{1478 const install_name = compile.install_name orelse b.fmt("@rpath/{s}{s}{s}", .{
1483 self.rootModuleTarget().libPrefix(),1479 compile.rootModuleTarget().libPrefix(),
1484 self.name,1480 compile.name,
1485 self.rootModuleTarget().dynamicLibSuffix(),1481 compile.rootModuleTarget().dynamicLibSuffix(),
1486 });1482 });
1487 try zig_args.append("-install_name");1483 try zig_args.append("-install_name");
1488 try zig_args.append(install_name);1484 try zig_args.append(install_name);
1489 }1485 }
1490 }1486 }
14911487
1492 if (self.entitlements) |entitlements| {1488 if (compile.entitlements) |entitlements| {
1493 try zig_args.appendSlice(&[_][]const u8{ "--entitlements", entitlements });1489 try zig_args.appendSlice(&[_][]const u8{ "--entitlements", entitlements });
1494 }1490 }
1495 if (self.pagezero_size) |pagezero_size| {1491 if (compile.pagezero_size) |pagezero_size| {
1496 const size = try std.fmt.allocPrint(arena, "{x}", .{pagezero_size});1492 const size = try std.fmt.allocPrint(arena, "{x}", .{pagezero_size});
1497 try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size });1493 try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size });
1498 }1494 }
1499 if (self.headerpad_size) |headerpad_size| {1495 if (compile.headerpad_size) |headerpad_size| {
1500 const size = try std.fmt.allocPrint(arena, "{x}", .{headerpad_size});1496 const size = try std.fmt.allocPrint(arena, "{x}", .{headerpad_size});
1501 try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size });1497 try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size });
1502 }1498 }
1503 if (self.headerpad_max_install_names) {1499 if (compile.headerpad_max_install_names) {
1504 try zig_args.append("-headerpad_max_install_names");1500 try zig_args.append("-headerpad_max_install_names");
1505 }1501 }
1506 if (self.dead_strip_dylibs) {1502 if (compile.dead_strip_dylibs) {
1507 try zig_args.append("-dead_strip_dylibs");1503 try zig_args.append("-dead_strip_dylibs");
1508 }1504 }
1509 if (self.force_load_objc) {1505 if (compile.force_load_objc) {
1510 try zig_args.append("-ObjC");1506 try zig_args.append("-ObjC");
1511 }1507 }
15121508
1513 try addFlag(&zig_args, "compiler-rt", self.bundle_compiler_rt);1509 try addFlag(&zig_args, "compiler-rt", compile.bundle_compiler_rt);
1514 try addFlag(&zig_args, "dll-export-fns", self.dll_export_fns);1510 try addFlag(&zig_args, "dll-export-fns", compile.dll_export_fns);
1515 if (self.rdynamic) {1511 if (compile.rdynamic) {
1516 try zig_args.append("-rdynamic");1512 try zig_args.append("-rdynamic");
1517 }1513 }
1518 if (self.import_memory) {1514 if (compile.import_memory) {
1519 try zig_args.append("--import-memory");1515 try zig_args.append("--import-memory");
1520 }1516 }
1521 if (self.export_memory) {1517 if (compile.export_memory) {
1522 try zig_args.append("--export-memory");1518 try zig_args.append("--export-memory");
1523 }1519 }
1524 if (self.import_symbols) {1520 if (compile.import_symbols) {
1525 try zig_args.append("--import-symbols");1521 try zig_args.append("--import-symbols");
1526 }1522 }
1527 if (self.import_table) {1523 if (compile.import_table) {
1528 try zig_args.append("--import-table");1524 try zig_args.append("--import-table");
1529 }1525 }
1530 if (self.export_table) {1526 if (compile.export_table) {
1531 try zig_args.append("--export-table");1527 try zig_args.append("--export-table");
1532 }1528 }
1533 if (self.initial_memory) |initial_memory| {1529 if (compile.initial_memory) |initial_memory| {
1534 try zig_args.append(b.fmt("--initial-memory={d}", .{initial_memory}));1530 try zig_args.append(b.fmt("--initial-memory={d}", .{initial_memory}));
1535 }1531 }
1536 if (self.max_memory) |max_memory| {1532 if (compile.max_memory) |max_memory| {
1537 try zig_args.append(b.fmt("--max-memory={d}", .{max_memory}));1533 try zig_args.append(b.fmt("--max-memory={d}", .{max_memory}));
1538 }1534 }
1539 if (self.shared_memory) {1535 if (compile.shared_memory) {
1540 try zig_args.append("--shared-memory");1536 try zig_args.append("--shared-memory");
1541 }1537 }
1542 if (self.global_base) |global_base| {1538 if (compile.global_base) |global_base| {
1543 try zig_args.append(b.fmt("--global-base={d}", .{global_base}));1539 try zig_args.append(b.fmt("--global-base={d}", .{global_base}));
1544 }1540 }
15451541
1546 if (self.wasi_exec_model) |model| {1542 if (compile.wasi_exec_model) |model| {
1547 try zig_args.append(b.fmt("-mexec-model={s}", .{@tagName(model)}));1543 try zig_args.append(b.fmt("-mexec-model={s}", .{@tagName(model)}));
1548 }1544 }
1549 if (self.linker_script) |linker_script| {1545 if (compile.linker_script) |linker_script| {
1550 try zig_args.append("--script");1546 try zig_args.append("--script");
1551 try zig_args.append(linker_script.getPath(b));1547 try zig_args.append(linker_script.getPath2(b, step));
1552 }1548 }
15531549
1554 if (self.version_script) |version_script| {1550 if (compile.version_script) |version_script| {
1555 try zig_args.append("--version-script");1551 try zig_args.append("--version-script");
1556 try zig_args.append(version_script.getPath(b));1552 try zig_args.append(version_script.getPath2(b, step));
1557 }1553 }
1558 if (self.linker_allow_undefined_version) |x| {1554 if (compile.linker_allow_undefined_version) |x| {
1559 try zig_args.append(if (x) "--undefined-version" else "--no-undefined-version");1555 try zig_args.append(if (x) "--undefined-version" else "--no-undefined-version");
1560 }1556 }
15611557
1562 if (self.linker_enable_new_dtags) |enabled| {1558 if (compile.linker_enable_new_dtags) |enabled| {
1563 try zig_args.append(if (enabled) "--enable-new-dtags" else "--disable-new-dtags");1559 try zig_args.append(if (enabled) "--enable-new-dtags" else "--disable-new-dtags");
1564 }1560 }
15651561
1566 if (self.kind == .@"test") {1562 if (compile.kind == .@"test") {
1567 if (self.exec_cmd_args) |exec_cmd_args| {1563 if (compile.exec_cmd_args) |exec_cmd_args| {
1568 for (exec_cmd_args) |cmd_arg| {1564 for (exec_cmd_args) |cmd_arg| {
1569 if (cmd_arg) |arg| {1565 if (cmd_arg) |arg| {
1570 try zig_args.append("--test-cmd");1566 try zig_args.append("--test-cmd");
...@@ -1595,7 +1591,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1595,7 +1591,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
15951591
1596 if (prefix_dir.accessZ("lib", .{})) |_| {1592 if (prefix_dir.accessZ("lib", .{})) |_| {
1597 try zig_args.appendSlice(&.{1593 try zig_args.appendSlice(&.{
1598 "-L", try fs.path.join(arena, &.{ search_prefix, "lib" }),1594 "-L", b.pathJoin(&.{ search_prefix, "lib" }),
1599 });1595 });
1600 } else |err| switch (err) {1596 } else |err| switch (err) {
1601 error.FileNotFound => {},1597 error.FileNotFound => {},
...@@ -1606,7 +1602,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1606,7 +1602,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
16061602
1607 if (prefix_dir.accessZ("include", .{})) |_| {1603 if (prefix_dir.accessZ("include", .{})) |_| {
1608 try zig_args.appendSlice(&.{1604 try zig_args.appendSlice(&.{
1609 "-I", try fs.path.join(arena, &.{ search_prefix, "include" }),1605 "-I", b.pathJoin(&.{ search_prefix, "include" }),
1610 });1606 });
1611 } else |err| switch (err) {1607 } else |err| switch (err) {
1612 error.FileNotFound => {},1608 error.FileNotFound => {},
...@@ -1616,14 +1612,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1616,14 +1612,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1616 }1612 }
1617 }1613 }
16181614
1619 if (self.rc_includes != .any) {1615 if (compile.rc_includes != .any) {
1620 try zig_args.append("-rcincludes");1616 try zig_args.append("-rcincludes");
1621 try zig_args.append(@tagName(self.rc_includes));1617 try zig_args.append(@tagName(compile.rc_includes));
1622 }1618 }
16231619
1624 try addFlag(&zig_args, "each-lib-rpath", self.each_lib_rpath);1620 try addFlag(&zig_args, "each-lib-rpath", compile.each_lib_rpath);
16251621
1626 if (self.build_id) |build_id| {1622 if (compile.build_id) |build_id| {
1627 try zig_args.append(switch (build_id) {1623 try zig_args.append(switch (build_id) {
1628 .hexstring => |hs| b.fmt("--build-id=0x{s}", .{1624 .hexstring => |hs| b.fmt("--build-id=0x{s}", .{
1629 std.fmt.fmtSliceHexLower(hs.toSlice()),1625 std.fmt.fmtSliceHexLower(hs.toSlice()),
...@@ -1632,15 +1628,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1632,15 +1628,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1632 });1628 });
1633 }1629 }
16341630
1635 if (self.zig_lib_dir) |dir| {1631 if (compile.zig_lib_dir) |dir| {
1636 try zig_args.append("--zig-lib-dir");1632 try zig_args.append("--zig-lib-dir");
1637 try zig_args.append(dir.getPath(b));1633 try zig_args.append(dir.getPath2(b, step));
1638 }1634 }
16391635
1640 try addFlag(&zig_args, "PIE", self.pie);1636 try addFlag(&zig_args, "PIE", compile.pie);
1641 try addFlag(&zig_args, "lto", self.want_lto);1637 try addFlag(&zig_args, "lto", compile.want_lto);
16421638
1643 if (self.subsystem) |subsystem| {1639 if (compile.subsystem) |subsystem| {
1644 try zig_args.append("--subsystem");1640 try zig_args.append("--subsystem");
1645 try zig_args.append(switch (subsystem) {1641 try zig_args.append(switch (subsystem) {
1646 .Console => "console",1642 .Console => "console",
...@@ -1654,11 +1650,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1654,11 +1650,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1654 });1650 });
1655 }1651 }
16561652
1657 if (self.mingw_unicode_entry_point) {1653 if (compile.mingw_unicode_entry_point) {
1658 try zig_args.append("-municode");1654 try zig_args.append("-municode");
1659 }1655 }
16601656
1661 if (self.error_limit) |err_limit| try zig_args.appendSlice(&.{1657 if (compile.error_limit) |err_limit| try zig_args.appendSlice(&.{
1662 "--error-limit",1658 "--error-limit",
1663 b.fmt("{}", .{err_limit}),1659 b.fmt("{}", .{err_limit}),
1664 });1660 });
...@@ -1724,8 +1720,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1724,8 +1720,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
17241720
1725 const maybe_output_bin_path = step.evalZigProcess(zig_args.items, prog_node) catch |err| switch (err) {1721 const maybe_output_bin_path = step.evalZigProcess(zig_args.items, prog_node) catch |err| switch (err) {
1726 error.NeedCompileErrorCheck => {1722 error.NeedCompileErrorCheck => {
1727 assert(self.expect_errors != null);1723 assert(compile.expect_errors != null);
1728 try checkCompileErrors(self);1724 try checkCompileErrors(compile);
1729 return;1725 return;
1730 },1726 },
1731 else => |e| return e,1727 else => |e| return e,
...@@ -1735,61 +1731,61 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1735,61 +1731,61 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1735 if (maybe_output_bin_path) |output_bin_path| {1731 if (maybe_output_bin_path) |output_bin_path| {
1736 const output_dir = fs.path.dirname(output_bin_path).?;1732 const output_dir = fs.path.dirname(output_bin_path).?;
17371733
1738 if (self.emit_directory) |lp| {1734 if (compile.emit_directory) |lp| {
1739 lp.path = output_dir;1735 lp.path = output_dir;
1740 }1736 }
17411737
1742 // -femit-bin[=path] (default) Output machine code1738 // -femit-bin[=path] (default) Output machine code
1743 if (self.generated_bin) |bin| {1739 if (compile.generated_bin) |bin| {
1744 bin.path = b.pathJoin(&.{ output_dir, self.out_filename });1740 bin.path = b.pathJoin(&.{ output_dir, compile.out_filename });
1745 }1741 }
17461742
1747 const sep = std.fs.path.sep;1743 const sep = std.fs.path.sep;
17481744
1749 // output PDB if someone requested it1745 // output PDB if someone requested it
1750 if (self.generated_pdb) |pdb| {1746 if (compile.generated_pdb) |pdb| {
1751 pdb.path = b.fmt("{s}{c}{s}.pdb", .{ output_dir, sep, self.name });1747 pdb.path = b.fmt("{s}{c}{s}.pdb", .{ output_dir, sep, compile.name });
1752 }1748 }
17531749
1754 // -femit-implib[=path] (default) Produce an import .lib when building a Windows DLL1750 // -femit-implib[=path] (default) Produce an import .lib when building a Windows DLL
1755 if (self.generated_implib) |implib| {1751 if (compile.generated_implib) |implib| {
1756 implib.path = b.fmt("{s}{c}{s}.lib", .{ output_dir, sep, self.name });1752 implib.path = b.fmt("{s}{c}{s}.lib", .{ output_dir, sep, compile.name });
1757 }1753 }
17581754
1759 // -femit-h[=path] Generate a C header file (.h)1755 // -femit-h[=path] Generate a C header file (.h)
1760 if (self.generated_h) |lp| {1756 if (compile.generated_h) |lp| {
1761 lp.path = b.fmt("{s}{c}{s}.h", .{ output_dir, sep, self.name });1757 lp.path = b.fmt("{s}{c}{s}.h", .{ output_dir, sep, compile.name });
1762 }1758 }
17631759
1764 // -femit-docs[=path] Create a docs/ dir with html documentation1760 // -femit-docs[=path] Create a docs/ dir with html documentation
1765 if (self.generated_docs) |generated_docs| {1761 if (compile.generated_docs) |generated_docs| {
1766 generated_docs.path = b.pathJoin(&.{ output_dir, "docs" });1762 generated_docs.path = b.pathJoin(&.{ output_dir, "docs" });
1767 }1763 }
17681764
1769 // -femit-asm[=path] Output .s (assembly code)1765 // -femit-asm[=path] Output .s (assembly code)
1770 if (self.generated_asm) |lp| {1766 if (compile.generated_asm) |lp| {
1771 lp.path = b.fmt("{s}{c}{s}.s", .{ output_dir, sep, self.name });1767 lp.path = b.fmt("{s}{c}{s}.s", .{ output_dir, sep, compile.name });
1772 }1768 }
17731769
1774 // -femit-llvm-ir[=path] Produce a .ll file with optimized LLVM IR (requires LLVM extensions)1770 // -femit-llvm-ir[=path] Produce a .ll file with optimized LLVM IR (requires LLVM extensions)
1775 if (self.generated_llvm_ir) |lp| {1771 if (compile.generated_llvm_ir) |lp| {
1776 lp.path = b.fmt("{s}{c}{s}.ll", .{ output_dir, sep, self.name });1772 lp.path = b.fmt("{s}{c}{s}.ll", .{ output_dir, sep, compile.name });
1777 }1773 }
17781774
1779 // -femit-llvm-bc[=path] Produce an optimized LLVM module as a .bc file (requires LLVM extensions)1775 // -femit-llvm-bc[=path] Produce an optimized LLVM module as a .bc file (requires LLVM extensions)
1780 if (self.generated_llvm_bc) |lp| {1776 if (compile.generated_llvm_bc) |lp| {
1781 lp.path = b.fmt("{s}{c}{s}.bc", .{ output_dir, sep, self.name });1777 lp.path = b.fmt("{s}{c}{s}.bc", .{ output_dir, sep, compile.name });
1782 }1778 }
1783 }1779 }
17841780
1785 if (self.kind == .lib and self.linkage != null and self.linkage.? == .dynamic and1781 if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic and
1786 self.version != null and std.Build.wantSharedLibSymLinks(self.rootModuleTarget()))1782 compile.version != null and std.Build.wantSharedLibSymLinks(compile.rootModuleTarget()))
1787 {1783 {
1788 try doAtomicSymLinks(1784 try doAtomicSymLinks(
1789 step,1785 step,
1790 self.getEmittedBin().getPath(b),1786 compile.getEmittedBin().getPath2(b, step),
1791 self.major_only_filename.?,1787 compile.major_only_filename.?,
1792 self.name_only_filename.?,1788 compile.name_only_filename.?,
1793 );1789 );
1794 }1790 }
1795}1791}
...@@ -1800,18 +1796,19 @@ pub fn doAtomicSymLinks(...@@ -1800,18 +1796,19 @@ pub fn doAtomicSymLinks(
1800 filename_major_only: []const u8,1796 filename_major_only: []const u8,
1801 filename_name_only: []const u8,1797 filename_name_only: []const u8,
1802) !void {1798) !void {
1803 const arena = step.owner.allocator;1799 const b = step.owner;
1800 const arena = b.allocator;
1804 const out_dir = fs.path.dirname(output_path) orelse ".";1801 const out_dir = fs.path.dirname(output_path) orelse ".";
1805 const out_basename = fs.path.basename(output_path);1802 const out_basename = fs.path.basename(output_path);
1806 // sym link for libfoo.so.1 to libfoo.so.1.2.31803 // sym link for libfoo.so.1 to libfoo.so.1.2.3
1807 const major_only_path = try fs.path.join(arena, &.{ out_dir, filename_major_only });1804 const major_only_path = b.pathJoin(&.{ out_dir, filename_major_only });
1808 fs.atomicSymLink(arena, out_basename, major_only_path) catch |err| {1805 fs.atomicSymLink(arena, out_basename, major_only_path) catch |err| {
1809 return step.fail("unable to symlink {s} -> {s}: {s}", .{1806 return step.fail("unable to symlink {s} -> {s}: {s}", .{
1810 major_only_path, out_basename, @errorName(err),1807 major_only_path, out_basename, @errorName(err),
1811 });1808 });
1812 };1809 };
1813 // sym link for libfoo.so to libfoo.so.11810 // sym link for libfoo.so to libfoo.so.1
1814 const name_only_path = try fs.path.join(arena, &.{ out_dir, filename_name_only });1811 const name_only_path = b.pathJoin(&.{ out_dir, filename_name_only });
1815 fs.atomicSymLink(arena, filename_major_only, name_only_path) catch |err| {1812 fs.atomicSymLink(arena, filename_major_only, name_only_path) catch |err| {
1816 return step.fail("Unable to symlink {s} -> {s}: {s}", .{1813 return step.fail("Unable to symlink {s} -> {s}: {s}", .{
1817 name_only_path, filename_major_only, @errorName(err),1814 name_only_path, filename_major_only, @errorName(err),
...@@ -1819,9 +1816,9 @@ pub fn doAtomicSymLinks(...@@ -1819,9 +1816,9 @@ pub fn doAtomicSymLinks(
1819 };1816 };
1820}1817}
18211818
1822fn execPkgConfigList(self: *std.Build, out_code: *u8) (PkgConfigError || RunError)![]const PkgConfigPkg {1819fn execPkgConfigList(compile: *std.Build, out_code: *u8) (PkgConfigError || RunError)![]const PkgConfigPkg {
1823 const stdout = try self.runAllowFail(&[_][]const u8{ "pkg-config", "--list-all" }, out_code, .Ignore);1820 const stdout = try compile.runAllowFail(&[_][]const u8{ "pkg-config", "--list-all" }, out_code, .Ignore);
1824 var list = ArrayList(PkgConfigPkg).init(self.allocator);1821 var list = ArrayList(PkgConfigPkg).init(compile.allocator);
1825 errdefer list.deinit();1822 errdefer list.deinit();
1826 var line_it = mem.tokenizeAny(u8, stdout, "\r\n");1823 var line_it = mem.tokenizeAny(u8, stdout, "\r\n");
1827 while (line_it.next()) |line| {1824 while (line_it.next()) |line| {
...@@ -1835,13 +1832,13 @@ fn execPkgConfigList(self: *std.Build, out_code: *u8) (PkgConfigError || RunErro...@@ -1835,13 +1832,13 @@ fn execPkgConfigList(self: *std.Build, out_code: *u8) (PkgConfigError || RunErro
1835 return list.toOwnedSlice();1832 return list.toOwnedSlice();
1836}1833}
18371834
1838fn getPkgConfigList(self: *std.Build) ![]const PkgConfigPkg {1835fn getPkgConfigList(compile: *std.Build) ![]const PkgConfigPkg {
1839 if (self.pkg_config_pkg_list) |res| {1836 if (compile.pkg_config_pkg_list) |res| {
1840 return res;1837 return res;
1841 }1838 }
1842 var code: u8 = undefined;1839 var code: u8 = undefined;
1843 if (execPkgConfigList(self, &code)) |list| {1840 if (execPkgConfigList(compile, &code)) |list| {
1844 self.pkg_config_pkg_list = list;1841 compile.pkg_config_pkg_list = list;
1845 return list;1842 return list;
1846 } else |err| {1843 } else |err| {
1847 const result = switch (err) {1844 const result = switch (err) {
...@@ -1853,7 +1850,7 @@ fn getPkgConfigList(self: *std.Build) ![]const PkgConfigPkg {...@@ -1853,7 +1850,7 @@ fn getPkgConfigList(self: *std.Build) ![]const PkgConfigPkg {
1853 error.PkgConfigInvalidOutput => error.PkgConfigInvalidOutput,1850 error.PkgConfigInvalidOutput => error.PkgConfigInvalidOutput,
1854 else => return err,1851 else => return err,
1855 };1852 };
1856 self.pkg_config_pkg_list = result;1853 compile.pkg_config_pkg_list = result;
1857 return result;1854 return result;
1858 }1855 }
1859}1856}
...@@ -1868,12 +1865,12 @@ fn addFlag(args: *ArrayList([]const u8), comptime name: []const u8, opt: ?bool)...@@ -1868,12 +1865,12 @@ fn addFlag(args: *ArrayList([]const u8), comptime name: []const u8, opt: ?bool)
1868 }1865 }
1869}1866}
18701867
1871fn checkCompileErrors(self: *Compile) !void {1868fn checkCompileErrors(compile: *Compile) !void {
1872 // Clear this field so that it does not get printed by the build runner.1869 // Clear this field so that it does not get printed by the build runner.
1873 const actual_eb = self.step.result_error_bundle;1870 const actual_eb = compile.step.result_error_bundle;
1874 self.step.result_error_bundle = std.zig.ErrorBundle.empty;1871 compile.step.result_error_bundle = std.zig.ErrorBundle.empty;
18751872
1876 const arena = self.step.owner.allocator;1873 const arena = compile.step.owner.allocator;
18771874
1878 var actual_stderr_list = std.ArrayList(u8).init(arena);1875 var actual_stderr_list = std.ArrayList(u8).init(arena);
1879 try actual_eb.renderToWriter(.{1876 try actual_eb.renderToWriter(.{
...@@ -1885,7 +1882,7 @@ fn checkCompileErrors(self: *Compile) !void {...@@ -1885,7 +1882,7 @@ fn checkCompileErrors(self: *Compile) !void {
18851882
1886 // Render the expected lines into a string that we can compare verbatim.1883 // Render the expected lines into a string that we can compare verbatim.
1887 var expected_generated = std.ArrayList(u8).init(arena);1884 var expected_generated = std.ArrayList(u8).init(arena);
1888 const expect_errors = self.expect_errors.?;1885 const expect_errors = compile.expect_errors.?;
18891886
1890 var actual_line_it = mem.splitScalar(u8, actual_stderr, '\n');1887 var actual_line_it = mem.splitScalar(u8, actual_stderr, '\n');
18911888
...@@ -1897,7 +1894,7 @@ fn checkCompileErrors(self: *Compile) !void {...@@ -1897,7 +1894,7 @@ fn checkCompileErrors(self: *Compile) !void {
1897 return;1894 return;
1898 }1895 }
18991896
1900 return self.step.fail(1897 return compile.step.fail(
1901 \\1898 \\
1902 \\========= should contain: ===============1899 \\========= should contain: ===============
1903 \\{s}1900 \\{s}
...@@ -1924,7 +1921,7 @@ fn checkCompileErrors(self: *Compile) !void {...@@ -1924,7 +1921,7 @@ fn checkCompileErrors(self: *Compile) !void {
19241921
1925 if (mem.eql(u8, expected_generated.items, actual_stderr)) return;1922 if (mem.eql(u8, expected_generated.items, actual_stderr)) return;
19261923
1927 return self.step.fail(1924 return compile.step.fail(
1928 \\1925 \\
1929 \\========= expected: =====================1926 \\========= expected: =====================
1930 \\{s}1927 \\{s}
lib/std/Build/Step/ConfigHeader.zig+38-39
...@@ -52,15 +52,14 @@ pub const Options = struct {...@@ -52,15 +52,14 @@ pub const Options = struct {
52};52};
5353
54pub fn create(owner: *std.Build, options: Options) *ConfigHeader {54pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
55 const self = owner.allocator.create(ConfigHeader) catch @panic("OOM");55 const config_header = owner.allocator.create(ConfigHeader) catch @panic("OOM");
5656
57 var include_path: []const u8 = "config.h";57 var include_path: []const u8 = "config.h";
5858
59 if (options.style.getPath()) |s| default_include_path: {59 if (options.style.getPath()) |s| default_include_path: {
60 const sub_path = switch (s) {60 const sub_path = switch (s) {
61 .src_path => |sp| sp.sub_path,61 .src_path => |sp| sp.sub_path,
62 .path => |path| path,62 .generated => break :default_include_path,
63 .generated, .generated_dirname => break :default_include_path,
64 .cwd_relative => |sub_path| sub_path,63 .cwd_relative => |sub_path| sub_path,
65 .dependency => |dependency| dependency.sub_path,64 .dependency => |dependency| dependency.sub_path,
66 };65 };
...@@ -81,7 +80,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {...@@ -81,7 +80,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
81 else80 else
82 owner.fmt("configure {s} header to {s}", .{ @tagName(options.style), include_path });81 owner.fmt("configure {s} header to {s}", .{ @tagName(options.style), include_path });
8382
84 self.* = .{83 config_header.* = .{
85 .step = Step.init(.{84 .step = Step.init(.{
86 .id = base_id,85 .id = base_id,
87 .name = name,86 .name = name,
...@@ -95,64 +94,64 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {...@@ -95,64 +94,64 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
95 .max_bytes = options.max_bytes,94 .max_bytes = options.max_bytes,
96 .include_path = include_path,95 .include_path = include_path,
97 .include_guard_override = options.include_guard_override,96 .include_guard_override = options.include_guard_override,
98 .output_file = .{ .step = &self.step },97 .output_file = .{ .step = &config_header.step },
99 };98 };
10099
101 return self;100 return config_header;
102}101}
103102
104pub fn addValues(self: *ConfigHeader, values: anytype) void {103pub fn addValues(config_header: *ConfigHeader, values: anytype) void {
105 return addValuesInner(self, values) catch @panic("OOM");104 return addValuesInner(config_header, values) catch @panic("OOM");
106}105}
107106
108pub fn getOutput(self: *ConfigHeader) std.Build.LazyPath {107pub fn getOutput(config_header: *ConfigHeader) std.Build.LazyPath {
109 return .{ .generated = &self.output_file };108 return .{ .generated = .{ .file = &config_header.output_file } };
110}109}
111110
112fn addValuesInner(self: *ConfigHeader, values: anytype) !void {111fn addValuesInner(config_header: *ConfigHeader, values: anytype) !void {
113 inline for (@typeInfo(@TypeOf(values)).Struct.fields) |field| {112 inline for (@typeInfo(@TypeOf(values)).Struct.fields) |field| {
114 try putValue(self, field.name, field.type, @field(values, field.name));113 try putValue(config_header, field.name, field.type, @field(values, field.name));
115 }114 }
116}115}
117116
118fn putValue(self: *ConfigHeader, field_name: []const u8, comptime T: type, v: T) !void {117fn putValue(config_header: *ConfigHeader, field_name: []const u8, comptime T: type, v: T) !void {
119 switch (@typeInfo(T)) {118 switch (@typeInfo(T)) {
120 .Null => {119 .Null => {
121 try self.values.put(field_name, .undef);120 try config_header.values.put(field_name, .undef);
122 },121 },
123 .Void => {122 .Void => {
124 try self.values.put(field_name, .defined);123 try config_header.values.put(field_name, .defined);
125 },124 },
126 .Bool => {125 .Bool => {
127 try self.values.put(field_name, .{ .boolean = v });126 try config_header.values.put(field_name, .{ .boolean = v });
128 },127 },
129 .Int => {128 .Int => {
130 try self.values.put(field_name, .{ .int = v });129 try config_header.values.put(field_name, .{ .int = v });
131 },130 },
132 .ComptimeInt => {131 .ComptimeInt => {
133 try self.values.put(field_name, .{ .int = v });132 try config_header.values.put(field_name, .{ .int = v });
134 },133 },
135 .EnumLiteral => {134 .EnumLiteral => {
136 try self.values.put(field_name, .{ .ident = @tagName(v) });135 try config_header.values.put(field_name, .{ .ident = @tagName(v) });
137 },136 },
138 .Optional => {137 .Optional => {
139 if (v) |x| {138 if (v) |x| {
140 return putValue(self, field_name, @TypeOf(x), x);139 return putValue(config_header, field_name, @TypeOf(x), x);
141 } else {140 } else {
142 try self.values.put(field_name, .undef);141 try config_header.values.put(field_name, .undef);
143 }142 }
144 },143 },
145 .Pointer => |ptr| {144 .Pointer => |ptr| {
146 switch (@typeInfo(ptr.child)) {145 switch (@typeInfo(ptr.child)) {
147 .Array => |array| {146 .Array => |array| {
148 if (ptr.size == .One and array.child == u8) {147 if (ptr.size == .One and array.child == u8) {
149 try self.values.put(field_name, .{ .string = v });148 try config_header.values.put(field_name, .{ .string = v });
150 return;149 return;
151 }150 }
152 },151 },
153 .Int => {152 .Int => {
154 if (ptr.size == .Slice and ptr.child == u8) {153 if (ptr.size == .Slice and ptr.child == u8) {
155 try self.values.put(field_name, .{ .string = v });154 try config_header.values.put(field_name, .{ .string = v });
156 return;155 return;
157 }156 }
158 },157 },
...@@ -168,7 +167,7 @@ fn putValue(self: *ConfigHeader, field_name: []const u8, comptime T: type, v: T)...@@ -168,7 +167,7 @@ fn putValue(self: *ConfigHeader, field_name: []const u8, comptime T: type, v: T)
168fn make(step: *Step, prog_node: *std.Progress.Node) !void {167fn make(step: *Step, prog_node: *std.Progress.Node) !void {
169 _ = prog_node;168 _ = prog_node;
170 const b = step.owner;169 const b = step.owner;
171 const self: *ConfigHeader = @fieldParentPtr("step", step);170 const config_header: *ConfigHeader = @fieldParentPtr("step", step);
172 const gpa = b.allocator;171 const gpa = b.allocator;
173 const arena = b.allocator;172 const arena = b.allocator;
174173
...@@ -179,8 +178,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -179,8 +178,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
179 // random bytes when ConfigHeader implementation is modified in a178 // random bytes when ConfigHeader implementation is modified in a
180 // non-backwards-compatible way.179 // non-backwards-compatible way.
181 man.hash.add(@as(u32, 0xdef08d23));180 man.hash.add(@as(u32, 0xdef08d23));
182 man.hash.addBytes(self.include_path);181 man.hash.addBytes(config_header.include_path);
183 man.hash.addOptionalBytes(self.include_guard_override);182 man.hash.addOptionalBytes(config_header.include_guard_override);
184183
185 var output = std.ArrayList(u8).init(gpa);184 var output = std.ArrayList(u8).init(gpa);
186 defer output.deinit();185 defer output.deinit();
...@@ -189,34 +188,34 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -189,34 +188,34 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
189 const c_generated_line = "/* " ++ header_text ++ " */\n";188 const c_generated_line = "/* " ++ header_text ++ " */\n";
190 const asm_generated_line = "; " ++ header_text ++ "\n";189 const asm_generated_line = "; " ++ header_text ++ "\n";
191190
192 switch (self.style) {191 switch (config_header.style) {
193 .autoconf => |file_source| {192 .autoconf => |file_source| {
194 try output.appendSlice(c_generated_line);193 try output.appendSlice(c_generated_line);
195 const src_path = file_source.getPath(b);194 const src_path = file_source.getPath2(b, step);
196 const contents = std.fs.cwd().readFileAlloc(arena, src_path, self.max_bytes) catch |err| {195 const contents = std.fs.cwd().readFileAlloc(arena, src_path, config_header.max_bytes) catch |err| {
197 return step.fail("unable to read autoconf input file '{s}': {s}", .{196 return step.fail("unable to read autoconf input file '{s}': {s}", .{
198 src_path, @errorName(err),197 src_path, @errorName(err),
199 });198 });
200 };199 };
201 try render_autoconf(step, contents, &output, self.values, src_path);200 try render_autoconf(step, contents, &output, config_header.values, src_path);
202 },201 },
203 .cmake => |file_source| {202 .cmake => |file_source| {
204 try output.appendSlice(c_generated_line);203 try output.appendSlice(c_generated_line);
205 const src_path = file_source.getPath(b);204 const src_path = file_source.getPath2(b, step);
206 const contents = std.fs.cwd().readFileAlloc(arena, src_path, self.max_bytes) catch |err| {205 const contents = std.fs.cwd().readFileAlloc(arena, src_path, config_header.max_bytes) catch |err| {
207 return step.fail("unable to read cmake input file '{s}': {s}", .{206 return step.fail("unable to read cmake input file '{s}': {s}", .{
208 src_path, @errorName(err),207 src_path, @errorName(err),
209 });208 });
210 };209 };
211 try render_cmake(step, contents, &output, self.values, src_path);210 try render_cmake(step, contents, &output, config_header.values, src_path);
212 },211 },
213 .blank => {212 .blank => {
214 try output.appendSlice(c_generated_line);213 try output.appendSlice(c_generated_line);
215 try render_blank(&output, self.values, self.include_path, self.include_guard_override);214 try render_blank(&output, config_header.values, config_header.include_path, config_header.include_guard_override);
216 },215 },
217 .nasm => {216 .nasm => {
218 try output.appendSlice(asm_generated_line);217 try output.appendSlice(asm_generated_line);
219 try render_nasm(&output, self.values);218 try render_nasm(&output, config_header.values);
220 },219 },
221 }220 }
222221
...@@ -224,8 +223,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -224,8 +223,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
224223
225 if (try step.cacheHit(&man)) {224 if (try step.cacheHit(&man)) {
226 const digest = man.final();225 const digest = man.final();
227 self.output_file.path = try b.cache_root.join(arena, &.{226 config_header.output_file.path = try b.cache_root.join(arena, &.{
228 "o", &digest, self.include_path,227 "o", &digest, config_header.include_path,
229 });228 });
230 return;229 return;
231 }230 }
...@@ -237,7 +236,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -237,7 +236,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
237 // output_path is libavutil/avconfig.h236 // output_path is libavutil/avconfig.h
238 // We want to open directory zig-cache/o/HASH/libavutil/237 // We want to open directory zig-cache/o/HASH/libavutil/
239 // but keep output_dir as zig-cache/o/HASH for -I include238 // but keep output_dir as zig-cache/o/HASH for -I include
240 const sub_path = try std.fs.path.join(arena, &.{ "o", &digest, self.include_path });239 const sub_path = b.pathJoin(&.{ "o", &digest, config_header.include_path });
241 const sub_path_dirname = std.fs.path.dirname(sub_path).?;240 const sub_path_dirname = std.fs.path.dirname(sub_path).?;
242241
243 b.cache_root.handle.makePath(sub_path_dirname) catch |err| {242 b.cache_root.handle.makePath(sub_path_dirname) catch |err| {
...@@ -252,7 +251,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -252,7 +251,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
252 });251 });
253 };252 };
254253
255 self.output_file.path = try b.cache_root.join(arena, &.{sub_path});254 config_header.output_file.path = try b.cache_root.join(arena, &.{sub_path});
256 try man.writeManifest();255 try man.writeManifest();
257}256}
258257
lib/std/Build/Step/Fmt.zig+9-9
...@@ -10,7 +10,7 @@ paths: []const []const u8,...@@ -10,7 +10,7 @@ paths: []const []const u8,
10exclude_paths: []const []const u8,10exclude_paths: []const []const u8,
11check: bool,11check: bool,
1212
13pub const base_id = .fmt;13pub const base_id: Step.Id = .fmt;
1414
15pub const Options = struct {15pub const Options = struct {
16 paths: []const []const u8 = &.{},16 paths: []const []const u8 = &.{},
...@@ -20,9 +20,9 @@ pub const Options = struct {...@@ -20,9 +20,9 @@ pub const Options = struct {
20};20};
2121
22pub fn create(owner: *std.Build, options: Options) *Fmt {22pub fn create(owner: *std.Build, options: Options) *Fmt {
23 const self = owner.allocator.create(Fmt) catch @panic("OOM");23 const fmt = owner.allocator.create(Fmt) catch @panic("OOM");
24 const name = if (options.check) "zig fmt --check" else "zig fmt";24 const name = if (options.check) "zig fmt --check" else "zig fmt";
25 self.* = .{25 fmt.* = .{
26 .step = Step.init(.{26 .step = Step.init(.{
27 .id = base_id,27 .id = base_id,
28 .name = name,28 .name = name,
...@@ -33,7 +33,7 @@ pub fn create(owner: *std.Build, options: Options) *Fmt {...@@ -33,7 +33,7 @@ pub fn create(owner: *std.Build, options: Options) *Fmt {
33 .exclude_paths = owner.dupeStrings(options.exclude_paths),33 .exclude_paths = owner.dupeStrings(options.exclude_paths),
34 .check = options.check,34 .check = options.check,
35 };35 };
36 return self;36 return fmt;
37}37}
3838
39fn make(step: *Step, prog_node: *std.Progress.Node) !void {39fn make(step: *Step, prog_node: *std.Progress.Node) !void {
...@@ -47,23 +47,23 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -47,23 +47,23 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
4747
48 const b = step.owner;48 const b = step.owner;
49 const arena = b.allocator;49 const arena = b.allocator;
50 const self: *Fmt = @fieldParentPtr("step", step);50 const fmt: *Fmt = @fieldParentPtr("step", step);
5151
52 var argv: std.ArrayListUnmanaged([]const u8) = .{};52 var argv: std.ArrayListUnmanaged([]const u8) = .{};
53 try argv.ensureUnusedCapacity(arena, 2 + 1 + self.paths.len + 2 * self.exclude_paths.len);53 try argv.ensureUnusedCapacity(arena, 2 + 1 + fmt.paths.len + 2 * fmt.exclude_paths.len);
5454
55 argv.appendAssumeCapacity(b.graph.zig_exe);55 argv.appendAssumeCapacity(b.graph.zig_exe);
56 argv.appendAssumeCapacity("fmt");56 argv.appendAssumeCapacity("fmt");
5757
58 if (self.check) {58 if (fmt.check) {
59 argv.appendAssumeCapacity("--check");59 argv.appendAssumeCapacity("--check");
60 }60 }
6161
62 for (self.paths) |p| {62 for (fmt.paths) |p| {
63 argv.appendAssumeCapacity(b.pathFromRoot(p));63 argv.appendAssumeCapacity(b.pathFromRoot(p));
64 }64 }
6565
66 for (self.exclude_paths) |p| {66 for (fmt.exclude_paths) |p| {
67 argv.appendAssumeCapacity("--exclude");67 argv.appendAssumeCapacity("--exclude");
68 argv.appendAssumeCapacity(b.pathFromRoot(p));68 argv.appendAssumeCapacity(b.pathFromRoot(p));
69 }69 }
lib/std/Build/Step/InstallArtifact.zig+22-22
...@@ -29,7 +29,7 @@ const DylibSymlinkInfo = struct {...@@ -29,7 +29,7 @@ const DylibSymlinkInfo = struct {
29 name_only_filename: []const u8,29 name_only_filename: []const u8,
30};30};
3131
32pub const base_id = .install_artifact;32pub const base_id: Step.Id = .install_artifact;
3333
34pub const Options = struct {34pub const Options = struct {
35 /// Which installation directory to put the main output file into.35 /// Which installation directory to put the main output file into.
...@@ -52,7 +52,7 @@ pub const Options = struct {...@@ -52,7 +52,7 @@ pub const Options = struct {
52};52};
5353
54pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *InstallArtifact {54pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *InstallArtifact {
55 const self = owner.allocator.create(InstallArtifact) catch @panic("OOM");55 const install_artifact = owner.allocator.create(InstallArtifact) catch @panic("OOM");
56 const dest_dir: ?InstallDir = switch (options.dest_dir) {56 const dest_dir: ?InstallDir = switch (options.dest_dir) {
57 .disabled => null,57 .disabled => null,
58 .default => switch (artifact.kind) {58 .default => switch (artifact.kind) {
...@@ -62,7 +62,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins...@@ -62,7 +62,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins
62 },62 },
63 .override => |o| o,63 .override => |o| o,
64 };64 };
65 self.* = .{65 install_artifact.* = .{
66 .step = Step.init(.{66 .step = Step.init(.{
67 .id = base_id,67 .id = base_id,
68 .name = owner.fmt("install {s}", .{artifact.name}),68 .name = owner.fmt("install {s}", .{artifact.name}),
...@@ -104,28 +104,28 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins...@@ -104,28 +104,28 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins
104 .artifact = artifact,104 .artifact = artifact,
105 };105 };
106106
107 self.step.dependOn(&artifact.step);107 install_artifact.step.dependOn(&artifact.step);
108108
109 if (self.dest_dir != null) self.emitted_bin = artifact.getEmittedBin();109 if (install_artifact.dest_dir != null) install_artifact.emitted_bin = artifact.getEmittedBin();
110 if (self.pdb_dir != null) self.emitted_pdb = artifact.getEmittedPdb();110 if (install_artifact.pdb_dir != null) install_artifact.emitted_pdb = artifact.getEmittedPdb();
111 // https://github.com/ziglang/zig/issues/9698111 // https://github.com/ziglang/zig/issues/9698
112 //if (self.h_dir != null) self.emitted_h = artifact.getEmittedH();112 //if (install_artifact.h_dir != null) install_artifact.emitted_h = artifact.getEmittedH();
113 if (self.implib_dir != null) self.emitted_implib = artifact.getEmittedImplib();113 if (install_artifact.implib_dir != null) install_artifact.emitted_implib = artifact.getEmittedImplib();
114114
115 return self;115 return install_artifact;
116}116}
117117
118fn make(step: *Step, prog_node: *std.Progress.Node) !void {118fn make(step: *Step, prog_node: *std.Progress.Node) !void {
119 _ = prog_node;119 _ = prog_node;
120 const self: *InstallArtifact = @fieldParentPtr("step", step);120 const install_artifact: *InstallArtifact = @fieldParentPtr("step", step);
121 const b = step.owner;121 const b = step.owner;
122 const cwd = fs.cwd();122 const cwd = fs.cwd();
123123
124 var all_cached = true;124 var all_cached = true;
125125
126 if (self.dest_dir) |dest_dir| {126 if (install_artifact.dest_dir) |dest_dir| {
127 const full_dest_path = b.getInstallPath(dest_dir, self.dest_sub_path);127 const full_dest_path = b.getInstallPath(dest_dir, install_artifact.dest_sub_path);
128 const full_src_path = self.emitted_bin.?.getPath2(b, step);128 const full_src_path = install_artifact.emitted_bin.?.getPath2(b, step);
129 const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| {129 const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| {
130 return step.fail("unable to update file from '{s}' to '{s}': {s}", .{130 return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
131 full_src_path, full_dest_path, @errorName(err),131 full_src_path, full_dest_path, @errorName(err),
...@@ -133,15 +133,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -133,15 +133,15 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
133 };133 };
134 all_cached = all_cached and p == .fresh;134 all_cached = all_cached and p == .fresh;
135135
136 if (self.dylib_symlinks) |dls| {136 if (install_artifact.dylib_symlinks) |dls| {
137 try Step.Compile.doAtomicSymLinks(step, full_dest_path, dls.major_only_filename, dls.name_only_filename);137 try Step.Compile.doAtomicSymLinks(step, full_dest_path, dls.major_only_filename, dls.name_only_filename);
138 }138 }
139139
140 self.artifact.installed_path = full_dest_path;140 install_artifact.artifact.installed_path = full_dest_path;
141 }141 }
142142
143 if (self.implib_dir) |implib_dir| {143 if (install_artifact.implib_dir) |implib_dir| {
144 const full_src_path = self.emitted_implib.?.getPath2(b, step);144 const full_src_path = install_artifact.emitted_implib.?.getPath2(b, step);
145 const full_implib_path = b.getInstallPath(implib_dir, fs.path.basename(full_src_path));145 const full_implib_path = b.getInstallPath(implib_dir, fs.path.basename(full_src_path));
146 const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_implib_path, .{}) catch |err| {146 const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_implib_path, .{}) catch |err| {
147 return step.fail("unable to update file from '{s}' to '{s}': {s}", .{147 return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
...@@ -151,8 +151,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -151,8 +151,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
151 all_cached = all_cached and p == .fresh;151 all_cached = all_cached and p == .fresh;
152 }152 }
153153
154 if (self.pdb_dir) |pdb_dir| {154 if (install_artifact.pdb_dir) |pdb_dir| {
155 const full_src_path = self.emitted_pdb.?.getPath2(b, step);155 const full_src_path = install_artifact.emitted_pdb.?.getPath2(b, step);
156 const full_pdb_path = b.getInstallPath(pdb_dir, fs.path.basename(full_src_path));156 const full_pdb_path = b.getInstallPath(pdb_dir, fs.path.basename(full_src_path));
157 const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_pdb_path, .{}) catch |err| {157 const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_pdb_path, .{}) catch |err| {
158 return step.fail("unable to update file from '{s}' to '{s}': {s}", .{158 return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
...@@ -162,8 +162,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -162,8 +162,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
162 all_cached = all_cached and p == .fresh;162 all_cached = all_cached and p == .fresh;
163 }163 }
164164
165 if (self.h_dir) |h_dir| {165 if (install_artifact.h_dir) |h_dir| {
166 if (self.emitted_h) |emitted_h| {166 if (install_artifact.emitted_h) |emitted_h| {
167 const full_src_path = emitted_h.getPath2(b, step);167 const full_src_path = emitted_h.getPath2(b, step);
168 const full_h_path = b.getInstallPath(h_dir, fs.path.basename(full_src_path));168 const full_h_path = b.getInstallPath(h_dir, fs.path.basename(full_src_path));
169 const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_h_path, .{}) catch |err| {169 const p = fs.Dir.updateFile(cwd, full_src_path, cwd, full_h_path, .{}) catch |err| {
...@@ -174,7 +174,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -174,7 +174,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
174 all_cached = all_cached and p == .fresh;174 all_cached = all_cached and p == .fresh;
175 }175 }
176176
177 for (self.artifact.installed_headers.items) |installation| switch (installation) {177 for (install_artifact.artifact.installed_headers.items) |installation| switch (installation) {
178 .file => |file| {178 .file => |file| {
179 const full_src_path = file.source.getPath2(b, step);179 const full_src_path = file.source.getPath2(b, step);
180 const full_h_path = b.getInstallPath(h_dir, file.dest_rel_path);180 const full_h_path = b.getInstallPath(h_dir, file.dest_rel_path);
lib/std/Build/Step/InstallDir.zig+24-25
...@@ -3,17 +3,16 @@ const mem = std.mem;...@@ -3,17 +3,16 @@ const mem = std.mem;
3const fs = std.fs;3const fs = std.fs;
4const Step = std.Build.Step;4const Step = std.Build.Step;
5const LazyPath = std.Build.LazyPath;5const LazyPath = std.Build.LazyPath;
6const InstallDir = std.Build.InstallDir;6const InstallDir = @This();
7const InstallDirStep = @This();
87
9step: Step,8step: Step,
10options: Options,9options: Options,
1110
12pub const base_id = .install_dir;11pub const base_id: Step.Id = .install_dir;
1312
14pub const Options = struct {13pub const Options = struct {
15 source_dir: LazyPath,14 source_dir: LazyPath,
16 install_dir: InstallDir,15 install_dir: std.Build.InstallDir,
17 install_subdir: []const u8,16 install_subdir: []const u8,
18 /// File paths which end in any of these suffixes will be excluded17 /// File paths which end in any of these suffixes will be excluded
19 /// from being installed.18 /// from being installed.
...@@ -29,41 +28,41 @@ pub const Options = struct {...@@ -29,41 +28,41 @@ pub const Options = struct {
29 /// `@import("test.zig")` would be a compile error.28 /// `@import("test.zig")` would be a compile error.
30 blank_extensions: []const []const u8 = &.{},29 blank_extensions: []const []const u8 = &.{},
3130
32 fn dupe(self: Options, b: *std.Build) Options {31 fn dupe(opts: Options, b: *std.Build) Options {
33 return .{32 return .{
34 .source_dir = self.source_dir.dupe(b),33 .source_dir = opts.source_dir.dupe(b),
35 .install_dir = self.install_dir.dupe(b),34 .install_dir = opts.install_dir.dupe(b),
36 .install_subdir = b.dupe(self.install_subdir),35 .install_subdir = b.dupe(opts.install_subdir),
37 .exclude_extensions = b.dupeStrings(self.exclude_extensions),36 .exclude_extensions = b.dupeStrings(opts.exclude_extensions),
38 .include_extensions = if (self.include_extensions) |incs| b.dupeStrings(incs) else null,37 .include_extensions = if (opts.include_extensions) |incs| b.dupeStrings(incs) else null,
39 .blank_extensions = b.dupeStrings(self.blank_extensions),38 .blank_extensions = b.dupeStrings(opts.blank_extensions),
40 };39 };
41 }40 }
42};41};
4342
44pub fn create(owner: *std.Build, options: Options) *InstallDirStep {43pub fn create(owner: *std.Build, options: Options) *InstallDir {
45 owner.pushInstalledFile(options.install_dir, options.install_subdir);44 owner.pushInstalledFile(options.install_dir, options.install_subdir);
46 const self = owner.allocator.create(InstallDirStep) catch @panic("OOM");45 const install_dir = owner.allocator.create(InstallDir) catch @panic("OOM");
47 self.* = .{46 install_dir.* = .{
48 .step = Step.init(.{47 .step = Step.init(.{
49 .id = .install_dir,48 .id = base_id,
50 .name = owner.fmt("install {s}/", .{options.source_dir.getDisplayName()}),49 .name = owner.fmt("install {s}/", .{options.source_dir.getDisplayName()}),
51 .owner = owner,50 .owner = owner,
52 .makeFn = make,51 .makeFn = make,
53 }),52 }),
54 .options = options.dupe(owner),53 .options = options.dupe(owner),
55 };54 };
56 options.source_dir.addStepDependencies(&self.step);55 options.source_dir.addStepDependencies(&install_dir.step);
57 return self;56 return install_dir;
58}57}
5958
60fn make(step: *Step, prog_node: *std.Progress.Node) !void {59fn make(step: *Step, prog_node: *std.Progress.Node) !void {
61 _ = prog_node;60 _ = prog_node;
62 const b = step.owner;61 const b = step.owner;
63 const self: *InstallDirStep = @fieldParentPtr("step", step);62 const install_dir: *InstallDir = @fieldParentPtr("step", step);
64 const arena = b.allocator;63 const arena = b.allocator;
65 const dest_prefix = b.getInstallPath(self.options.install_dir, self.options.install_subdir);64 const dest_prefix = b.getInstallPath(install_dir.options.install_dir, install_dir.options.install_subdir);
66 const src_dir_path = self.options.source_dir.getPath2(b, step);65 const src_dir_path = install_dir.options.source_dir.getPath2(b, step);
67 var src_dir = b.build_root.handle.openDir(src_dir_path, .{ .iterate = true }) catch |err| {66 var src_dir = b.build_root.handle.openDir(src_dir_path, .{ .iterate = true }) catch |err| {
68 return step.fail("unable to open source directory '{}{s}': {s}", .{67 return step.fail("unable to open source directory '{}{s}': {s}", .{
69 b.build_root, src_dir_path, @errorName(err),68 b.build_root, src_dir_path, @errorName(err),
...@@ -73,12 +72,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -73,12 +72,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
73 var it = try src_dir.walk(arena);72 var it = try src_dir.walk(arena);
74 var all_cached = true;73 var all_cached = true;
75 next_entry: while (try it.next()) |entry| {74 next_entry: while (try it.next()) |entry| {
76 for (self.options.exclude_extensions) |ext| {75 for (install_dir.options.exclude_extensions) |ext| {
77 if (mem.endsWith(u8, entry.path, ext)) {76 if (mem.endsWith(u8, entry.path, ext)) {
78 continue :next_entry;77 continue :next_entry;
79 }78 }
80 }79 }
81 if (self.options.include_extensions) |incs| {80 if (install_dir.options.include_extensions) |incs| {
82 var found = false;81 var found = false;
83 for (incs) |inc| {82 for (incs) |inc| {
84 if (mem.endsWith(u8, entry.path, inc)) {83 if (mem.endsWith(u8, entry.path, inc)) {
...@@ -90,14 +89,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -90,14 +89,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
90 }89 }
9190
92 // relative to src build root91 // relative to src build root
93 const src_sub_path = try fs.path.join(arena, &.{ src_dir_path, entry.path });92 const src_sub_path = b.pathJoin(&.{ src_dir_path, entry.path });
94 const dest_path = try fs.path.join(arena, &.{ dest_prefix, entry.path });93 const dest_path = b.pathJoin(&.{ dest_prefix, entry.path });
95 const cwd = fs.cwd();94 const cwd = fs.cwd();
9695
97 switch (entry.kind) {96 switch (entry.kind) {
98 .directory => try cwd.makePath(dest_path),97 .directory => try cwd.makePath(dest_path),
99 .file => {98 .file => {
100 for (self.options.blank_extensions) |ext| {99 for (install_dir.options.blank_extensions) |ext| {
101 if (mem.endsWith(u8, entry.path, ext)) {100 if (mem.endsWith(u8, entry.path, ext)) {
102 try b.truncateFile(dest_path);101 try b.truncateFile(dest_path);
103 continue :next_entry;102 continue :next_entry;
lib/std/Build/Step/InstallFile.zig+8-8
...@@ -5,7 +5,7 @@ const InstallDir = std.Build.InstallDir;...@@ -5,7 +5,7 @@ const InstallDir = std.Build.InstallDir;
5const InstallFile = @This();5const InstallFile = @This();
6const assert = std.debug.assert;6const assert = std.debug.assert;
77
8pub const base_id = .install_file;8pub const base_id: Step.Id = .install_file;
99
10step: Step,10step: Step,
11source: LazyPath,11source: LazyPath,
...@@ -20,8 +20,8 @@ pub fn create(...@@ -20,8 +20,8 @@ pub fn create(
20) *InstallFile {20) *InstallFile {
21 assert(dest_rel_path.len != 0);21 assert(dest_rel_path.len != 0);
22 owner.pushInstalledFile(dir, dest_rel_path);22 owner.pushInstalledFile(dir, dest_rel_path);
23 const self = owner.allocator.create(InstallFile) catch @panic("OOM");23 const install_file = owner.allocator.create(InstallFile) catch @panic("OOM");
24 self.* = .{24 install_file.* = .{
25 .step = Step.init(.{25 .step = Step.init(.{
26 .id = base_id,26 .id = base_id,
27 .name = owner.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }),27 .name = owner.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }),
...@@ -32,16 +32,16 @@ pub fn create(...@@ -32,16 +32,16 @@ pub fn create(
32 .dir = dir.dupe(owner),32 .dir = dir.dupe(owner),
33 .dest_rel_path = owner.dupePath(dest_rel_path),33 .dest_rel_path = owner.dupePath(dest_rel_path),
34 };34 };
35 source.addStepDependencies(&self.step);35 source.addStepDependencies(&install_file.step);
36 return self;36 return install_file;
37}37}
3838
39fn make(step: *Step, prog_node: *std.Progress.Node) !void {39fn make(step: *Step, prog_node: *std.Progress.Node) !void {
40 _ = prog_node;40 _ = prog_node;
41 const b = step.owner;41 const b = step.owner;
42 const self: *InstallFile = @fieldParentPtr("step", step);42 const install_file: *InstallFile = @fieldParentPtr("step", step);
43 const full_src_path = self.source.getPath2(b, step);43 const full_src_path = install_file.source.getPath2(b, step);
44 const full_dest_path = b.getInstallPath(self.dir, self.dest_rel_path);44 const full_dest_path = b.getInstallPath(install_file.dir, install_file.dest_rel_path);
45 const cwd = std.fs.cwd();45 const cwd = std.fs.cwd();
46 const prev = std.fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| {46 const prev = std.fs.Dir.updateFile(cwd, full_src_path, cwd, full_dest_path, .{}) catch |err| {
47 return step.fail("unable to update file from '{s}' to '{s}': {s}", .{47 return step.fail("unable to update file from '{s}' to '{s}': {s}", .{
lib/std/Build/Step/ObjCopy.zig+32-32
...@@ -58,8 +58,8 @@ pub fn create(...@@ -58,8 +58,8 @@ pub fn create(
58 input_file: std.Build.LazyPath,58 input_file: std.Build.LazyPath,
59 options: Options,59 options: Options,
60) *ObjCopy {60) *ObjCopy {
61 const self = owner.allocator.create(ObjCopy) catch @panic("OOM");61 const objcopy = owner.allocator.create(ObjCopy) catch @panic("OOM");
62 self.* = ObjCopy{62 objcopy.* = ObjCopy{
63 .step = Step.init(.{63 .step = Step.init(.{
64 .id = base_id,64 .id = base_id,
65 .name = owner.fmt("objcopy {s}", .{input_file.getDisplayName()}),65 .name = owner.fmt("objcopy {s}", .{input_file.getDisplayName()}),
...@@ -68,31 +68,31 @@ pub fn create(...@@ -68,31 +68,31 @@ pub fn create(
68 }),68 }),
69 .input_file = input_file,69 .input_file = input_file,
70 .basename = options.basename orelse input_file.getDisplayName(),70 .basename = options.basename orelse input_file.getDisplayName(),
71 .output_file = std.Build.GeneratedFile{ .step = &self.step },71 .output_file = std.Build.GeneratedFile{ .step = &objcopy.step },
72 .output_file_debug = if (options.strip != .none and options.extract_to_separate_file) std.Build.GeneratedFile{ .step = &self.step } else null,72 .output_file_debug = if (options.strip != .none and options.extract_to_separate_file) std.Build.GeneratedFile{ .step = &objcopy.step } else null,
73 .format = options.format,73 .format = options.format,
74 .only_sections = options.only_sections,74 .only_sections = options.only_sections,
75 .pad_to = options.pad_to,75 .pad_to = options.pad_to,
76 .strip = options.strip,76 .strip = options.strip,
77 .compress_debug = options.compress_debug,77 .compress_debug = options.compress_debug,
78 };78 };
79 input_file.addStepDependencies(&self.step);79 input_file.addStepDependencies(&objcopy.step);
80 return self;80 return objcopy;
81}81}
8282
83/// deprecated: use getOutput83/// deprecated: use getOutput
84pub const getOutputSource = getOutput;84pub const getOutputSource = getOutput;
8585
86pub fn getOutput(self: *const ObjCopy) std.Build.LazyPath {86pub fn getOutput(objcopy: *const ObjCopy) std.Build.LazyPath {
87 return .{ .generated = &self.output_file };87 return .{ .generated = .{ .file = &objcopy.output_file } };
88}88}
89pub fn getOutputSeparatedDebug(self: *const ObjCopy) ?std.Build.LazyPath {89pub fn getOutputSeparatedDebug(objcopy: *const ObjCopy) ?std.Build.LazyPath {
90 return if (self.output_file_debug) |*file| .{ .generated = file } else null;90 return if (objcopy.output_file_debug) |*file| .{ .generated = .{ .file = file } } else null;
91}91}
9292
93fn make(step: *Step, prog_node: *std.Progress.Node) !void {93fn make(step: *Step, prog_node: *std.Progress.Node) !void {
94 const b = step.owner;94 const b = step.owner;
95 const self: *ObjCopy = @fieldParentPtr("step", step);95 const objcopy: *ObjCopy = @fieldParentPtr("step", step);
9696
97 var man = b.graph.cache.obtain();97 var man = b.graph.cache.obtain();
98 defer man.deinit();98 defer man.deinit();
...@@ -101,24 +101,24 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -101,24 +101,24 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
101 // bytes when ObjCopy implementation is modified incompatibly.101 // bytes when ObjCopy implementation is modified incompatibly.
102 man.hash.add(@as(u32, 0xe18b7baf));102 man.hash.add(@as(u32, 0xe18b7baf));
103103
104 const full_src_path = self.input_file.getPath(b);104 const full_src_path = objcopy.input_file.getPath2(b, step);
105 _ = try man.addFile(full_src_path, null);105 _ = try man.addFile(full_src_path, null);
106 man.hash.addOptionalListOfBytes(self.only_sections);106 man.hash.addOptionalListOfBytes(objcopy.only_sections);
107 man.hash.addOptional(self.pad_to);107 man.hash.addOptional(objcopy.pad_to);
108 man.hash.addOptional(self.format);108 man.hash.addOptional(objcopy.format);
109 man.hash.add(self.compress_debug);109 man.hash.add(objcopy.compress_debug);
110 man.hash.add(self.strip);110 man.hash.add(objcopy.strip);
111 man.hash.add(self.output_file_debug != null);111 man.hash.add(objcopy.output_file_debug != null);
112112
113 if (try step.cacheHit(&man)) {113 if (try step.cacheHit(&man)) {
114 // Cache hit, skip subprocess execution.114 // Cache hit, skip subprocess execution.
115 const digest = man.final();115 const digest = man.final();
116 self.output_file.path = try b.cache_root.join(b.allocator, &.{116 objcopy.output_file.path = try b.cache_root.join(b.allocator, &.{
117 "o", &digest, self.basename,117 "o", &digest, objcopy.basename,
118 });118 });
119 if (self.output_file_debug) |*file| {119 if (objcopy.output_file_debug) |*file| {
120 file.path = try b.cache_root.join(b.allocator, &.{120 file.path = try b.cache_root.join(b.allocator, &.{
121 "o", &digest, b.fmt("{s}.debug", .{self.basename}),121 "o", &digest, b.fmt("{s}.debug", .{objcopy.basename}),
122 });122 });
123 }123 }
124 return;124 return;
...@@ -126,8 +126,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -126,8 +126,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
126126
127 const digest = man.final();127 const digest = man.final();
128 const cache_path = "o" ++ fs.path.sep_str ++ digest;128 const cache_path = "o" ++ fs.path.sep_str ++ digest;
129 const full_dest_path = try b.cache_root.join(b.allocator, &.{ cache_path, self.basename });129 const full_dest_path = try b.cache_root.join(b.allocator, &.{ cache_path, objcopy.basename });
130 const full_dest_path_debug = try b.cache_root.join(b.allocator, &.{ cache_path, b.fmt("{s}.debug", .{self.basename}) });130 const full_dest_path_debug = try b.cache_root.join(b.allocator, &.{ cache_path, b.fmt("{s}.debug", .{objcopy.basename}) });
131 b.cache_root.handle.makePath(cache_path) catch |err| {131 b.cache_root.handle.makePath(cache_path) catch |err| {
132 return step.fail("unable to make path {s}: {s}", .{ cache_path, @errorName(err) });132 return step.fail("unable to make path {s}: {s}", .{ cache_path, @errorName(err) });
133 };133 };
...@@ -135,28 +135,28 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -135,28 +135,28 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
135 var argv = std.ArrayList([]const u8).init(b.allocator);135 var argv = std.ArrayList([]const u8).init(b.allocator);
136 try argv.appendSlice(&.{ b.graph.zig_exe, "objcopy" });136 try argv.appendSlice(&.{ b.graph.zig_exe, "objcopy" });
137137
138 if (self.only_sections) |only_sections| {138 if (objcopy.only_sections) |only_sections| {
139 for (only_sections) |only_section| {139 for (only_sections) |only_section| {
140 try argv.appendSlice(&.{ "-j", only_section });140 try argv.appendSlice(&.{ "-j", only_section });
141 }141 }
142 }142 }
143 switch (self.strip) {143 switch (objcopy.strip) {
144 .none => {},144 .none => {},
145 .debug => try argv.appendSlice(&.{"--strip-debug"}),145 .debug => try argv.appendSlice(&.{"--strip-debug"}),
146 .debug_and_symbols => try argv.appendSlice(&.{"--strip-all"}),146 .debug_and_symbols => try argv.appendSlice(&.{"--strip-all"}),
147 }147 }
148 if (self.pad_to) |pad_to| {148 if (objcopy.pad_to) |pad_to| {
149 try argv.appendSlice(&.{ "--pad-to", b.fmt("{d}", .{pad_to}) });149 try argv.appendSlice(&.{ "--pad-to", b.fmt("{d}", .{pad_to}) });
150 }150 }
151 if (self.format) |format| switch (format) {151 if (objcopy.format) |format| switch (format) {
152 .bin => try argv.appendSlice(&.{ "-O", "binary" }),152 .bin => try argv.appendSlice(&.{ "-O", "binary" }),
153 .hex => try argv.appendSlice(&.{ "-O", "hex" }),153 .hex => try argv.appendSlice(&.{ "-O", "hex" }),
154 .elf => try argv.appendSlice(&.{ "-O", "elf" }),154 .elf => try argv.appendSlice(&.{ "-O", "elf" }),
155 };155 };
156 if (self.compress_debug) {156 if (objcopy.compress_debug) {
157 try argv.appendSlice(&.{"--compress-debug-sections"});157 try argv.appendSlice(&.{"--compress-debug-sections"});
158 }158 }
159 if (self.output_file_debug != null) {159 if (objcopy.output_file_debug != null) {
160 try argv.appendSlice(&.{b.fmt("--extract-to={s}", .{full_dest_path_debug})});160 try argv.appendSlice(&.{b.fmt("--extract-to={s}", .{full_dest_path_debug})});
161 }161 }
162162
...@@ -165,7 +165,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -165,7 +165,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
165 try argv.append("--listen=-");165 try argv.append("--listen=-");
166 _ = try step.evalZigProcess(argv.items, prog_node);166 _ = try step.evalZigProcess(argv.items, prog_node);
167167
168 self.output_file.path = full_dest_path;168 objcopy.output_file.path = full_dest_path;
169 if (self.output_file_debug) |*file| file.path = full_dest_path_debug;169 if (objcopy.output_file_debug) |*file| file.path = full_dest_path_debug;
170 try man.writeManifest();170 try man.writeManifest();
171}171}
lib/std/Build/Step/Options.zig+52-52
...@@ -7,7 +7,7 @@ const LazyPath = std.Build.LazyPath;...@@ -7,7 +7,7 @@ const LazyPath = std.Build.LazyPath;
77
8const Options = @This();8const Options = @This();
99
10pub const base_id = .options;10pub const base_id: Step.Id = .options;
1111
12step: Step,12step: Step,
13generated_file: GeneratedFile,13generated_file: GeneratedFile,
...@@ -17,8 +17,8 @@ args: std.ArrayList(Arg),...@@ -17,8 +17,8 @@ args: std.ArrayList(Arg),
17encountered_types: std.StringHashMap(void),17encountered_types: std.StringHashMap(void),
1818
19pub fn create(owner: *std.Build) *Options {19pub fn create(owner: *std.Build) *Options {
20 const self = owner.allocator.create(Options) catch @panic("OOM");20 const options = owner.allocator.create(Options) catch @panic("OOM");
21 self.* = .{21 options.* = .{
22 .step = Step.init(.{22 .step = Step.init(.{
23 .id = base_id,23 .id = base_id,
24 .name = "options",24 .name = "options",
...@@ -30,21 +30,21 @@ pub fn create(owner: *std.Build) *Options {...@@ -30,21 +30,21 @@ pub fn create(owner: *std.Build) *Options {
30 .args = std.ArrayList(Arg).init(owner.allocator),30 .args = std.ArrayList(Arg).init(owner.allocator),
31 .encountered_types = std.StringHashMap(void).init(owner.allocator),31 .encountered_types = std.StringHashMap(void).init(owner.allocator),
32 };32 };
33 self.generated_file = .{ .step = &self.step };33 options.generated_file = .{ .step = &options.step };
3434
35 return self;35 return options;
36}36}
3737
38pub fn addOption(self: *Options, comptime T: type, name: []const u8, value: T) void {38pub fn addOption(options: *Options, comptime T: type, name: []const u8, value: T) void {
39 return addOptionFallible(self, T, name, value) catch @panic("unhandled error");39 return addOptionFallible(options, T, name, value) catch @panic("unhandled error");
40}40}
4141
42fn addOptionFallible(self: *Options, comptime T: type, name: []const u8, value: T) !void {42fn addOptionFallible(options: *Options, comptime T: type, name: []const u8, value: T) !void {
43 const out = self.contents.writer();43 const out = options.contents.writer();
44 try printType(self, out, T, value, 0, name);44 try printType(options, out, T, value, 0, name);
45}45}
4646
47fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u8, name: ?[]const u8) !void {47fn printType(options: *Options, out: anytype, comptime T: type, value: T, indent: u8, name: ?[]const u8) !void {
48 switch (T) {48 switch (T) {
49 []const []const u8 => {49 []const []const u8 => {
50 if (name) |payload| {50 if (name) |payload| {
...@@ -159,7 +159,7 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u...@@ -159,7 +159,7 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u
159 try out.print("{s} {{\n", .{@typeName(T)});159 try out.print("{s} {{\n", .{@typeName(T)});
160 for (value) |item| {160 for (value) |item| {
161 try out.writeByteNTimes(' ', indent + 4);161 try out.writeByteNTimes(' ', indent + 4);
162 try printType(self, out, @TypeOf(item), item, indent + 4, null);162 try printType(options, out, @TypeOf(item), item, indent + 4, null);
163 }163 }
164 try out.writeByteNTimes(' ', indent);164 try out.writeByteNTimes(' ', indent);
165 try out.writeAll("}");165 try out.writeAll("}");
...@@ -183,7 +183,7 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u...@@ -183,7 +183,7 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u
183 try out.print("&[_]{s} {{\n", .{@typeName(p.child)});183 try out.print("&[_]{s} {{\n", .{@typeName(p.child)});
184 for (value) |item| {184 for (value) |item| {
185 try out.writeByteNTimes(' ', indent + 4);185 try out.writeByteNTimes(' ', indent + 4);
186 try printType(self, out, @TypeOf(item), item, indent + 4, null);186 try printType(options, out, @TypeOf(item), item, indent + 4, null);
187 }187 }
188 try out.writeByteNTimes(' ', indent);188 try out.writeByteNTimes(' ', indent);
189 try out.writeAll("}");189 try out.writeAll("}");
...@@ -201,10 +201,10 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u...@@ -201,10 +201,10 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u
201 }201 }
202202
203 if (value) |inner| {203 if (value) |inner| {
204 try printType(self, out, @TypeOf(inner), inner, indent + 4, null);204 try printType(options, out, @TypeOf(inner), inner, indent + 4, null);
205 // Pop the '\n' and ',' chars205 // Pop the '\n' and ',' chars
206 _ = self.contents.pop();206 _ = options.contents.pop();
207 _ = self.contents.pop();207 _ = options.contents.pop();
208 } else {208 } else {
209 try out.writeAll("null");209 try out.writeAll("null");
210 }210 }
...@@ -231,7 +231,7 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u...@@ -231,7 +231,7 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u
231 return;231 return;
232 },232 },
233 .Enum => |info| {233 .Enum => |info| {
234 try printEnum(self, out, T, info, indent);234 try printEnum(options, out, T, info, indent);
235235
236 if (name) |some| {236 if (name) |some| {
237 try out.print("pub const {}: {} = .{p_};\n", .{237 try out.print("pub const {}: {} = .{p_};\n", .{
...@@ -243,14 +243,14 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u...@@ -243,14 +243,14 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u
243 return;243 return;
244 },244 },
245 .Struct => |info| {245 .Struct => |info| {
246 try printStruct(self, out, T, info, indent);246 try printStruct(options, out, T, info, indent);
247247
248 if (name) |some| {248 if (name) |some| {
249 try out.print("pub const {}: {} = ", .{249 try out.print("pub const {}: {} = ", .{
250 std.zig.fmtId(some),250 std.zig.fmtId(some),
251 std.zig.fmtId(@typeName(T)),251 std.zig.fmtId(@typeName(T)),
252 });252 });
253 try printStructValue(self, out, info, value, indent);253 try printStructValue(options, out, info, value, indent);
254 }254 }
255 return;255 return;
256 },256 },
...@@ -258,20 +258,20 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u...@@ -258,20 +258,20 @@ fn printType(self: *Options, out: anytype, comptime T: type, value: T, indent: u
258 }258 }
259}259}
260260
261fn printUserDefinedType(self: *Options, out: anytype, comptime T: type, indent: u8) !void {261fn printUserDefinedType(options: *Options, out: anytype, comptime T: type, indent: u8) !void {
262 switch (@typeInfo(T)) {262 switch (@typeInfo(T)) {
263 .Enum => |info| {263 .Enum => |info| {
264 return try printEnum(self, out, T, info, indent);264 return try printEnum(options, out, T, info, indent);
265 },265 },
266 .Struct => |info| {266 .Struct => |info| {
267 return try printStruct(self, out, T, info, indent);267 return try printStruct(options, out, T, info, indent);
268 },268 },
269 else => {},269 else => {},
270 }270 }
271}271}
272272
273fn printEnum(self: *Options, out: anytype, comptime T: type, comptime val: std.builtin.Type.Enum, indent: u8) !void {273fn printEnum(options: *Options, out: anytype, comptime T: type, comptime val: std.builtin.Type.Enum, indent: u8) !void {
274 const gop = try self.encountered_types.getOrPut(@typeName(T));274 const gop = try options.encountered_types.getOrPut(@typeName(T));
275 if (gop.found_existing) return;275 if (gop.found_existing) return;
276276
277 try out.writeByteNTimes(' ', indent);277 try out.writeByteNTimes(' ', indent);
...@@ -291,8 +291,8 @@ fn printEnum(self: *Options, out: anytype, comptime T: type, comptime val: std.b...@@ -291,8 +291,8 @@ fn printEnum(self: *Options, out: anytype, comptime T: type, comptime val: std.b
291 try out.writeAll("};\n");291 try out.writeAll("};\n");
292}292}
293293
294fn printStruct(self: *Options, out: anytype, comptime T: type, comptime val: std.builtin.Type.Struct, indent: u8) !void {294fn printStruct(options: *Options, out: anytype, comptime T: type, comptime val: std.builtin.Type.Struct, indent: u8) !void {
295 const gop = try self.encountered_types.getOrPut(@typeName(T));295 const gop = try options.encountered_types.getOrPut(@typeName(T));
296 if (gop.found_existing) return;296 if (gop.found_existing) return;
297297
298 try out.writeByteNTimes(' ', indent);298 try out.writeByteNTimes(' ', indent);
...@@ -325,9 +325,9 @@ fn printStruct(self: *Options, out: anytype, comptime T: type, comptime val: std...@@ -325,9 +325,9 @@ fn printStruct(self: *Options, out: anytype, comptime T: type, comptime val: std
325 switch (@typeInfo(@TypeOf(default_value))) {325 switch (@typeInfo(@TypeOf(default_value))) {
326 .Enum => try out.print(".{s},\n", .{@tagName(default_value)}),326 .Enum => try out.print(".{s},\n", .{@tagName(default_value)}),
327 .Struct => |info| {327 .Struct => |info| {
328 try printStructValue(self, out, info, default_value, indent + 4);328 try printStructValue(options, out, info, default_value, indent + 4);
329 },329 },
330 else => try printType(self, out, @TypeOf(default_value), default_value, indent, null),330 else => try printType(options, out, @TypeOf(default_value), default_value, indent, null),
331 }331 }
332 } else {332 } else {
333 try out.writeAll(",\n");333 try out.writeAll(",\n");
...@@ -340,17 +340,17 @@ fn printStruct(self: *Options, out: anytype, comptime T: type, comptime val: std...@@ -340,17 +340,17 @@ fn printStruct(self: *Options, out: anytype, comptime T: type, comptime val: std
340 try out.writeAll("};\n");340 try out.writeAll("};\n");
341341
342 inline for (val.fields) |field| {342 inline for (val.fields) |field| {
343 try printUserDefinedType(self, out, field.type, 0);343 try printUserDefinedType(options, out, field.type, 0);
344 }344 }
345}345}
346346
347fn printStructValue(self: *Options, out: anytype, comptime struct_val: std.builtin.Type.Struct, val: anytype, indent: u8) !void {347fn printStructValue(options: *Options, out: anytype, comptime struct_val: std.builtin.Type.Struct, val: anytype, indent: u8) !void {
348 try out.writeAll(".{\n");348 try out.writeAll(".{\n");
349349
350 if (struct_val.is_tuple) {350 if (struct_val.is_tuple) {
351 inline for (struct_val.fields) |field| {351 inline for (struct_val.fields) |field| {
352 try out.writeByteNTimes(' ', indent);352 try out.writeByteNTimes(' ', indent);
353 try printType(self, out, @TypeOf(@field(val, field.name)), @field(val, field.name), indent, null);353 try printType(options, out, @TypeOf(@field(val, field.name)), @field(val, field.name), indent, null);
354 }354 }
355 } else {355 } else {
356 inline for (struct_val.fields) |field| {356 inline for (struct_val.fields) |field| {
...@@ -361,9 +361,9 @@ fn printStructValue(self: *Options, out: anytype, comptime struct_val: std.built...@@ -361,9 +361,9 @@ fn printStructValue(self: *Options, out: anytype, comptime struct_val: std.built
361 switch (@typeInfo(@TypeOf(field_name))) {361 switch (@typeInfo(@TypeOf(field_name))) {
362 .Enum => try out.print(".{s},\n", .{@tagName(field_name)}),362 .Enum => try out.print(".{s},\n", .{@tagName(field_name)}),
363 .Struct => |struct_info| {363 .Struct => |struct_info| {
364 try printStructValue(self, out, struct_info, field_name, indent + 4);364 try printStructValue(options, out, struct_info, field_name, indent + 4);
365 },365 },
366 else => try printType(self, out, @TypeOf(field_name), field_name, indent, null),366 else => try printType(options, out, @TypeOf(field_name), field_name, indent, null),
367 }367 }
368 }368 }
369 }369 }
...@@ -379,25 +379,25 @@ fn printStructValue(self: *Options, out: anytype, comptime struct_val: std.built...@@ -379,25 +379,25 @@ fn printStructValue(self: *Options, out: anytype, comptime struct_val: std.built
379/// The value is the path in the cache dir.379/// The value is the path in the cache dir.
380/// Adds a dependency automatically.380/// Adds a dependency automatically.
381pub fn addOptionPath(381pub fn addOptionPath(
382 self: *Options,382 options: *Options,
383 name: []const u8,383 name: []const u8,
384 path: LazyPath,384 path: LazyPath,
385) void {385) void {
386 self.args.append(.{386 options.args.append(.{
387 .name = self.step.owner.dupe(name),387 .name = options.step.owner.dupe(name),
388 .path = path.dupe(self.step.owner),388 .path = path.dupe(options.step.owner),
389 }) catch @panic("OOM");389 }) catch @panic("OOM");
390 path.addStepDependencies(&self.step);390 path.addStepDependencies(&options.step);
391}391}
392392
393/// Deprecated: use `addOptionPath(options, name, artifact.getEmittedBin())` instead.393/// Deprecated: use `addOptionPath(options, name, artifact.getEmittedBin())` instead.
394pub fn addOptionArtifact(self: *Options, name: []const u8, artifact: *Step.Compile) void {394pub fn addOptionArtifact(options: *Options, name: []const u8, artifact: *Step.Compile) void {
395 return addOptionPath(self, name, artifact.getEmittedBin());395 return addOptionPath(options, name, artifact.getEmittedBin());
396}396}
397397
398pub fn createModule(self: *Options) *std.Build.Module {398pub fn createModule(options: *Options) *std.Build.Module {
399 return self.step.owner.createModule(.{399 return options.step.owner.createModule(.{
400 .root_source_file = self.getOutput(),400 .root_source_file = options.getOutput(),
401 });401 });
402}402}
403403
...@@ -406,8 +406,8 @@ pub const getSource = getOutput;...@@ -406,8 +406,8 @@ pub const getSource = getOutput;
406406
407/// Returns the main artifact of this Build Step which is a Zig source file407/// Returns the main artifact of this Build Step which is a Zig source file
408/// generated from the key-value pairs of the Options.408/// generated from the key-value pairs of the Options.
409pub fn getOutput(self: *Options) LazyPath {409pub fn getOutput(options: *Options) LazyPath {
410 return .{ .generated = &self.generated_file };410 return .{ .generated = .{ .file = &options.generated_file } };
411}411}
412412
413fn make(step: *Step, prog_node: *std.Progress.Node) !void {413fn make(step: *Step, prog_node: *std.Progress.Node) !void {
...@@ -415,13 +415,13 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -415,13 +415,13 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
415 _ = prog_node;415 _ = prog_node;
416416
417 const b = step.owner;417 const b = step.owner;
418 const self: *Options = @fieldParentPtr("step", step);418 const options: *Options = @fieldParentPtr("step", step);
419419
420 for (self.args.items) |item| {420 for (options.args.items) |item| {
421 self.addOption(421 options.addOption(
422 []const u8,422 []const u8,
423 item.name,423 item.name,
424 item.path.getPath(b),424 item.path.getPath2(b, step),
425 );425 );
426 }426 }
427427
...@@ -432,10 +432,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -432,10 +432,10 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
432 // Random bytes to make unique. Refresh this with new random bytes when432 // Random bytes to make unique. Refresh this with new random bytes when
433 // implementation is modified in a non-backwards-compatible way.433 // implementation is modified in a non-backwards-compatible way.
434 hash.add(@as(u32, 0xad95e922));434 hash.add(@as(u32, 0xad95e922));
435 hash.addBytes(self.contents.items);435 hash.addBytes(options.contents.items);
436 const sub_path = "c" ++ fs.path.sep_str ++ hash.final() ++ fs.path.sep_str ++ basename;436 const sub_path = "c" ++ fs.path.sep_str ++ hash.final() ++ fs.path.sep_str ++ basename;
437437
438 self.generated_file.path = try b.cache_root.join(b.allocator, &.{sub_path});438 options.generated_file.path = try b.cache_root.join(b.allocator, &.{sub_path});
439439
440 // Optimize for the hot path. Stat the file, and if it already exists,440 // Optimize for the hot path. Stat the file, and if it already exists,
441 // cache hit.441 // cache hit.
...@@ -464,7 +464,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -464,7 +464,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
464 });464 });
465 };465 };
466466
467 b.cache_root.handle.writeFile(.{ .sub_path = tmp_sub_path, .data = self.contents.items }) catch |err| {467 b.cache_root.handle.writeFile(.{ .sub_path = tmp_sub_path, .data = options.contents.items }) catch |err| {
468 return step.fail("unable to write options to '{}{s}': {s}", .{468 return step.fail("unable to write options to '{}{s}': {s}", .{
469 b.cache_root, tmp_sub_path, @errorName(err),469 b.cache_root, tmp_sub_path, @errorName(err),
470 });470 });
lib/std/Build/Step/RemoveDir.zig+9-9
...@@ -3,23 +3,23 @@ const fs = std.fs;...@@ -3,23 +3,23 @@ const fs = std.fs;
3const Step = std.Build.Step;3const Step = std.Build.Step;
4const RemoveDir = @This();4const RemoveDir = @This();
55
6pub const base_id = .remove_dir;6pub const base_id: Step.Id = .remove_dir;
77
8step: Step,8step: Step,
9dir_path: []const u8,9dir_path: []const u8,
1010
11pub fn create(owner: *std.Build, dir_path: []const u8) *RemoveDir {11pub fn create(owner: *std.Build, dir_path: []const u8) *RemoveDir {
12 const self = owner.allocator.create(RemoveDir) catch @panic("OOM");12 const remove_dir = owner.allocator.create(RemoveDir) catch @panic("OOM");
13 self.* = .{13 remove_dir.* = .{
14 .step = Step.init(.{14 .step = Step.init(.{
15 .id = .remove_dir,15 .id = base_id,
16 .name = owner.fmt("RemoveDir {s}", .{dir_path}),16 .name = owner.fmt("RemoveDir {s}", .{dir_path}),
17 .owner = owner,17 .owner = owner,
18 .makeFn = make,18 .makeFn = make,
19 }),19 }),
20 .dir_path = owner.dupePath(dir_path),20 .dir_path = owner.dupePath(dir_path),
21 };21 };
22 return self;22 return remove_dir;
23}23}
2424
25fn make(step: *Step, prog_node: *std.Progress.Node) !void {25fn make(step: *Step, prog_node: *std.Progress.Node) !void {
...@@ -28,16 +28,16 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -28,16 +28,16 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
28 _ = prog_node;28 _ = prog_node;
2929
30 const b = step.owner;30 const b = step.owner;
31 const self: *RemoveDir = @fieldParentPtr("step", step);31 const remove_dir: *RemoveDir = @fieldParentPtr("step", step);
3232
33 b.build_root.handle.deleteTree(self.dir_path) catch |err| {33 b.build_root.handle.deleteTree(remove_dir.dir_path) catch |err| {
34 if (b.build_root.path) |base| {34 if (b.build_root.path) |base| {
35 return step.fail("unable to recursively delete path '{s}/{s}': {s}", .{35 return step.fail("unable to recursively delete path '{s}/{s}': {s}", .{
36 base, self.dir_path, @errorName(err),36 base, remove_dir.dir_path, @errorName(err),
37 });37 });
38 } else {38 } else {
39 return step.fail("unable to recursively delete path '{s}': {s}", .{39 return step.fail("unable to recursively delete path '{s}': {s}", .{
40 self.dir_path, @errorName(err),40 remove_dir.dir_path, @errorName(err),
41 });41 });
42 }42 }
43 };43 };
lib/std/Build/Step/Run.zig+356-237
...@@ -5,7 +5,6 @@ const Step = Build.Step;...@@ -5,7 +5,6 @@ const Step = Build.Step;
5const fs = std.fs;5const fs = std.fs;
6const mem = std.mem;6const mem = std.mem;
7const process = std.process;7const process = std.process;
8const ArrayList = std.ArrayList;
9const EnvMap = process.EnvMap;8const EnvMap = process.EnvMap;
10const assert = std.debug.assert;9const assert = std.debug.assert;
1110
...@@ -16,7 +15,7 @@ pub const base_id: Step.Id = .run;...@@ -16,7 +15,7 @@ pub const base_id: Step.Id = .run;
16step: Step,15step: Step,
1716
18/// See also addArg and addArgs to modifying this directly17/// See also addArg and addArgs to modifying this directly
19argv: ArrayList(Arg),18argv: std.ArrayListUnmanaged(Arg),
2019
21/// Use `setCwd` to set the initial current working directory20/// Use `setCwd` to set the initial current working directory
22cwd: ?Build.LazyPath,21cwd: ?Build.LazyPath,
...@@ -32,22 +31,26 @@ env_map: ?*EnvMap,...@@ -32,22 +31,26 @@ env_map: ?*EnvMap,
32/// If the Run step is determined to not have side-effects, then execution will31/// If the Run step is determined to not have side-effects, then execution will
33/// be skipped if all output files are up-to-date and input files are32/// be skipped if all output files are up-to-date and input files are
34/// unchanged.33/// unchanged.
35stdio: StdIo = .infer_from_args,34stdio: StdIo,
3635
37/// This field must be `.none` if stdio is `inherit`.36/// This field must be `.none` if stdio is `inherit`.
38/// It should be only set using `setStdIn`.37/// It should be only set using `setStdIn`.
39stdin: StdIn = .none,38stdin: StdIn,
4039
41/// Additional file paths relative to build.zig that, when modified, indicate40/// Deprecated: use `addFileInput`
42/// that the Run step should be re-executed.41extra_file_dependencies: []const []const u8,
43/// If the Run step is determined to have side-effects, this field is ignored42
44/// and the Run step is always executed when it appears in the build graph.43/// Additional input files that, when modified, indicate that the Run step
45extra_file_dependencies: []const []const u8 = &.{},44/// should be re-executed.
45/// If the Run step is determined to have side-effects, the Run step is always
46/// executed when it appears in the build graph, regardless of whether these
47/// files have been modified.
48file_inputs: std.ArrayListUnmanaged(std.Build.LazyPath),
4649
47/// After adding an output argument, this step will by default rename itself50/// After adding an output argument, this step will by default rename itself
48/// for a better display name in the build summary.51/// for a better display name in the build summary.
49/// This can be disabled by setting this to false.52/// This can be disabled by setting this to false.
50rename_step_with_output_arg: bool = true,53rename_step_with_output_arg: bool,
5154
52/// If this is true, a Run step which is configured to check the output of the55/// If this is true, a Run step which is configured to check the output of the
53/// executed binary will not fail the build if the binary cannot be executed56/// executed binary will not fail the build if the binary cannot be executed
...@@ -58,25 +61,25 @@ rename_step_with_output_arg: bool = true,...@@ -58,25 +61,25 @@ rename_step_with_output_arg: bool = true,
58/// Rosetta (macOS) and binfmt_misc (Linux).61/// Rosetta (macOS) and binfmt_misc (Linux).
59/// If this Run step is considered to have side-effects, then this flag does62/// If this Run step is considered to have side-effects, then this flag does
60/// nothing.63/// nothing.
61skip_foreign_checks: bool = false,64skip_foreign_checks: bool,
6265
63/// If this is true, failing to execute a foreign binary will be considered an66/// If this is true, failing to execute a foreign binary will be considered an
64/// error. However if this is false, the step will be skipped on failure instead.67/// error. However if this is false, the step will be skipped on failure instead.
65///68///
66/// This allows for a Run step to attempt to execute a foreign binary using an69/// This allows for a Run step to attempt to execute a foreign binary using an
67/// external executor (such as qemu) but not fail if the executor is unavailable.70/// external executor (such as qemu) but not fail if the executor is unavailable.
68failing_to_execute_foreign_is_an_error: bool = true,71failing_to_execute_foreign_is_an_error: bool,
6972
70/// If stderr or stdout exceeds this amount, the child process is killed and73/// If stderr or stdout exceeds this amount, the child process is killed and
71/// the step fails.74/// the step fails.
72max_stdio_size: usize = 10 * 1024 * 1024,75max_stdio_size: usize,
7376
74captured_stdout: ?*Output = null,77captured_stdout: ?*Output,
75captured_stderr: ?*Output = null,78captured_stderr: ?*Output,
7679
77dep_output_file: ?*Output = null,80dep_output_file: ?*Output,
7881
79has_side_effects: bool = false,82has_side_effects: bool,
8083
81pub const StdIn = union(enum) {84pub const StdIn = union(enum) {
82 none,85 none,
...@@ -103,7 +106,7 @@ pub const StdIo = union(enum) {...@@ -103,7 +106,7 @@ pub const StdIo = union(enum) {
103 /// conditions.106 /// conditions.
104 /// Note that an explicit check for exit code 0 needs to be added to this107 /// Note that an explicit check for exit code 0 needs to be added to this
105 /// list if such a check is desirable.108 /// list if such a check is desirable.
106 check: std.ArrayList(Check),109 check: std.ArrayListUnmanaged(Check),
107 /// This Run step is running a zig unit test binary and will communicate110 /// This Run step is running a zig unit test binary and will communicate
108 /// extra metadata over the IPC protocol.111 /// extra metadata over the IPC protocol.
109 zig_test,112 zig_test,
...@@ -122,7 +125,8 @@ pub const Arg = union(enum) {...@@ -122,7 +125,8 @@ pub const Arg = union(enum) {
122 lazy_path: PrefixedLazyPath,125 lazy_path: PrefixedLazyPath,
123 directory_source: PrefixedLazyPath,126 directory_source: PrefixedLazyPath,
124 bytes: []u8,127 bytes: []u8,
125 output: *Output,128 output_file: *Output,
129 output_directory: *Output,
126};130};
127131
128pub const PrefixedLazyPath = struct {132pub const PrefixedLazyPath = struct {
...@@ -137,35 +141,48 @@ pub const Output = struct {...@@ -137,35 +141,48 @@ pub const Output = struct {
137};141};
138142
139pub fn create(owner: *std.Build, name: []const u8) *Run {143pub fn create(owner: *std.Build, name: []const u8) *Run {
140 const self = owner.allocator.create(Run) catch @panic("OOM");144 const run = owner.allocator.create(Run) catch @panic("OOM");
141 self.* = .{145 run.* = .{
142 .step = Step.init(.{146 .step = Step.init(.{
143 .id = base_id,147 .id = base_id,
144 .name = name,148 .name = name,
145 .owner = owner,149 .owner = owner,
146 .makeFn = make,150 .makeFn = make,
147 }),151 }),
148 .argv = ArrayList(Arg).init(owner.allocator),152 .argv = .{},
149 .cwd = null,153 .cwd = null,
150 .env_map = null,154 .env_map = null,
155 .stdio = .infer_from_args,
156 .stdin = .none,
157 .extra_file_dependencies = &.{},
158 .file_inputs = .{},
159 .rename_step_with_output_arg = true,
160 .skip_foreign_checks = false,
161 .failing_to_execute_foreign_is_an_error = true,
162 .max_stdio_size = 10 * 1024 * 1024,
163 .captured_stdout = null,
164 .captured_stderr = null,
165 .dep_output_file = null,
166 .has_side_effects = false,
151 };167 };
152 return self;168 return run;
153}169}
154170
155pub fn setName(self: *Run, name: []const u8) void {171pub fn setName(run: *Run, name: []const u8) void {
156 self.step.name = name;172 run.step.name = name;
157 self.rename_step_with_output_arg = false;173 run.rename_step_with_output_arg = false;
158}174}
159175
160pub fn enableTestRunnerMode(self: *Run) void {176pub fn enableTestRunnerMode(run: *Run) void {
161 self.stdio = .zig_test;177 run.stdio = .zig_test;
162 self.addArgs(&.{"--listen=-"});178 run.addArgs(&.{"--listen=-"});
163}179}
164180
165pub fn addArtifactArg(self: *Run, artifact: *Step.Compile) void {181pub fn addArtifactArg(run: *Run, artifact: *Step.Compile) void {
182 const b = run.step.owner;
166 const bin_file = artifact.getEmittedBin();183 const bin_file = artifact.getEmittedBin();
167 bin_file.addStepDependencies(&self.step);184 bin_file.addStepDependencies(&run.step);
168 self.argv.append(Arg{ .artifact = artifact }) catch @panic("OOM");185 run.argv.append(b.allocator, Arg{ .artifact = artifact }) catch @panic("OOM");
169}186}
170187
171/// Provides a file path as a command line argument to the command being run.188/// Provides a file path as a command line argument to the command being run.
...@@ -176,11 +193,12 @@ pub fn addArtifactArg(self: *Run, artifact: *Step.Compile) void {...@@ -176,11 +193,12 @@ pub fn addArtifactArg(self: *Run, artifact: *Step.Compile) void {
176/// Related:193/// Related:
177/// * `addPrefixedOutputFileArg` - same thing but prepends a string to the argument194/// * `addPrefixedOutputFileArg` - same thing but prepends a string to the argument
178/// * `addFileArg` - for input files given to the child process195/// * `addFileArg` - for input files given to the child process
179pub fn addOutputFileArg(self: *Run, basename: []const u8) std.Build.LazyPath {196pub fn addOutputFileArg(run: *Run, basename: []const u8) std.Build.LazyPath {
180 return self.addPrefixedOutputFileArg("", basename);197 return run.addPrefixedOutputFileArg("", basename);
181}198}
182199
183/// Provides a file path as a command line argument to the command being run.200/// Provides a file path as a command line argument to the command being run.
201/// Asserts `basename` is not empty.
184///202///
185/// For example, a prefix of "-o" and basename of "output.txt" will result in203/// For example, a prefix of "-o" and basename of "output.txt" will result in
186/// the child process seeing something like this: "-ozig-cache/.../output.txt"204/// the child process seeing something like this: "-ozig-cache/.../output.txt"
...@@ -195,25 +213,26 @@ pub fn addOutputFileArg(self: *Run, basename: []const u8) std.Build.LazyPath {...@@ -195,25 +213,26 @@ pub fn addOutputFileArg(self: *Run, basename: []const u8) std.Build.LazyPath {
195/// * `addOutputFileArg` - same thing but without the prefix213/// * `addOutputFileArg` - same thing but without the prefix
196/// * `addFileArg` - for input files given to the child process214/// * `addFileArg` - for input files given to the child process
197pub fn addPrefixedOutputFileArg(215pub fn addPrefixedOutputFileArg(
198 self: *Run,216 run: *Run,
199 prefix: []const u8,217 prefix: []const u8,
200 basename: []const u8,218 basename: []const u8,
201) std.Build.LazyPath {219) std.Build.LazyPath {
202 const b = self.step.owner;220 const b = run.step.owner;
221 if (basename.len == 0) @panic("basename must not be empty");
203222
204 const output = b.allocator.create(Output) catch @panic("OOM");223 const output = b.allocator.create(Output) catch @panic("OOM");
205 output.* = .{224 output.* = .{
206 .prefix = prefix,225 .prefix = b.dupe(prefix),
207 .basename = basename,226 .basename = b.dupe(basename),
208 .generated_file = .{ .step = &self.step },227 .generated_file = .{ .step = &run.step },
209 };228 };
210 self.argv.append(.{ .output = output }) catch @panic("OOM");229 run.argv.append(b.allocator, .{ .output_file = output }) catch @panic("OOM");
211230
212 if (self.rename_step_with_output_arg) {231 if (run.rename_step_with_output_arg) {
213 self.setName(b.fmt("{s} ({s})", .{ self.step.name, basename }));232 run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename }));
214 }233 }
215234
216 return .{ .generated = &output.generated_file };235 return .{ .generated = .{ .file = &output.generated_file } };
217}236}
218237
219/// Appends an input file to the command line arguments.238/// Appends an input file to the command line arguments.
...@@ -225,8 +244,8 @@ pub fn addPrefixedOutputFileArg(...@@ -225,8 +244,8 @@ pub fn addPrefixedOutputFileArg(
225/// Related:244/// Related:
226/// * `addPrefixedFileArg` - same thing but prepends a string to the argument245/// * `addPrefixedFileArg` - same thing but prepends a string to the argument
227/// * `addOutputFileArg` - for files generated by the child process246/// * `addOutputFileArg` - for files generated by the child process
228pub fn addFileArg(self: *Run, lp: std.Build.LazyPath) void {247pub fn addFileArg(run: *Run, lp: std.Build.LazyPath) void {
229 self.addPrefixedFileArg("", lp);248 run.addPrefixedFileArg("", lp);
230}249}
231250
232/// Appends an input file to the command line arguments prepended with a string.251/// Appends an input file to the command line arguments prepended with a string.
...@@ -241,100 +260,148 @@ pub fn addFileArg(self: *Run, lp: std.Build.LazyPath) void {...@@ -241,100 +260,148 @@ pub fn addFileArg(self: *Run, lp: std.Build.LazyPath) void {
241/// Related:260/// Related:
242/// * `addFileArg` - same thing but without the prefix261/// * `addFileArg` - same thing but without the prefix
243/// * `addOutputFileArg` - for files generated by the child process262/// * `addOutputFileArg` - for files generated by the child process
244pub fn addPrefixedFileArg(self: *Run, prefix: []const u8, lp: std.Build.LazyPath) void {263pub fn addPrefixedFileArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void {
245 const b = self.step.owner;264 const b = run.step.owner;
246265
247 const prefixed_file_source: PrefixedLazyPath = .{266 const prefixed_file_source: PrefixedLazyPath = .{
248 .prefix = b.dupe(prefix),267 .prefix = b.dupe(prefix),
249 .lazy_path = lp.dupe(b),268 .lazy_path = lp.dupe(b),
250 };269 };
251 self.argv.append(.{ .lazy_path = prefixed_file_source }) catch @panic("OOM");270 run.argv.append(b.allocator, .{ .lazy_path = prefixed_file_source }) catch @panic("OOM");
252 lp.addStepDependencies(&self.step);271 lp.addStepDependencies(&run.step);
272}
273
274/// Provides a directory path as a command line argument to the command being run.
275///
276/// Returns a `std.Build.LazyPath` which can be used as inputs to other APIs
277/// throughout the build system.
278///
279/// Related:
280/// * `addPrefixedOutputDirectoryArg` - same thing but prepends a string to the argument
281/// * `addDirectoryArg` - for input directories given to the child process
282pub fn addOutputDirectoryArg(run: *Run, basename: []const u8) std.Build.LazyPath {
283 return run.addPrefixedOutputDirectoryArg("", basename);
284}
285
286/// Provides a directory path as a command line argument to the command being run.
287/// Asserts `basename` is not empty.
288///
289/// For example, a prefix of "-o" and basename of "output_dir" will result in
290/// the child process seeing something like this: "-ozig-cache/.../output_dir"
291///
292/// The child process will see a single argument, regardless of whether the
293/// prefix or basename have spaces.
294///
295/// The returned `std.Build.LazyPath` can be used as inputs to other APIs
296/// throughout the build system.
297///
298/// Related:
299/// * `addOutputDirectoryArg` - same thing but without the prefix
300/// * `addDirectoryArg` - for input directories given to the child process
301pub fn addPrefixedOutputDirectoryArg(
302 run: *Run,
303 prefix: []const u8,
304 basename: []const u8,
305) std.Build.LazyPath {
306 if (basename.len == 0) @panic("basename must not be empty");
307 const b = run.step.owner;
308
309 const output = b.allocator.create(Output) catch @panic("OOM");
310 output.* = .{
311 .prefix = b.dupe(prefix),
312 .basename = b.dupe(basename),
313 .generated_file = .{ .step = &run.step },
314 };
315 run.argv.append(b.allocator, .{ .output_directory = output }) catch @panic("OOM");
316
317 if (run.rename_step_with_output_arg) {
318 run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename }));
319 }
320
321 return .{ .generated = .{ .file = &output.generated_file } };
253}322}
254323
255/// deprecated: use `addDirectoryArg`324/// deprecated: use `addDirectoryArg`
256pub const addDirectorySourceArg = addDirectoryArg;325pub const addDirectorySourceArg = addDirectoryArg;
257326
258pub fn addDirectoryArg(self: *Run, directory_source: std.Build.LazyPath) void {327pub fn addDirectoryArg(run: *Run, directory_source: std.Build.LazyPath) void {
259 self.addPrefixedDirectoryArg("", directory_source);328 run.addPrefixedDirectoryArg("", directory_source);
260}329}
261330
262// deprecated: use `addPrefixedDirectoryArg`331// deprecated: use `addPrefixedDirectoryArg`
263pub const addPrefixedDirectorySourceArg = addPrefixedDirectoryArg;332pub const addPrefixedDirectorySourceArg = addPrefixedDirectoryArg;
264333
265pub fn addPrefixedDirectoryArg(self: *Run, prefix: []const u8, directory_source: std.Build.LazyPath) void {334pub fn addPrefixedDirectoryArg(run: *Run, prefix: []const u8, directory_source: std.Build.LazyPath) void {
266 const b = self.step.owner;335 const b = run.step.owner;
267336
268 const prefixed_directory_source: PrefixedLazyPath = .{337 const prefixed_directory_source: PrefixedLazyPath = .{
269 .prefix = b.dupe(prefix),338 .prefix = b.dupe(prefix),
270 .lazy_path = directory_source.dupe(b),339 .lazy_path = directory_source.dupe(b),
271 };340 };
272 self.argv.append(.{ .directory_source = prefixed_directory_source }) catch @panic("OOM");341 run.argv.append(b.allocator, .{ .directory_source = prefixed_directory_source }) catch @panic("OOM");
273 directory_source.addStepDependencies(&self.step);342 directory_source.addStepDependencies(&run.step);
274}343}
275344
276/// Add a path argument to a dep file (.d) for the child process to write its345/// Add a path argument to a dep file (.d) for the child process to write its
277/// discovered additional dependencies.346/// discovered additional dependencies.
278/// Only one dep file argument is allowed by instance.347/// Only one dep file argument is allowed by instance.
279pub fn addDepFileOutputArg(self: *Run, basename: []const u8) std.Build.LazyPath {348pub fn addDepFileOutputArg(run: *Run, basename: []const u8) std.Build.LazyPath {
280 return self.addPrefixedDepFileOutputArg("", basename);349 return run.addPrefixedDepFileOutputArg("", basename);
281}350}
282351
283/// Add a prefixed path argument to a dep file (.d) for the child process to352/// Add a prefixed path argument to a dep file (.d) for the child process to
284/// write its discovered additional dependencies.353/// write its discovered additional dependencies.
285/// Only one dep file argument is allowed by instance.354/// Only one dep file argument is allowed by instance.
286pub fn addPrefixedDepFileOutputArg(self: *Run, prefix: []const u8, basename: []const u8) std.Build.LazyPath {355pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []const u8) std.Build.LazyPath {
287 assert(self.dep_output_file == null);356 const b = run.step.owner;
288357 assert(run.dep_output_file == null);
289 const b = self.step.owner;
290358
291 const dep_file = b.allocator.create(Output) catch @panic("OOM");359 const dep_file = b.allocator.create(Output) catch @panic("OOM");
292 dep_file.* = .{360 dep_file.* = .{
293 .prefix = b.dupe(prefix),361 .prefix = b.dupe(prefix),
294 .basename = b.dupe(basename),362 .basename = b.dupe(basename),
295 .generated_file = .{ .step = &self.step },363 .generated_file = .{ .step = &run.step },
296 };364 };
297365
298 self.dep_output_file = dep_file;366 run.dep_output_file = dep_file;
299367
300 self.argv.append(.{ .output = dep_file }) catch @panic("OOM");368 run.argv.append(b.allocator, .{ .output_file = dep_file }) catch @panic("OOM");
301369
302 return .{ .generated = &dep_file.generated_file };370 return .{ .generated = .{ .file = &dep_file.generated_file } };
303}371}
304372
305pub fn addArg(self: *Run, arg: []const u8) void {373pub fn addArg(run: *Run, arg: []const u8) void {
306 self.argv.append(.{ .bytes = self.step.owner.dupe(arg) }) catch @panic("OOM");374 const b = run.step.owner;
375 run.argv.append(b.allocator, .{ .bytes = b.dupe(arg) }) catch @panic("OOM");
307}376}
308377
309pub fn addArgs(self: *Run, args: []const []const u8) void {378pub fn addArgs(run: *Run, args: []const []const u8) void {
310 for (args) |arg| {379 for (args) |arg| run.addArg(arg);
311 self.addArg(arg);
312 }
313}380}
314381
315pub fn setStdIn(self: *Run, stdin: StdIn) void {382pub fn setStdIn(run: *Run, stdin: StdIn) void {
316 switch (stdin) {383 switch (stdin) {
317 .lazy_path => |lazy_path| lazy_path.addStepDependencies(&self.step),384 .lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step),
318 .bytes, .none => {},385 .bytes, .none => {},
319 }386 }
320 self.stdin = stdin;387 run.stdin = stdin;
321}388}
322389
323pub fn setCwd(self: *Run, cwd: Build.LazyPath) void {390pub fn setCwd(run: *Run, cwd: Build.LazyPath) void {
324 cwd.addStepDependencies(&self.step);391 cwd.addStepDependencies(&run.step);
325 self.cwd = cwd;392 run.cwd = cwd.dupe(run.step.owner);
326}393}
327394
328pub fn clearEnvironment(self: *Run) void {395pub fn clearEnvironment(run: *Run) void {
329 const b = self.step.owner;396 const b = run.step.owner;
330 const new_env_map = b.allocator.create(EnvMap) catch @panic("OOM");397 const new_env_map = b.allocator.create(EnvMap) catch @panic("OOM");
331 new_env_map.* = EnvMap.init(b.allocator);398 new_env_map.* = EnvMap.init(b.allocator);
332 self.env_map = new_env_map;399 run.env_map = new_env_map;
333}400}
334401
335pub fn addPathDir(self: *Run, search_path: []const u8) void {402pub fn addPathDir(run: *Run, search_path: []const u8) void {
336 const b = self.step.owner;403 const b = run.step.owner;
337 const env_map = getEnvMapInternal(self);404 const env_map = getEnvMapInternal(run);
338405
339 const key = "PATH";406 const key = "PATH";
340 const prev_path = env_map.get(key);407 const prev_path = env_map.get(key);
...@@ -347,116 +414,128 @@ pub fn addPathDir(self: *Run, search_path: []const u8) void {...@@ -347,116 +414,128 @@ pub fn addPathDir(self: *Run, search_path: []const u8) void {
347 }414 }
348}415}
349416
350pub fn getEnvMap(self: *Run) *EnvMap {417pub fn getEnvMap(run: *Run) *EnvMap {
351 return getEnvMapInternal(self);418 return getEnvMapInternal(run);
352}419}
353420
354fn getEnvMapInternal(self: *Run) *EnvMap {421fn getEnvMapInternal(run: *Run) *EnvMap {
355 const arena = self.step.owner.allocator;422 const arena = run.step.owner.allocator;
356 return self.env_map orelse {423 return run.env_map orelse {
357 const env_map = arena.create(EnvMap) catch @panic("OOM");424 const env_map = arena.create(EnvMap) catch @panic("OOM");
358 env_map.* = process.getEnvMap(arena) catch @panic("unhandled error");425 env_map.* = process.getEnvMap(arena) catch @panic("unhandled error");
359 self.env_map = env_map;426 run.env_map = env_map;
360 return env_map;427 return env_map;
361 };428 };
362}429}
363430
364pub fn setEnvironmentVariable(self: *Run, key: []const u8, value: []const u8) void {431pub fn setEnvironmentVariable(run: *Run, key: []const u8, value: []const u8) void {
365 const b = self.step.owner;432 const b = run.step.owner;
366 const env_map = self.getEnvMap();433 const env_map = run.getEnvMap();
367 env_map.put(b.dupe(key), b.dupe(value)) catch @panic("unhandled error");434 env_map.put(b.dupe(key), b.dupe(value)) catch @panic("unhandled error");
368}435}
369436
370pub fn removeEnvironmentVariable(self: *Run, key: []const u8) void {437pub fn removeEnvironmentVariable(run: *Run, key: []const u8) void {
371 self.getEnvMap().remove(key);438 run.getEnvMap().remove(key);
372}439}
373440
374/// Adds a check for exact stderr match. Does not add any other checks.441/// Adds a check for exact stderr match. Does not add any other checks.
375pub fn expectStdErrEqual(self: *Run, bytes: []const u8) void {442pub fn expectStdErrEqual(run: *Run, bytes: []const u8) void {
376 const new_check: StdIo.Check = .{ .expect_stderr_exact = self.step.owner.dupe(bytes) };443 const new_check: StdIo.Check = .{ .expect_stderr_exact = run.step.owner.dupe(bytes) };
377 self.addCheck(new_check);444 run.addCheck(new_check);
378}445}
379446
380/// Adds a check for exact stdout match as well as a check for exit code 0, if447/// Adds a check for exact stdout match as well as a check for exit code 0, if
381/// there is not already an expected termination check.448/// there is not already an expected termination check.
382pub fn expectStdOutEqual(self: *Run, bytes: []const u8) void {449pub fn expectStdOutEqual(run: *Run, bytes: []const u8) void {
383 const new_check: StdIo.Check = .{ .expect_stdout_exact = self.step.owner.dupe(bytes) };450 const new_check: StdIo.Check = .{ .expect_stdout_exact = run.step.owner.dupe(bytes) };
384 self.addCheck(new_check);451 run.addCheck(new_check);
385 if (!self.hasTermCheck()) {452 if (!run.hasTermCheck()) {
386 self.expectExitCode(0);453 run.expectExitCode(0);
387 }454 }
388}455}
389456
390pub fn expectExitCode(self: *Run, code: u8) void {457pub fn expectExitCode(run: *Run, code: u8) void {
391 const new_check: StdIo.Check = .{ .expect_term = .{ .Exited = code } };458 const new_check: StdIo.Check = .{ .expect_term = .{ .Exited = code } };
392 self.addCheck(new_check);459 run.addCheck(new_check);
393}460}
394461
395pub fn hasTermCheck(self: Run) bool {462pub fn hasTermCheck(run: Run) bool {
396 for (self.stdio.check.items) |check| switch (check) {463 for (run.stdio.check.items) |check| switch (check) {
397 .expect_term => return true,464 .expect_term => return true,
398 else => continue,465 else => continue,
399 };466 };
400 return false;467 return false;
401}468}
402469
403pub fn addCheck(self: *Run, new_check: StdIo.Check) void {470pub fn addCheck(run: *Run, new_check: StdIo.Check) void {
404 switch (self.stdio) {471 const b = run.step.owner;
472
473 switch (run.stdio) {
405 .infer_from_args => {474 .infer_from_args => {
406 self.stdio = .{ .check = std.ArrayList(StdIo.Check).init(self.step.owner.allocator) };475 run.stdio = .{ .check = .{} };
407 self.stdio.check.append(new_check) catch @panic("OOM");476 run.stdio.check.append(b.allocator, new_check) catch @panic("OOM");
408 },477 },
409 .check => |*checks| checks.append(new_check) catch @panic("OOM"),478 .check => |*checks| checks.append(b.allocator, new_check) catch @panic("OOM"),
410 else => @panic("illegal call to addCheck: conflicting helper method calls. Suggest to directly set stdio field of Run instead"),479 else => @panic("illegal call to addCheck: conflicting helper method calls. Suggest to directly set stdio field of Run instead"),
411 }480 }
412}481}
413482
414pub fn captureStdErr(self: *Run) std.Build.LazyPath {483pub fn captureStdErr(run: *Run) std.Build.LazyPath {
415 assert(self.stdio != .inherit);484 assert(run.stdio != .inherit);
416485
417 if (self.captured_stderr) |output| return .{ .generated = &output.generated_file };486 if (run.captured_stderr) |output| return .{ .generated = .{ .file = &output.generated_file } };
418487
419 const output = self.step.owner.allocator.create(Output) catch @panic("OOM");488 const output = run.step.owner.allocator.create(Output) catch @panic("OOM");
420 output.* = .{489 output.* = .{
421 .prefix = "",490 .prefix = "",
422 .basename = "stderr",491 .basename = "stderr",
423 .generated_file = .{ .step = &self.step },492 .generated_file = .{ .step = &run.step },
424 };493 };
425 self.captured_stderr = output;494 run.captured_stderr = output;
426 return .{ .generated = &output.generated_file };495 return .{ .generated = .{ .file = &output.generated_file } };
427}496}
428497
429pub fn captureStdOut(self: *Run) std.Build.LazyPath {498pub fn captureStdOut(run: *Run) std.Build.LazyPath {
430 assert(self.stdio != .inherit);499 assert(run.stdio != .inherit);
431500
432 if (self.captured_stdout) |output| return .{ .generated = &output.generated_file };501 if (run.captured_stdout) |output| return .{ .generated = .{ .file = &output.generated_file } };
433502
434 const output = self.step.owner.allocator.create(Output) catch @panic("OOM");503 const output = run.step.owner.allocator.create(Output) catch @panic("OOM");
435 output.* = .{504 output.* = .{
436 .prefix = "",505 .prefix = "",
437 .basename = "stdout",506 .basename = "stdout",
438 .generated_file = .{ .step = &self.step },507 .generated_file = .{ .step = &run.step },
439 };508 };
440 self.captured_stdout = output;509 run.captured_stdout = output;
441 return .{ .generated = &output.generated_file };510 return .{ .generated = .{ .file = &output.generated_file } };
511}
512
513/// Adds an additional input files that, when modified, indicates that this Run
514/// step should be re-executed.
515/// If the Run step is determined to have side-effects, the Run step is always
516/// executed when it appears in the build graph, regardless of whether this
517/// file has been modified.
518pub fn addFileInput(self: *Run, file_input: std.Build.LazyPath) void {
519 file_input.addStepDependencies(&self.step);
520 self.file_inputs.append(self.step.owner.allocator, file_input.dupe(self.step.owner)) catch @panic("OOM");
442}521}
443522
444/// Returns whether the Run step has side effects *other than* updating the output arguments.523/// Returns whether the Run step has side effects *other than* updating the output arguments.
445fn hasSideEffects(self: Run) bool {524fn hasSideEffects(run: Run) bool {
446 if (self.has_side_effects) return true;525 if (run.has_side_effects) return true;
447 return switch (self.stdio) {526 return switch (run.stdio) {
448 .infer_from_args => !self.hasAnyOutputArgs(),527 .infer_from_args => !run.hasAnyOutputArgs(),
449 .inherit => true,528 .inherit => true,
450 .check => false,529 .check => false,
451 .zig_test => false,530 .zig_test => false,
452 };531 };
453}532}
454533
455fn hasAnyOutputArgs(self: Run) bool {534fn hasAnyOutputArgs(run: Run) bool {
456 if (self.captured_stdout != null) return true;535 if (run.captured_stdout != null) return true;
457 if (self.captured_stderr != null) return true;536 if (run.captured_stderr != null) return true;
458 for (self.argv.items) |arg| switch (arg) {537 for (run.argv.items) |arg| switch (arg) {
459 .output => return true,538 .output_file, .output_directory => return true,
460 else => continue,539 else => continue,
461 };540 };
462 return false;541 return false;
...@@ -492,34 +571,35 @@ fn checksContainStderr(checks: []const StdIo.Check) bool {...@@ -492,34 +571,35 @@ fn checksContainStderr(checks: []const StdIo.Check) bool {
492571
493const IndexedOutput = struct {572const IndexedOutput = struct {
494 index: usize,573 index: usize,
574 tag: @typeInfo(Arg).Union.tag_type.?,
495 output: *Output,575 output: *Output,
496};576};
497fn make(step: *Step, prog_node: *std.Progress.Node) !void {577fn make(step: *Step, prog_node: *std.Progress.Node) !void {
498 const b = step.owner;578 const b = step.owner;
499 const arena = b.allocator;579 const arena = b.allocator;
500 const self: *Run = @fieldParentPtr("step", step);580 const run: *Run = @fieldParentPtr("step", step);
501 const has_side_effects = self.hasSideEffects();581 const has_side_effects = run.hasSideEffects();
502582
503 var argv_list = ArrayList([]const u8).init(arena);583 var argv_list = std.ArrayList([]const u8).init(arena);
504 var output_placeholders = ArrayList(IndexedOutput).init(arena);584 var output_placeholders = std.ArrayList(IndexedOutput).init(arena);
505585
506 var man = b.graph.cache.obtain();586 var man = b.graph.cache.obtain();
507 defer man.deinit();587 defer man.deinit();
508588
509 for (self.argv.items) |arg| {589 for (run.argv.items) |arg| {
510 switch (arg) {590 switch (arg) {
511 .bytes => |bytes| {591 .bytes => |bytes| {
512 try argv_list.append(bytes);592 try argv_list.append(bytes);
513 man.hash.addBytes(bytes);593 man.hash.addBytes(bytes);
514 },594 },
515 .lazy_path => |file| {595 .lazy_path => |file| {
516 const file_path = file.lazy_path.getPath(b);596 const file_path = file.lazy_path.getPath2(b, step);
517 try argv_list.append(b.fmt("{s}{s}", .{ file.prefix, file_path }));597 try argv_list.append(b.fmt("{s}{s}", .{ file.prefix, file_path }));
518 man.hash.addBytes(file.prefix);598 man.hash.addBytes(file.prefix);
519 _ = try man.addFile(file_path, null);599 _ = try man.addFile(file_path, null);
520 },600 },
521 .directory_source => |file| {601 .directory_source => |file| {
522 const file_path = file.lazy_path.getPath(b);602 const file_path = file.lazy_path.getPath2(b, step);
523 try argv_list.append(b.fmt("{s}{s}", .{ file.prefix, file_path }));603 try argv_list.append(b.fmt("{s}{s}", .{ file.prefix, file_path }));
524 man.hash.addBytes(file.prefix);604 man.hash.addBytes(file.prefix);
525 man.hash.addBytes(file_path);605 man.hash.addBytes(file_path);
...@@ -527,7 +607,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -527,7 +607,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
527 .artifact => |artifact| {607 .artifact => |artifact| {
528 if (artifact.rootModuleTarget().os.tag == .windows) {608 if (artifact.rootModuleTarget().os.tag == .windows) {
529 // On Windows we don't have rpaths so we have to add .dll search paths to PATH609 // On Windows we don't have rpaths so we have to add .dll search paths to PATH
530 self.addPathForDynLibs(artifact);610 run.addPathForDynLibs(artifact);
531 }611 }
532 const file_path = artifact.installed_path orelse artifact.generated_bin.?.path.?; // the path is guaranteed to be set612 const file_path = artifact.installed_path orelse artifact.generated_bin.?.path.?; // the path is guaranteed to be set
533613
...@@ -535,60 +615,59 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -535,60 +615,59 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
535615
536 _ = try man.addFile(file_path, null);616 _ = try man.addFile(file_path, null);
537 },617 },
538 .output => |output| {618 .output_file, .output_directory => |output| {
539 man.hash.addBytes(output.prefix);619 man.hash.addBytes(output.prefix);
540 man.hash.addBytes(output.basename);620 man.hash.addBytes(output.basename);
541 // Add a placeholder into the argument list because we need the621 // Add a placeholder into the argument list because we need the
542 // manifest hash to be updated with all arguments before the622 // manifest hash to be updated with all arguments before the
543 // object directory is computed.623 // object directory is computed.
544 try argv_list.append("");
545 try output_placeholders.append(.{624 try output_placeholders.append(.{
546 .index = argv_list.items.len - 1,625 .index = argv_list.items.len,
626 .tag = arg,
547 .output = output,627 .output = output,
548 });628 });
629 _ = try argv_list.addOne();
549 },630 },
550 }631 }
551 }632 }
552633
553 switch (self.stdin) {634 switch (run.stdin) {
554 .bytes => |bytes| {635 .bytes => |bytes| {
555 man.hash.addBytes(bytes);636 man.hash.addBytes(bytes);
556 },637 },
557 .lazy_path => |lazy_path| {638 .lazy_path => |lazy_path| {
558 const file_path = lazy_path.getPath(b);639 const file_path = lazy_path.getPath2(b, step);
559 _ = try man.addFile(file_path, null);640 _ = try man.addFile(file_path, null);
560 },641 },
561 .none => {},642 .none => {},
562 }643 }
563644
564 if (self.captured_stdout) |output| {645 if (run.captured_stdout) |output| {
565 man.hash.addBytes(output.basename);646 man.hash.addBytes(output.basename);
566 }647 }
567648
568 if (self.captured_stderr) |output| {649 if (run.captured_stderr) |output| {
569 man.hash.addBytes(output.basename);650 man.hash.addBytes(output.basename);
570 }651 }
571652
572 hashStdIo(&man.hash, self.stdio);653 hashStdIo(&man.hash, run.stdio);
573654
574 if (has_side_effects) {655 for (run.extra_file_dependencies) |file_path| {
575 try runCommand(self, argv_list.items, has_side_effects, null, prog_node);
576 return;
577 }
578
579 for (self.extra_file_dependencies) |file_path| {
580 _ = try man.addFile(b.pathFromRoot(file_path), null);656 _ = try man.addFile(b.pathFromRoot(file_path), null);
581 }657 }
658 for (run.file_inputs.items) |lazy_path| {
659 _ = try man.addFile(lazy_path.getPath2(b, step), null);
660 }
582661
583 if (try step.cacheHit(&man)) {662 if (try step.cacheHit(&man) and !has_side_effects) {
584 // cache hit, skip running command663 // cache hit, skip running command
585 const digest = man.final();664 const digest = man.final();
586665
587 try populateGeneratedPaths(666 try populateGeneratedPaths(
588 arena,667 arena,
589 output_placeholders.items,668 output_placeholders.items,
590 self.captured_stdout,669 run.captured_stdout,
591 self.captured_stderr,670 run.captured_stderr,
592 b.cache_root,671 b.cache_root,
593 &digest,672 &digest,
594 );673 );
...@@ -597,13 +676,54 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -597,13 +676,54 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
597 return;676 return;
598 }677 }
599678
679 const dep_output_file = run.dep_output_file orelse {
680 // We already know the final output paths, use them directly.
681 const digest = man.final();
682
683 try populateGeneratedPaths(
684 arena,
685 output_placeholders.items,
686 run.captured_stdout,
687 run.captured_stderr,
688 b.cache_root,
689 &digest,
690 );
691
692 const output_dir_path = "o" ++ fs.path.sep_str ++ &digest;
693 for (output_placeholders.items) |placeholder| {
694 const output_sub_path = b.pathJoin(&.{ output_dir_path, placeholder.output.basename });
695 const output_sub_dir_path = switch (placeholder.tag) {
696 .output_file => fs.path.dirname(output_sub_path).?,
697 .output_directory => output_sub_path,
698 else => unreachable,
699 };
700 b.cache_root.handle.makePath(output_sub_dir_path) catch |err| {
701 return step.fail("unable to make path '{}{s}': {s}", .{
702 b.cache_root, output_sub_dir_path, @errorName(err),
703 });
704 };
705 const output_path = placeholder.output.generated_file.path.?;
706 argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0)
707 output_path
708 else
709 b.fmt("{s}{s}", .{ placeholder.output.prefix, output_path });
710 }
711
712 return runCommand(run, argv_list.items, has_side_effects, output_dir_path, prog_node);
713 };
714
715 // We do not know the final output paths yet, use temp paths to run the command.
600 const rand_int = std.crypto.random.int(u64);716 const rand_int = std.crypto.random.int(u64);
601 const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.Build.hex64(rand_int);717 const tmp_dir_path = "tmp" ++ fs.path.sep_str ++ std.Build.hex64(rand_int);
602718
603 for (output_placeholders.items) |placeholder| {719 for (output_placeholders.items) |placeholder| {
604 const output_components = .{ tmp_dir_path, placeholder.output.basename };720 const output_components = .{ tmp_dir_path, placeholder.output.basename };
605 const output_sub_path = try fs.path.join(arena, &output_components);721 const output_sub_path = b.pathJoin(&output_components);
606 const output_sub_dir_path = fs.path.dirname(output_sub_path).?;722 const output_sub_dir_path = switch (placeholder.tag) {
723 .output_file => fs.path.dirname(output_sub_path).?,
724 .output_directory => output_sub_path,
725 else => unreachable,
726 };
607 b.cache_root.handle.makePath(output_sub_dir_path) catch |err| {727 b.cache_root.handle.makePath(output_sub_dir_path) catch |err| {
608 return step.fail("unable to make path '{}{s}': {s}", .{728 return step.fail("unable to make path '{}{s}': {s}", .{
609 b.cache_root, output_sub_dir_path, @errorName(err),729 b.cache_root, output_sub_dir_path, @errorName(err),
...@@ -611,22 +731,20 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -611,22 +731,20 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
611 };731 };
612 const output_path = try b.cache_root.join(arena, &output_components);732 const output_path = try b.cache_root.join(arena, &output_components);
613 placeholder.output.generated_file.path = output_path;733 placeholder.output.generated_file.path = output_path;
614 const cli_arg = if (placeholder.output.prefix.len == 0)734 argv_list.items[placeholder.index] = if (placeholder.output.prefix.len == 0)
615 output_path735 output_path
616 else736 else
617 b.fmt("{s}{s}", .{ placeholder.output.prefix, output_path });737 b.fmt("{s}{s}", .{ placeholder.output.prefix, output_path });
618 argv_list.items[placeholder.index] = cli_arg;
619 }738 }
620739
621 try runCommand(self, argv_list.items, has_side_effects, tmp_dir_path, prog_node);740 try runCommand(run, argv_list.items, has_side_effects, tmp_dir_path, prog_node);
622741
623 if (self.dep_output_file) |dep_output_file|742 try man.addDepFilePost(std.fs.cwd(), dep_output_file.generated_file.getPath());
624 try man.addDepFilePost(std.fs.cwd(), dep_output_file.generated_file.getPath());
625743
626 const digest = man.final();744 const digest = man.final();
627745
628 const any_output = output_placeholders.items.len > 0 or746 const any_output = output_placeholders.items.len > 0 or
629 self.captured_stdout != null or self.captured_stderr != null;747 run.captured_stdout != null or run.captured_stderr != null;
630748
631 // Rename into place749 // Rename into place
632 if (any_output) {750 if (any_output) {
...@@ -663,8 +781,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -663,8 +781,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
663 try populateGeneratedPaths(781 try populateGeneratedPaths(
664 arena,782 arena,
665 output_placeholders.items,783 output_placeholders.items,
666 self.captured_stdout,784 run.captured_stdout,
667 self.captured_stderr,785 run.captured_stderr,
668 b.cache_root,786 b.cache_root,
669 &digest,787 &digest,
670 );788 );
...@@ -743,30 +861,30 @@ fn termMatches(expected: ?std.process.Child.Term, actual: std.process.Child.Term...@@ -743,30 +861,30 @@ fn termMatches(expected: ?std.process.Child.Term, actual: std.process.Child.Term
743}861}
744862
745fn runCommand(863fn runCommand(
746 self: *Run,864 run: *Run,
747 argv: []const []const u8,865 argv: []const []const u8,
748 has_side_effects: bool,866 has_side_effects: bool,
749 tmp_dir_path: ?[]const u8,867 output_dir_path: []const u8,
750 prog_node: *std.Progress.Node,868 prog_node: *std.Progress.Node,
751) !void {869) !void {
752 const step = &self.step;870 const step = &run.step;
753 const b = step.owner;871 const b = step.owner;
754 const arena = b.allocator;872 const arena = b.allocator;
755873
756 const cwd: ?[]const u8 = if (self.cwd) |lazy_cwd| lazy_cwd.getPath(b) else null;874 const cwd: ?[]const u8 = if (run.cwd) |lazy_cwd| lazy_cwd.getPath2(b, step) else null;
757875
758 try step.handleChildProcUnsupported(cwd, argv);876 try step.handleChildProcUnsupported(cwd, argv);
759 try Step.handleVerbose2(step.owner, cwd, self.env_map, argv);877 try Step.handleVerbose2(step.owner, cwd, run.env_map, argv);
760878
761 const allow_skip = switch (self.stdio) {879 const allow_skip = switch (run.stdio) {
762 .check, .zig_test => self.skip_foreign_checks,880 .check, .zig_test => run.skip_foreign_checks,
763 else => false,881 else => false,
764 };882 };
765883
766 var interp_argv = std.ArrayList([]const u8).init(b.allocator);884 var interp_argv = std.ArrayList([]const u8).init(b.allocator);
767 defer interp_argv.deinit();885 defer interp_argv.deinit();
768886
769 const result = spawnChildAndCollect(self, argv, has_side_effects, prog_node) catch |err| term: {887 const result = spawnChildAndCollect(run, argv, has_side_effects, prog_node) catch |err| term: {
770 // InvalidExe: cpu arch mismatch888 // InvalidExe: cpu arch mismatch
771 // FileNotFound: can happen with a wrong dynamic linker path889 // FileNotFound: can happen with a wrong dynamic linker path
772 if (err == error.InvalidExe or err == error.FileNotFound) interpret: {890 if (err == error.InvalidExe or err == error.FileNotFound) interpret: {
...@@ -774,7 +892,7 @@ fn runCommand(...@@ -774,7 +892,7 @@ fn runCommand(
774 // relying on it being a Compile step. This will make this logic892 // relying on it being a Compile step. This will make this logic
775 // work even for the edge case that the binary was produced by a893 // work even for the edge case that the binary was produced by a
776 // third party.894 // third party.
777 const exe = switch (self.argv.items[0]) {895 const exe = switch (run.argv.items[0]) {
778 .artifact => |exe| exe,896 .artifact => |exe| exe,
779 else => break :interpret,897 else => break :interpret,
780 };898 };
...@@ -799,14 +917,14 @@ fn runCommand(...@@ -799,14 +917,14 @@ fn runCommand(
799 try interp_argv.append(bin_name);917 try interp_argv.append(bin_name);
800 try interp_argv.appendSlice(argv);918 try interp_argv.appendSlice(argv);
801 } else {919 } else {
802 return failForeign(self, "-fwine", argv[0], exe);920 return failForeign(run, "-fwine", argv[0], exe);
803 }921 }
804 },922 },
805 .qemu => |bin_name| {923 .qemu => |bin_name| {
806 if (b.enable_qemu) {924 if (b.enable_qemu) {
807 const glibc_dir_arg = if (need_cross_glibc)925 const glibc_dir_arg = if (need_cross_glibc)
808 b.glibc_runtimes_dir orelse926 b.glibc_runtimes_dir orelse
809 return failForeign(self, "--glibc-runtimes", argv[0], exe)927 return failForeign(run, "--glibc-runtimes", argv[0], exe)
810 else928 else
811 null;929 null;
812930
...@@ -834,7 +952,7 @@ fn runCommand(...@@ -834,7 +952,7 @@ fn runCommand(
834952
835 try interp_argv.appendSlice(argv);953 try interp_argv.appendSlice(argv);
836 } else {954 } else {
837 return failForeign(self, "-fqemu", argv[0], exe);955 return failForeign(run, "-fqemu", argv[0], exe);
838 }956 }
839 },957 },
840 .darling => |bin_name| {958 .darling => |bin_name| {
...@@ -842,7 +960,7 @@ fn runCommand(...@@ -842,7 +960,7 @@ fn runCommand(
842 try interp_argv.append(bin_name);960 try interp_argv.append(bin_name);
843 try interp_argv.appendSlice(argv);961 try interp_argv.appendSlice(argv);
844 } else {962 } else {
845 return failForeign(self, "-fdarling", argv[0], exe);963 return failForeign(run, "-fdarling", argv[0], exe);
846 }964 }
847 },965 },
848 .wasmtime => |bin_name| {966 .wasmtime => |bin_name| {
...@@ -853,7 +971,7 @@ fn runCommand(...@@ -853,7 +971,7 @@ fn runCommand(
853 try interp_argv.append("--");971 try interp_argv.append("--");
854 try interp_argv.appendSlice(argv[1..]);972 try interp_argv.appendSlice(argv[1..]);
855 } else {973 } else {
856 return failForeign(self, "-fwasmtime", argv[0], exe);974 return failForeign(run, "-fwasmtime", argv[0], exe);
857 }975 }
858 },976 },
859 .bad_dl => |foreign_dl| {977 .bad_dl => |foreign_dl| {
...@@ -882,13 +1000,13 @@ fn runCommand(...@@ -882,13 +1000,13 @@ fn runCommand(
8821000
883 if (exe.rootModuleTarget().os.tag == .windows) {1001 if (exe.rootModuleTarget().os.tag == .windows) {
884 // On Windows we don't have rpaths so we have to add .dll search paths to PATH1002 // On Windows we don't have rpaths so we have to add .dll search paths to PATH
885 self.addPathForDynLibs(exe);1003 run.addPathForDynLibs(exe);
886 }1004 }
8871005
888 try Step.handleVerbose2(step.owner, cwd, self.env_map, interp_argv.items);1006 try Step.handleVerbose2(step.owner, cwd, run.env_map, interp_argv.items);
8891007
890 break :term spawnChildAndCollect(self, interp_argv.items, has_side_effects, prog_node) catch |e| {1008 break :term spawnChildAndCollect(run, interp_argv.items, has_side_effects, prog_node) catch |e| {
891 if (!self.failing_to_execute_foreign_is_an_error) return error.MakeSkipped;1009 if (!run.failing_to_execute_foreign_is_an_error) return error.MakeSkipped;
8921010
893 return step.fail("unable to spawn interpreter {s}: {s}", .{1011 return step.fail("unable to spawn interpreter {s}: {s}", .{
894 interp_argv.items[0], @errorName(e),1012 interp_argv.items[0], @errorName(e),
...@@ -910,20 +1028,20 @@ fn runCommand(...@@ -910,20 +1028,20 @@ fn runCommand(
910 };1028 };
911 for ([_]Stream{1029 for ([_]Stream{
912 .{1030 .{
913 .captured = self.captured_stdout,1031 .captured = run.captured_stdout,
914 .bytes = result.stdio.stdout,1032 .bytes = result.stdio.stdout,
915 },1033 },
916 .{1034 .{
917 .captured = self.captured_stderr,1035 .captured = run.captured_stderr,
918 .bytes = result.stdio.stderr,1036 .bytes = result.stdio.stderr,
919 },1037 },
920 }) |stream| {1038 }) |stream| {
921 if (stream.captured) |output| {1039 if (stream.captured) |output| {
922 const output_components = .{ tmp_dir_path.?, output.basename };1040 const output_components = .{ output_dir_path, output.basename };
923 const output_path = try b.cache_root.join(arena, &output_components);1041 const output_path = try b.cache_root.join(arena, &output_components);
924 output.generated_file.path = output_path;1042 output.generated_file.path = output_path;
9251043
926 const sub_path = try fs.path.join(arena, &output_components);1044 const sub_path = b.pathJoin(&output_components);
927 const sub_path_dirname = fs.path.dirname(sub_path).?;1045 const sub_path_dirname = fs.path.dirname(sub_path).?;
928 b.cache_root.handle.makePath(sub_path_dirname) catch |err| {1046 b.cache_root.handle.makePath(sub_path_dirname) catch |err| {
929 return step.fail("unable to make path '{}{s}': {s}", .{1047 return step.fail("unable to make path '{}{s}': {s}", .{
...@@ -940,7 +1058,7 @@ fn runCommand(...@@ -940,7 +1058,7 @@ fn runCommand(
9401058
941 const final_argv = if (interp_argv.items.len == 0) argv else interp_argv.items;1059 const final_argv = if (interp_argv.items.len == 0) argv else interp_argv.items;
9421060
943 switch (self.stdio) {1061 switch (run.stdio) {
944 .check => |checks| for (checks.items) |check| switch (check) {1062 .check => |checks| for (checks.items) |check| switch (check) {
945 .expect_stderr_exact => |expected_bytes| {1063 .expect_stderr_exact => |expected_bytes| {
946 if (!mem.eql(u8, expected_bytes, result.stdio.stderr.?)) {1064 if (!mem.eql(u8, expected_bytes, result.stdio.stderr.?)) {
...@@ -1061,56 +1179,56 @@ const ChildProcResult = struct {...@@ -1061,56 +1179,56 @@ const ChildProcResult = struct {
1061};1179};
10621180
1063fn spawnChildAndCollect(1181fn spawnChildAndCollect(
1064 self: *Run,1182 run: *Run,
1065 argv: []const []const u8,1183 argv: []const []const u8,
1066 has_side_effects: bool,1184 has_side_effects: bool,
1067 prog_node: *std.Progress.Node,1185 prog_node: *std.Progress.Node,
1068) !ChildProcResult {1186) !ChildProcResult {
1069 const b = self.step.owner;1187 const b = run.step.owner;
1070 const arena = b.allocator;1188 const arena = b.allocator;
10711189
1072 var child = std.process.Child.init(argv, arena);1190 var child = std.process.Child.init(argv, arena);
1073 if (self.cwd) |lazy_cwd| {1191 if (run.cwd) |lazy_cwd| {
1074 child.cwd = lazy_cwd.getPath(b);1192 child.cwd = lazy_cwd.getPath2(b, &run.step);
1075 } else {1193 } else {
1076 child.cwd = b.build_root.path;1194 child.cwd = b.build_root.path;
1077 child.cwd_dir = b.build_root.handle;1195 child.cwd_dir = b.build_root.handle;
1078 }1196 }
1079 child.env_map = self.env_map orelse &b.graph.env_map;1197 child.env_map = run.env_map orelse &b.graph.env_map;
1080 child.request_resource_usage_statistics = true;1198 child.request_resource_usage_statistics = true;
10811199
1082 child.stdin_behavior = switch (self.stdio) {1200 child.stdin_behavior = switch (run.stdio) {
1083 .infer_from_args => if (has_side_effects) .Inherit else .Ignore,1201 .infer_from_args => if (has_side_effects) .Inherit else .Ignore,
1084 .inherit => .Inherit,1202 .inherit => .Inherit,
1085 .check => .Ignore,1203 .check => .Ignore,
1086 .zig_test => .Pipe,1204 .zig_test => .Pipe,
1087 };1205 };
1088 child.stdout_behavior = switch (self.stdio) {1206 child.stdout_behavior = switch (run.stdio) {
1089 .infer_from_args => if (has_side_effects) .Inherit else .Ignore,1207 .infer_from_args => if (has_side_effects) .Inherit else .Ignore,
1090 .inherit => .Inherit,1208 .inherit => .Inherit,
1091 .check => |checks| if (checksContainStdout(checks.items)) .Pipe else .Ignore,1209 .check => |checks| if (checksContainStdout(checks.items)) .Pipe else .Ignore,
1092 .zig_test => .Pipe,1210 .zig_test => .Pipe,
1093 };1211 };
1094 child.stderr_behavior = switch (self.stdio) {1212 child.stderr_behavior = switch (run.stdio) {
1095 .infer_from_args => if (has_side_effects) .Inherit else .Pipe,1213 .infer_from_args => if (has_side_effects) .Inherit else .Pipe,
1096 .inherit => .Inherit,1214 .inherit => .Inherit,
1097 .check => .Pipe,1215 .check => .Pipe,
1098 .zig_test => .Pipe,1216 .zig_test => .Pipe,
1099 };1217 };
1100 if (self.captured_stdout != null) child.stdout_behavior = .Pipe;1218 if (run.captured_stdout != null) child.stdout_behavior = .Pipe;
1101 if (self.captured_stderr != null) child.stderr_behavior = .Pipe;1219 if (run.captured_stderr != null) child.stderr_behavior = .Pipe;
1102 if (self.stdin != .none) {1220 if (run.stdin != .none) {
1103 assert(self.stdio != .inherit);1221 assert(run.stdio != .inherit);
1104 child.stdin_behavior = .Pipe;1222 child.stdin_behavior = .Pipe;
1105 }1223 }
11061224
1107 try child.spawn();1225 try child.spawn();
1108 var timer = try std.time.Timer.start();1226 var timer = try std.time.Timer.start();
11091227
1110 const result = if (self.stdio == .zig_test)1228 const result = if (run.stdio == .zig_test)
1111 evalZigTest(self, &child, prog_node)1229 evalZigTest(run, &child, prog_node)
1112 else1230 else
1113 evalGeneric(self, &child);1231 evalGeneric(run, &child);
11141232
1115 const term = try child.wait();1233 const term = try child.wait();
1116 const elapsed_ns = timer.read();1234 const elapsed_ns = timer.read();
...@@ -1131,12 +1249,12 @@ const StdIoResult = struct {...@@ -1131,12 +1249,12 @@ const StdIoResult = struct {
1131};1249};
11321250
1133fn evalZigTest(1251fn evalZigTest(
1134 self: *Run,1252 run: *Run,
1135 child: *std.process.Child,1253 child: *std.process.Child,
1136 prog_node: *std.Progress.Node,1254 prog_node: *std.Progress.Node,
1137) !StdIoResult {1255) !StdIoResult {
1138 const gpa = self.step.owner.allocator;1256 const gpa = run.step.owner.allocator;
1139 const arena = self.step.owner.allocator;1257 const arena = run.step.owner.allocator;
11401258
1141 var poller = std.io.poll(gpa, enum { stdout, stderr }, .{1259 var poller = std.io.poll(gpa, enum { stdout, stderr }, .{
1142 .stdout = child.stdout.?,1260 .stdout = child.stdout.?,
...@@ -1175,7 +1293,7 @@ fn evalZigTest(...@@ -1175,7 +1293,7 @@ fn evalZigTest(
1175 switch (header.tag) {1293 switch (header.tag) {
1176 .zig_version => {1294 .zig_version => {
1177 if (!std.mem.eql(u8, builtin.zig_version_string, body)) {1295 if (!std.mem.eql(u8, builtin.zig_version_string, body)) {
1178 return self.step.fail(1296 return run.step.fail(
1179 "zig version mismatch build runner vs compiler: '{s}' vs '{s}'",1297 "zig version mismatch build runner vs compiler: '{s}' vs '{s}'",
1180 .{ builtin.zig_version_string, body },1298 .{ builtin.zig_version_string, body },
1181 );1299 );
...@@ -1233,9 +1351,9 @@ fn evalZigTest(...@@ -1233,9 +1351,9 @@ fn evalZigTest(
1233 else1351 else
1234 unreachable;1352 unreachable;
1235 if (msg.len > 0) {1353 if (msg.len > 0) {
1236 try self.step.addError("'{s}' {s}: {s}", .{ name, label, msg });1354 try run.step.addError("'{s}' {s}: {s}", .{ name, label, msg });
1237 } else {1355 } else {
1238 try self.step.addError("'{s}' {s}", .{ name, label });1356 try run.step.addError("'{s}' {s}", .{ name, label });
1239 }1357 }
1240 }1358 }
12411359
...@@ -1249,7 +1367,7 @@ fn evalZigTest(...@@ -1249,7 +1367,7 @@ fn evalZigTest(
12491367
1250 if (stderr.readableLength() > 0) {1368 if (stderr.readableLength() > 0) {
1251 const msg = std.mem.trim(u8, try stderr.toOwnedSlice(), "\n");1369 const msg = std.mem.trim(u8, try stderr.toOwnedSlice(), "\n");
1252 if (msg.len > 0) self.step.result_stderr = msg;1370 if (msg.len > 0) run.step.result_stderr = msg;
1253 }1371 }
12541372
1255 // Send EOF to stdin.1373 // Send EOF to stdin.
...@@ -1317,25 +1435,26 @@ fn sendRunTestMessage(file: std.fs.File, index: u32) !void {...@@ -1317,25 +1435,26 @@ fn sendRunTestMessage(file: std.fs.File, index: u32) !void {
1317 try file.writeAll(full_msg);1435 try file.writeAll(full_msg);
1318}1436}
13191437
1320fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult {1438fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult {
1321 const arena = self.step.owner.allocator;1439 const b = run.step.owner;
1440 const arena = b.allocator;
13221441
1323 switch (self.stdin) {1442 switch (run.stdin) {
1324 .bytes => |bytes| {1443 .bytes => |bytes| {
1325 child.stdin.?.writeAll(bytes) catch |err| {1444 child.stdin.?.writeAll(bytes) catch |err| {
1326 return self.step.fail("unable to write stdin: {s}", .{@errorName(err)});1445 return run.step.fail("unable to write stdin: {s}", .{@errorName(err)});
1327 };1446 };
1328 child.stdin.?.close();1447 child.stdin.?.close();
1329 child.stdin = null;1448 child.stdin = null;
1330 },1449 },
1331 .lazy_path => |lazy_path| {1450 .lazy_path => |lazy_path| {
1332 const path = lazy_path.getPath(self.step.owner);1451 const path = lazy_path.getPath2(b, &run.step);
1333 const file = self.step.owner.build_root.handle.openFile(path, .{}) catch |err| {1452 const file = b.build_root.handle.openFile(path, .{}) catch |err| {
1334 return self.step.fail("unable to open stdin file: {s}", .{@errorName(err)});1453 return run.step.fail("unable to open stdin file: {s}", .{@errorName(err)});
1335 };1454 };
1336 defer file.close();1455 defer file.close();
1337 child.stdin.?.writeFileAll(file, .{}) catch |err| {1456 child.stdin.?.writeFileAll(file, .{}) catch |err| {
1338 return self.step.fail("unable to write file to stdin: {s}", .{@errorName(err)});1457 return run.step.fail("unable to write file to stdin: {s}", .{@errorName(err)});
1339 };1458 };
1340 child.stdin.?.close();1459 child.stdin.?.close();
1341 child.stdin = null;1460 child.stdin = null;
...@@ -1355,29 +1474,29 @@ fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult {...@@ -1355,29 +1474,29 @@ fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult {
1355 defer poller.deinit();1474 defer poller.deinit();
13561475
1357 while (try poller.poll()) {1476 while (try poller.poll()) {
1358 if (poller.fifo(.stdout).count > self.max_stdio_size)1477 if (poller.fifo(.stdout).count > run.max_stdio_size)
1359 return error.StdoutStreamTooLong;1478 return error.StdoutStreamTooLong;
1360 if (poller.fifo(.stderr).count > self.max_stdio_size)1479 if (poller.fifo(.stderr).count > run.max_stdio_size)
1361 return error.StderrStreamTooLong;1480 return error.StderrStreamTooLong;
1362 }1481 }
13631482
1364 stdout_bytes = try poller.fifo(.stdout).toOwnedSlice();1483 stdout_bytes = try poller.fifo(.stdout).toOwnedSlice();
1365 stderr_bytes = try poller.fifo(.stderr).toOwnedSlice();1484 stderr_bytes = try poller.fifo(.stderr).toOwnedSlice();
1366 } else {1485 } else {
1367 stdout_bytes = try stdout.reader().readAllAlloc(arena, self.max_stdio_size);1486 stdout_bytes = try stdout.reader().readAllAlloc(arena, run.max_stdio_size);
1368 }1487 }
1369 } else if (child.stderr) |stderr| {1488 } else if (child.stderr) |stderr| {
1370 stderr_bytes = try stderr.reader().readAllAlloc(arena, self.max_stdio_size);1489 stderr_bytes = try stderr.reader().readAllAlloc(arena, run.max_stdio_size);
1371 }1490 }
13721491
1373 if (stderr_bytes) |bytes| if (bytes.len > 0) {1492 if (stderr_bytes) |bytes| if (bytes.len > 0) {
1374 // Treat stderr as an error message.1493 // Treat stderr as an error message.
1375 const stderr_is_diagnostic = self.captured_stderr == null and switch (self.stdio) {1494 const stderr_is_diagnostic = run.captured_stderr == null and switch (run.stdio) {
1376 .check => |checks| !checksContainStderr(checks.items),1495 .check => |checks| !checksContainStderr(checks.items),
1377 else => true,1496 else => true,
1378 };1497 };
1379 if (stderr_is_diagnostic) {1498 if (stderr_is_diagnostic) {
1380 self.step.result_stderr = bytes;1499 run.step.result_stderr = bytes;
1381 }1500 }
1382 };1501 };
13831502
...@@ -1389,8 +1508,8 @@ fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult {...@@ -1389,8 +1508,8 @@ fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult {
1389 };1508 };
1390}1509}
13911510
1392fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void {1511fn addPathForDynLibs(run: *Run, artifact: *Step.Compile) void {
1393 const b = self.step.owner;1512 const b = run.step.owner;
1394 var it = artifact.root_module.iterateDependencies(artifact, true);1513 var it = artifact.root_module.iterateDependencies(artifact, true);
1395 while (it.next()) |item| {1514 while (it.next()) |item| {
1396 const other = item.compile.?;1515 const other = item.compile.?;
...@@ -1398,34 +1517,34 @@ fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void {...@@ -1398,34 +1517,34 @@ fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void {
1398 if (item.module.resolved_target.?.result.os.tag == .windows and1517 if (item.module.resolved_target.?.result.os.tag == .windows and
1399 other.isDynamicLibrary())1518 other.isDynamicLibrary())
1400 {1519 {
1401 addPathDir(self, fs.path.dirname(other.getEmittedBin().getPath(b)).?);1520 addPathDir(run, fs.path.dirname(other.getEmittedBin().getPath2(b, &run.step)).?);
1402 }1521 }
1403 }1522 }
1404 }1523 }
1405}1524}
14061525
1407fn failForeign(1526fn failForeign(
1408 self: *Run,1527 run: *Run,
1409 suggested_flag: []const u8,1528 suggested_flag: []const u8,
1410 argv0: []const u8,1529 argv0: []const u8,
1411 exe: *Step.Compile,1530 exe: *Step.Compile,
1412) error{ MakeFailed, MakeSkipped, OutOfMemory } {1531) error{ MakeFailed, MakeSkipped, OutOfMemory } {
1413 switch (self.stdio) {1532 switch (run.stdio) {
1414 .check, .zig_test => {1533 .check, .zig_test => {
1415 if (self.skip_foreign_checks)1534 if (run.skip_foreign_checks)
1416 return error.MakeSkipped;1535 return error.MakeSkipped;
14171536
1418 const b = self.step.owner;1537 const b = run.step.owner;
1419 const host_name = try b.host.result.zigTriple(b.allocator);1538 const host_name = try b.host.result.zigTriple(b.allocator);
1420 const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator);1539 const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator);
14211540
1422 return self.step.fail(1541 return run.step.fail(
1423 \\unable to spawn foreign binary '{s}' ({s}) on host system ({s})1542 \\unable to spawn foreign binary '{s}' ({s}) on host system ({s})
1424 \\ consider using {s} or enabling skip_foreign_checks in the Run step1543 \\ consider using {s} or enabling skip_foreign_checks in the Run step
1425 , .{ argv0, foreign_name, host_name, suggested_flag });1544 , .{ argv0, foreign_name, host_name, suggested_flag });
1426 },1545 },
1427 else => {1546 else => {
1428 return self.step.fail("unable to spawn foreign binary '{s}'", .{argv0});1547 return run.step.fail("unable to spawn foreign binary '{s}'", .{argv0});
1429 },1548 },
1430 }1549 }
1431}1550}
lib/std/Build/Step/TranslateC.zig+42-45
...@@ -5,7 +5,7 @@ const mem = std.mem;...@@ -5,7 +5,7 @@ const mem = std.mem;
55
6const TranslateC = @This();6const TranslateC = @This();
77
8pub const base_id = .translate_c;8pub const base_id: Step.Id = .translate_c;
99
10step: Step,10step: Step,
11source: std.Build.LazyPath,11source: std.Build.LazyPath,
...@@ -27,11 +27,11 @@ pub const Options = struct {...@@ -27,11 +27,11 @@ pub const Options = struct {
27};27};
2828
29pub fn create(owner: *std.Build, options: Options) *TranslateC {29pub fn create(owner: *std.Build, options: Options) *TranslateC {
30 const self = owner.allocator.create(TranslateC) catch @panic("OOM");30 const translate_c = owner.allocator.create(TranslateC) catch @panic("OOM");
31 const source = options.root_source_file.dupe(owner);31 const source = options.root_source_file.dupe(owner);
32 self.* = TranslateC{32 translate_c.* = TranslateC{
33 .step = Step.init(.{33 .step = Step.init(.{
34 .id = .translate_c,34 .id = base_id,
35 .name = "translate-c",35 .name = "translate-c",
36 .owner = owner,36 .owner = owner,
37 .makeFn = make,37 .makeFn = make,
...@@ -42,12 +42,12 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC {...@@ -42,12 +42,12 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC {
42 .out_basename = undefined,42 .out_basename = undefined,
43 .target = options.target,43 .target = options.target,
44 .optimize = options.optimize,44 .optimize = options.optimize,
45 .output_file = std.Build.GeneratedFile{ .step = &self.step },45 .output_file = std.Build.GeneratedFile{ .step = &translate_c.step },
46 .link_libc = options.link_libc,46 .link_libc = options.link_libc,
47 .use_clang = options.use_clang,47 .use_clang = options.use_clang,
48 };48 };
49 source.addStepDependencies(&self.step);49 source.addStepDependencies(&translate_c.step);
50 return self;50 return translate_c;
51}51}
5252
53pub const AddExecutableOptions = struct {53pub const AddExecutableOptions = struct {
...@@ -58,18 +58,18 @@ pub const AddExecutableOptions = struct {...@@ -58,18 +58,18 @@ pub const AddExecutableOptions = struct {
58 linkage: ?std.builtin.LinkMode = null,58 linkage: ?std.builtin.LinkMode = null,
59};59};
6060
61pub fn getOutput(self: *TranslateC) std.Build.LazyPath {61pub fn getOutput(translate_c: *TranslateC) std.Build.LazyPath {
62 return .{ .generated = &self.output_file };62 return .{ .generated = .{ .file = &translate_c.output_file } };
63}63}
6464
65/// Creates a step to build an executable from the translated source.65/// Creates a step to build an executable from the translated source.
66pub fn addExecutable(self: *TranslateC, options: AddExecutableOptions) *Step.Compile {66pub fn addExecutable(translate_c: *TranslateC, options: AddExecutableOptions) *Step.Compile {
67 return self.step.owner.addExecutable(.{67 return translate_c.step.owner.addExecutable(.{
68 .root_source_file = self.getOutput(),68 .root_source_file = translate_c.getOutput(),
69 .name = options.name orelse "translated_c",69 .name = options.name orelse "translated_c",
70 .version = options.version,70 .version = options.version,
71 .target = options.target orelse self.target,71 .target = options.target orelse translate_c.target,
72 .optimize = options.optimize orelse self.optimize,72 .optimize = options.optimize orelse translate_c.optimize,
73 .linkage = options.linkage,73 .linkage = options.linkage,
74 });74 });
75}75}
...@@ -77,90 +77,87 @@ pub fn addExecutable(self: *TranslateC, options: AddExecutableOptions) *Step.Com...@@ -77,90 +77,87 @@ pub fn addExecutable(self: *TranslateC, options: AddExecutableOptions) *Step.Com
77/// Creates a module from the translated source and adds it to the package's77/// Creates a module from the translated source and adds it to the package's
78/// module set making it available to other packages which depend on this one.78/// module set making it available to other packages which depend on this one.
79/// `createModule` can be used instead to create a private module.79/// `createModule` can be used instead to create a private module.
80pub fn addModule(self: *TranslateC, name: []const u8) *std.Build.Module {80pub fn addModule(translate_c: *TranslateC, name: []const u8) *std.Build.Module {
81 return self.step.owner.addModule(name, .{81 return translate_c.step.owner.addModule(name, .{
82 .root_source_file = self.getOutput(),82 .root_source_file = translate_c.getOutput(),
83 });83 });
84}84}
8585
86/// Creates a private module from the translated source to be used by the86/// Creates a private module from the translated source to be used by the
87/// current package, but not exposed to other packages depending on this one.87/// current package, but not exposed to other packages depending on this one.
88/// `addModule` can be used instead to create a public module.88/// `addModule` can be used instead to create a public module.
89pub fn createModule(self: *TranslateC) *std.Build.Module {89pub fn createModule(translate_c: *TranslateC) *std.Build.Module {
90 return self.step.owner.createModule(.{90 return translate_c.step.owner.createModule(.{
91 .root_source_file = self.getOutput(),91 .root_source_file = translate_c.getOutput(),
92 });92 });
93}93}
9494
95pub fn addIncludeDir(self: *TranslateC, include_dir: []const u8) void {95pub fn addIncludeDir(translate_c: *TranslateC, include_dir: []const u8) void {
96 self.include_dirs.append(self.step.owner.dupePath(include_dir)) catch @panic("OOM");96 translate_c.include_dirs.append(translate_c.step.owner.dupePath(include_dir)) catch @panic("OOM");
97}97}
9898
99pub fn addCheckFile(self: *TranslateC, expected_matches: []const []const u8) *Step.CheckFile {99pub fn addCheckFile(translate_c: *TranslateC, expected_matches: []const []const u8) *Step.CheckFile {
100 return Step.CheckFile.create(100 return Step.CheckFile.create(
101 self.step.owner,101 translate_c.step.owner,
102 self.getOutput(),102 translate_c.getOutput(),
103 .{ .expected_matches = expected_matches },103 .{ .expected_matches = expected_matches },
104 );104 );
105}105}
106106
107/// If the value is omitted, it is set to 1.107/// If the value is omitted, it is set to 1.
108/// `name` and `value` need not live longer than the function call.108/// `name` and `value` need not live longer than the function call.
109pub fn defineCMacro(self: *TranslateC, name: []const u8, value: ?[]const u8) void {109pub fn defineCMacro(translate_c: *TranslateC, name: []const u8, value: ?[]const u8) void {
110 const macro = std.Build.constructCMacro(self.step.owner.allocator, name, value);110 const macro = std.Build.constructranslate_cMacro(translate_c.step.owner.allocator, name, value);
111 self.c_macros.append(macro) catch @panic("OOM");111 translate_c.c_macros.append(macro) catch @panic("OOM");
112}112}
113113
114/// name_and_value looks like [name]=[value]. If the value is omitted, it is set to 1.114/// name_and_value looks like [name]=[value]. If the value is omitted, it is set to 1.
115pub fn defineCMacroRaw(self: *TranslateC, name_and_value: []const u8) void {115pub fn defineCMacroRaw(translate_c: *TranslateC, name_and_value: []const u8) void {
116 self.c_macros.append(self.step.owner.dupe(name_and_value)) catch @panic("OOM");116 translate_c.c_macros.append(translate_c.step.owner.dupe(name_and_value)) catch @panic("OOM");
117}117}
118118
119fn make(step: *Step, prog_node: *std.Progress.Node) !void {119fn make(step: *Step, prog_node: *std.Progress.Node) !void {
120 const b = step.owner;120 const b = step.owner;
121 const self: *TranslateC = @fieldParentPtr("step", step);121 const translate_c: *TranslateC = @fieldParentPtr("step", step);
122122
123 var argv_list = std.ArrayList([]const u8).init(b.allocator);123 var argv_list = std.ArrayList([]const u8).init(b.allocator);
124 try argv_list.append(b.graph.zig_exe);124 try argv_list.append(b.graph.zig_exe);
125 try argv_list.append("translate-c");125 try argv_list.append("translate-c");
126 if (self.link_libc) {126 if (translate_c.link_libc) {
127 try argv_list.append("-lc");127 try argv_list.append("-lc");
128 }128 }
129 if (!self.use_clang) {129 if (!translate_c.use_clang) {
130 try argv_list.append("-fno-clang");130 try argv_list.append("-fno-clang");
131 }131 }
132132
133 try argv_list.append("--listen=-");133 try argv_list.append("--listen=-");
134134
135 if (!self.target.query.isNative()) {135 if (!translate_c.target.query.isNative()) {
136 try argv_list.append("-target");136 try argv_list.append("-target");
137 try argv_list.append(try self.target.query.zigTriple(b.allocator));137 try argv_list.append(try translate_c.target.query.zigTriple(b.allocator));
138 }138 }
139139
140 switch (self.optimize) {140 switch (translate_c.optimize) {
141 .Debug => {}, // Skip since it's the default.141 .Debug => {}, // Skip since it's the default.
142 else => try argv_list.append(b.fmt("-O{s}", .{@tagName(self.optimize)})),142 else => try argv_list.append(b.fmt("-O{s}", .{@tagName(translate_c.optimize)})),
143 }143 }
144144
145 for (self.include_dirs.items) |include_dir| {145 for (translate_c.include_dirs.items) |include_dir| {
146 try argv_list.append("-I");146 try argv_list.append("-I");
147 try argv_list.append(include_dir);147 try argv_list.append(include_dir);
148 }148 }
149149
150 for (self.c_macros.items) |c_macro| {150 for (translate_c.c_macros.items) |c_macro| {
151 try argv_list.append("-D");151 try argv_list.append("-D");
152 try argv_list.append(c_macro);152 try argv_list.append(c_macro);
153 }153 }
154154
155 try argv_list.append(self.source.getPath(b));155 try argv_list.append(translate_c.source.getPath2(b, step));
156156
157 const output_path = try step.evalZigProcess(argv_list.items, prog_node);157 const output_path = try step.evalZigProcess(argv_list.items, prog_node);
158158
159 self.out_basename = fs.path.basename(output_path.?);159 translate_c.out_basename = fs.path.basename(output_path.?);
160 const output_dir = fs.path.dirname(output_path.?).?;160 const output_dir = fs.path.dirname(output_path.?).?;
161161
162 self.output_file.path = try fs.path.join(162 translate_c.output_file.path = b.pathJoin(&.{ output_dir, translate_c.out_basename });
163 b.allocator,
164 &[_][]const u8{ output_dir, self.out_basename },
165 );
166}163}
lib/std/Build/Step/WriteFile.zig+58-58
...@@ -23,15 +23,15 @@ directories: std.ArrayListUnmanaged(*Directory),...@@ -23,15 +23,15 @@ directories: std.ArrayListUnmanaged(*Directory),
23output_source_files: std.ArrayListUnmanaged(OutputSourceFile),23output_source_files: std.ArrayListUnmanaged(OutputSourceFile),
24generated_directory: std.Build.GeneratedFile,24generated_directory: std.Build.GeneratedFile,
2525
26pub const base_id = .write_file;26pub const base_id: Step.Id = .write_file;
2727
28pub const File = struct {28pub const File = struct {
29 generated_file: std.Build.GeneratedFile,29 generated_file: std.Build.GeneratedFile,
30 sub_path: []const u8,30 sub_path: []const u8,
31 contents: Contents,31 contents: Contents,
3232
33 pub fn getPath(self: *File) std.Build.LazyPath {33 pub fn getPath(file: *File) std.Build.LazyPath {
34 return .{ .generated = &self.generated_file };34 return .{ .generated = .{ .file = &file.generated_file } };
35 }35 }
36};36};
3737
...@@ -49,16 +49,16 @@ pub const Directory = struct {...@@ -49,16 +49,16 @@ pub const Directory = struct {
49 /// `exclude_extensions` takes precedence over `include_extensions`.49 /// `exclude_extensions` takes precedence over `include_extensions`.
50 include_extensions: ?[]const []const u8 = null,50 include_extensions: ?[]const []const u8 = null,
5151
52 pub fn dupe(self: Options, b: *std.Build) Options {52 pub fn dupe(opts: Options, b: *std.Build) Options {
53 return .{53 return .{
54 .exclude_extensions = b.dupeStrings(self.exclude_extensions),54 .exclude_extensions = b.dupeStrings(opts.exclude_extensions),
55 .include_extensions = if (self.include_extensions) |incs| b.dupeStrings(incs) else null,55 .include_extensions = if (opts.include_extensions) |incs| b.dupeStrings(incs) else null,
56 };56 };
57 }57 }
58 };58 };
5959
60 pub fn getPath(self: *Directory) std.Build.LazyPath {60 pub fn getPath(dir: *Directory) std.Build.LazyPath {
61 return .{ .generated = &self.generated_dir };61 return .{ .generated = .{ .file = &dir.generated_dir } };
62 }62 }
63};63};
6464
...@@ -73,10 +73,10 @@ pub const Contents = union(enum) {...@@ -73,10 +73,10 @@ pub const Contents = union(enum) {
73};73};
7474
75pub fn create(owner: *std.Build) *WriteFile {75pub fn create(owner: *std.Build) *WriteFile {
76 const wf = owner.allocator.create(WriteFile) catch @panic("OOM");76 const write_file = owner.allocator.create(WriteFile) catch @panic("OOM");
77 wf.* = .{77 write_file.* = .{
78 .step = Step.init(.{78 .step = Step.init(.{
79 .id = .write_file,79 .id = base_id,
80 .name = "WriteFile",80 .name = "WriteFile",
81 .owner = owner,81 .owner = owner,
82 .makeFn = make,82 .makeFn = make,
...@@ -84,22 +84,22 @@ pub fn create(owner: *std.Build) *WriteFile {...@@ -84,22 +84,22 @@ pub fn create(owner: *std.Build) *WriteFile {
84 .files = .{},84 .files = .{},
85 .directories = .{},85 .directories = .{},
86 .output_source_files = .{},86 .output_source_files = .{},
87 .generated_directory = .{ .step = &wf.step },87 .generated_directory = .{ .step = &write_file.step },
88 };88 };
89 return wf;89 return write_file;
90}90}
9191
92pub fn add(wf: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.LazyPath {92pub fn add(write_file: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.LazyPath {
93 const b = wf.step.owner;93 const b = write_file.step.owner;
94 const gpa = b.allocator;94 const gpa = b.allocator;
95 const file = gpa.create(File) catch @panic("OOM");95 const file = gpa.create(File) catch @panic("OOM");
96 file.* = .{96 file.* = .{
97 .generated_file = .{ .step = &wf.step },97 .generated_file = .{ .step = &write_file.step },
98 .sub_path = b.dupePath(sub_path),98 .sub_path = b.dupePath(sub_path),
99 .contents = .{ .bytes = b.dupe(bytes) },99 .contents = .{ .bytes = b.dupe(bytes) },
100 };100 };
101 wf.files.append(gpa, file) catch @panic("OOM");101 write_file.files.append(gpa, file) catch @panic("OOM");
102 wf.maybeUpdateName();102 write_file.maybeUpdateName();
103 return file.getPath();103 return file.getPath();
104}104}
105105
...@@ -110,19 +110,19 @@ pub fn add(wf: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.La...@@ -110,19 +110,19 @@ pub fn add(wf: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.La
110/// include sub-directories, in which case this step will ensure the110/// include sub-directories, in which case this step will ensure the
111/// required sub-path exists.111/// required sub-path exists.
112/// This is the option expected to be used most commonly with `addCopyFile`.112/// This is the option expected to be used most commonly with `addCopyFile`.
113pub fn addCopyFile(wf: *WriteFile, source: std.Build.LazyPath, sub_path: []const u8) std.Build.LazyPath {113pub fn addCopyFile(write_file: *WriteFile, source: std.Build.LazyPath, sub_path: []const u8) std.Build.LazyPath {
114 const b = wf.step.owner;114 const b = write_file.step.owner;
115 const gpa = b.allocator;115 const gpa = b.allocator;
116 const file = gpa.create(File) catch @panic("OOM");116 const file = gpa.create(File) catch @panic("OOM");
117 file.* = .{117 file.* = .{
118 .generated_file = .{ .step = &wf.step },118 .generated_file = .{ .step = &write_file.step },
119 .sub_path = b.dupePath(sub_path),119 .sub_path = b.dupePath(sub_path),
120 .contents = .{ .copy = source },120 .contents = .{ .copy = source },
121 };121 };
122 wf.files.append(gpa, file) catch @panic("OOM");122 write_file.files.append(gpa, file) catch @panic("OOM");
123123
124 wf.maybeUpdateName();124 write_file.maybeUpdateName();
125 source.addStepDependencies(&wf.step);125 source.addStepDependencies(&write_file.step);
126 return file.getPath();126 return file.getPath();
127}127}
128128
...@@ -130,24 +130,24 @@ pub fn addCopyFile(wf: *WriteFile, source: std.Build.LazyPath, sub_path: []const...@@ -130,24 +130,24 @@ pub fn addCopyFile(wf: *WriteFile, source: std.Build.LazyPath, sub_path: []const
130/// relative to this step's generated directory.130/// relative to this step's generated directory.
131/// The returned value is a lazy path to the generated subdirectory.131/// The returned value is a lazy path to the generated subdirectory.
132pub fn addCopyDirectory(132pub fn addCopyDirectory(
133 wf: *WriteFile,133 write_file: *WriteFile,
134 source: std.Build.LazyPath,134 source: std.Build.LazyPath,
135 sub_path: []const u8,135 sub_path: []const u8,
136 options: Directory.Options,136 options: Directory.Options,
137) std.Build.LazyPath {137) std.Build.LazyPath {
138 const b = wf.step.owner;138 const b = write_file.step.owner;
139 const gpa = b.allocator;139 const gpa = b.allocator;
140 const dir = gpa.create(Directory) catch @panic("OOM");140 const dir = gpa.create(Directory) catch @panic("OOM");
141 dir.* = .{141 dir.* = .{
142 .source = source.dupe(b),142 .source = source.dupe(b),
143 .sub_path = b.dupePath(sub_path),143 .sub_path = b.dupePath(sub_path),
144 .options = options.dupe(b),144 .options = options.dupe(b),
145 .generated_dir = .{ .step = &wf.step },145 .generated_dir = .{ .step = &write_file.step },
146 };146 };
147 wf.directories.append(gpa, dir) catch @panic("OOM");147 write_file.directories.append(gpa, dir) catch @panic("OOM");
148148
149 wf.maybeUpdateName();149 write_file.maybeUpdateName();
150 source.addStepDependencies(&wf.step);150 source.addStepDependencies(&write_file.step);
151 return dir.getPath();151 return dir.getPath();
152}152}
153153
...@@ -156,13 +156,13 @@ pub fn addCopyDirectory(...@@ -156,13 +156,13 @@ pub fn addCopyDirectory(
156/// used as part of the normal build process, but as a utility occasionally156/// used as part of the normal build process, but as a utility occasionally
157/// run by a developer with intent to modify source files and then commit157/// run by a developer with intent to modify source files and then commit
158/// those changes to version control.158/// those changes to version control.
159pub fn addCopyFileToSource(wf: *WriteFile, source: std.Build.LazyPath, sub_path: []const u8) void {159pub fn addCopyFileToSource(write_file: *WriteFile, source: std.Build.LazyPath, sub_path: []const u8) void {
160 const b = wf.step.owner;160 const b = write_file.step.owner;
161 wf.output_source_files.append(b.allocator, .{161 write_file.output_source_files.append(b.allocator, .{
162 .contents = .{ .copy = source },162 .contents = .{ .copy = source },
163 .sub_path = sub_path,163 .sub_path = sub_path,
164 }) catch @panic("OOM");164 }) catch @panic("OOM");
165 source.addStepDependencies(&wf.step);165 source.addStepDependencies(&write_file.step);
166}166}
167167
168/// A path relative to the package root.168/// A path relative to the package root.
...@@ -170,9 +170,9 @@ pub fn addCopyFileToSource(wf: *WriteFile, source: std.Build.LazyPath, sub_path:...@@ -170,9 +170,9 @@ pub fn addCopyFileToSource(wf: *WriteFile, source: std.Build.LazyPath, sub_path:
170/// used as part of the normal build process, but as a utility occasionally170/// used as part of the normal build process, but as a utility occasionally
171/// run by a developer with intent to modify source files and then commit171/// run by a developer with intent to modify source files and then commit
172/// those changes to version control.172/// those changes to version control.
173pub fn addBytesToSource(wf: *WriteFile, bytes: []const u8, sub_path: []const u8) void {173pub fn addBytesToSource(write_file: *WriteFile, bytes: []const u8, sub_path: []const u8) void {
174 const b = wf.step.owner;174 const b = write_file.step.owner;
175 wf.output_source_files.append(b.allocator, .{175 write_file.output_source_files.append(b.allocator, .{
176 .contents = .{ .bytes = bytes },176 .contents = .{ .bytes = bytes },
177 .sub_path = sub_path,177 .sub_path = sub_path,
178 }) catch @panic("OOM");178 }) catch @panic("OOM");
...@@ -180,20 +180,20 @@ pub fn addBytesToSource(wf: *WriteFile, bytes: []const u8, sub_path: []const u8)...@@ -180,20 +180,20 @@ pub fn addBytesToSource(wf: *WriteFile, bytes: []const u8, sub_path: []const u8)
180180
181/// Returns a `LazyPath` representing the base directory that contains all the181/// Returns a `LazyPath` representing the base directory that contains all the
182/// files from this `WriteFile`.182/// files from this `WriteFile`.
183pub fn getDirectory(wf: *WriteFile) std.Build.LazyPath {183pub fn getDirectory(write_file: *WriteFile) std.Build.LazyPath {
184 return .{ .generated = &wf.generated_directory };184 return .{ .generated = .{ .file = &write_file.generated_directory } };
185}185}
186186
187fn maybeUpdateName(wf: *WriteFile) void {187fn maybeUpdateName(write_file: *WriteFile) void {
188 if (wf.files.items.len == 1 and wf.directories.items.len == 0) {188 if (write_file.files.items.len == 1 and write_file.directories.items.len == 0) {
189 // First time adding a file; update name.189 // First time adding a file; update name.
190 if (std.mem.eql(u8, wf.step.name, "WriteFile")) {190 if (std.mem.eql(u8, write_file.step.name, "WriteFile")) {
191 wf.step.name = wf.step.owner.fmt("WriteFile {s}", .{wf.files.items[0].sub_path});191 write_file.step.name = write_file.step.owner.fmt("WriteFile {s}", .{write_file.files.items[0].sub_path});
192 }192 }
193 } else if (wf.directories.items.len == 1 and wf.files.items.len == 0) {193 } else if (write_file.directories.items.len == 1 and write_file.files.items.len == 0) {
194 // First time adding a directory; update name.194 // First time adding a directory; update name.
195 if (std.mem.eql(u8, wf.step.name, "WriteFile")) {195 if (std.mem.eql(u8, write_file.step.name, "WriteFile")) {
196 wf.step.name = wf.step.owner.fmt("WriteFile {s}", .{wf.directories.items[0].sub_path});196 write_file.step.name = write_file.step.owner.fmt("WriteFile {s}", .{write_file.directories.items[0].sub_path});
197 }197 }
198 }198 }
199}199}
...@@ -201,14 +201,14 @@ fn maybeUpdateName(wf: *WriteFile) void {...@@ -201,14 +201,14 @@ fn maybeUpdateName(wf: *WriteFile) void {
201fn make(step: *Step, prog_node: *std.Progress.Node) !void {201fn make(step: *Step, prog_node: *std.Progress.Node) !void {
202 _ = prog_node;202 _ = prog_node;
203 const b = step.owner;203 const b = step.owner;
204 const wf: *WriteFile = @fieldParentPtr("step", step);204 const write_file: *WriteFile = @fieldParentPtr("step", step);
205205
206 // Writing to source files is kind of an extra capability of this206 // Writing to source files is kind of an extra capability of this
207 // WriteFile - arguably it should be a different step. But anyway here207 // WriteFile - arguably it should be a different step. But anyway here
208 // it is, it happens unconditionally and does not interact with the other208 // it is, it happens unconditionally and does not interact with the other
209 // files here.209 // files here.
210 var any_miss = false;210 var any_miss = false;
211 for (wf.output_source_files.items) |output_source_file| {211 for (write_file.output_source_files.items) |output_source_file| {
212 if (fs.path.dirname(output_source_file.sub_path)) |dirname| {212 if (fs.path.dirname(output_source_file.sub_path)) |dirname| {
213 b.build_root.handle.makePath(dirname) catch |err| {213 b.build_root.handle.makePath(dirname) catch |err| {
214 return step.fail("unable to make path '{}{s}': {s}", .{214 return step.fail("unable to make path '{}{s}': {s}", .{
...@@ -226,7 +226,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -226,7 +226,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
226 any_miss = true;226 any_miss = true;
227 },227 },
228 .copy => |file_source| {228 .copy => |file_source| {
229 const source_path = file_source.getPath(b);229 const source_path = file_source.getPath2(b, step);
230 const prev_status = fs.Dir.updateFile(230 const prev_status = fs.Dir.updateFile(
231 fs.cwd(),231 fs.cwd(),
232 source_path,232 source_path,
...@@ -258,18 +258,18 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -258,18 +258,18 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
258 // in a non-backwards-compatible way.258 // in a non-backwards-compatible way.
259 man.hash.add(@as(u32, 0xd767ee59));259 man.hash.add(@as(u32, 0xd767ee59));
260260
261 for (wf.files.items) |file| {261 for (write_file.files.items) |file| {
262 man.hash.addBytes(file.sub_path);262 man.hash.addBytes(file.sub_path);
263 switch (file.contents) {263 switch (file.contents) {
264 .bytes => |bytes| {264 .bytes => |bytes| {
265 man.hash.addBytes(bytes);265 man.hash.addBytes(bytes);
266 },266 },
267 .copy => |file_source| {267 .copy => |file_source| {
268 _ = try man.addFile(file_source.getPath(b), null);268 _ = try man.addFile(file_source.getPath2(b, step), null);
269 },269 },
270 }270 }
271 }271 }
272 for (wf.directories.items) |dir| {272 for (write_file.directories.items) |dir| {
273 man.hash.addBytes(dir.source.getPath2(b, step));273 man.hash.addBytes(dir.source.getPath2(b, step));
274 man.hash.addBytes(dir.sub_path);274 man.hash.addBytes(dir.sub_path);
275 for (dir.options.exclude_extensions) |ext| man.hash.addBytes(ext);275 for (dir.options.exclude_extensions) |ext| man.hash.addBytes(ext);
...@@ -278,19 +278,19 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -278,19 +278,19 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
278278
279 if (try step.cacheHit(&man)) {279 if (try step.cacheHit(&man)) {
280 const digest = man.final();280 const digest = man.final();
281 for (wf.files.items) |file| {281 for (write_file.files.items) |file| {
282 file.generated_file.path = try b.cache_root.join(b.allocator, &.{282 file.generated_file.path = try b.cache_root.join(b.allocator, &.{
283 "o", &digest, file.sub_path,283 "o", &digest, file.sub_path,
284 });284 });
285 }285 }
286 wf.generated_directory.path = try b.cache_root.join(b.allocator, &.{ "o", &digest });286 write_file.generated_directory.path = try b.cache_root.join(b.allocator, &.{ "o", &digest });
287 return;287 return;
288 }288 }
289289
290 const digest = man.final();290 const digest = man.final();
291 const cache_path = "o" ++ fs.path.sep_str ++ digest;291 const cache_path = "o" ++ fs.path.sep_str ++ digest;
292292
293 wf.generated_directory.path = try b.cache_root.join(b.allocator, &.{ "o", &digest });293 write_file.generated_directory.path = try b.cache_root.join(b.allocator, &.{ "o", &digest });
294294
295 var cache_dir = b.cache_root.handle.makeOpenPath(cache_path, .{}) catch |err| {295 var cache_dir = b.cache_root.handle.makeOpenPath(cache_path, .{}) catch |err| {
296 return step.fail("unable to make path '{}{s}': {s}", .{296 return step.fail("unable to make path '{}{s}': {s}", .{
...@@ -301,7 +301,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -301,7 +301,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
301301
302 const cwd = fs.cwd();302 const cwd = fs.cwd();
303303
304 for (wf.files.items) |file| {304 for (write_file.files.items) |file| {
305 if (fs.path.dirname(file.sub_path)) |dirname| {305 if (fs.path.dirname(file.sub_path)) |dirname| {
306 cache_dir.makePath(dirname) catch |err| {306 cache_dir.makePath(dirname) catch |err| {
307 return step.fail("unable to make path '{}{s}{c}{s}': {s}", .{307 return step.fail("unable to make path '{}{s}{c}{s}': {s}", .{
...@@ -318,7 +318,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -318,7 +318,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
318 };318 };
319 },319 },
320 .copy => |file_source| {320 .copy => |file_source| {
321 const source_path = file_source.getPath(b);321 const source_path = file_source.getPath2(b, step);
322 const prev_status = fs.Dir.updateFile(322 const prev_status = fs.Dir.updateFile(
323 cwd,323 cwd,
324 source_path,324 source_path,
...@@ -347,7 +347,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -347,7 +347,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
347 cache_path, file.sub_path,347 cache_path, file.sub_path,
348 });348 });
349 }349 }
350 for (wf.directories.items) |dir| {350 for (write_file.directories.items) |dir| {
351 const full_src_dir_path = dir.source.getPath2(b, step);351 const full_src_dir_path = dir.source.getPath2(b, step);
352 const dest_dirname = dir.sub_path;352 const dest_dirname = dir.sub_path;
353353
test/standalone/build.zig.zon+3
...@@ -164,6 +164,9 @@...@@ -164,6 +164,9 @@
164 .dependencyFromBuildZig = .{164 .dependencyFromBuildZig = .{
165 .path = "dependencyFromBuildZig",165 .path = "dependencyFromBuildZig",
166 },166 },
167 .run_output_paths = .{
168 .path = "run_output_paths",
169 },
167 },170 },
168 .paths = .{171 .paths = .{
169 "build.zig",172 "build.zig",
test/standalone/coff_dwarf/build.zig+2-2
...@@ -18,7 +18,7 @@ pub fn build(b: *std.Build) void {...@@ -18,7 +18,7 @@ pub fn build(b: *std.Build) void {
1818
19 const exe = b.addExecutable(.{19 const exe = b.addExecutable(.{
20 .name = "main",20 .name = "main",
21 .root_source_file = .{ .path = "main.zig" },21 .root_source_file = b.path("main.zig"),
22 .optimize = optimize,22 .optimize = optimize,
23 .target = target,23 .target = target,
24 });24 });
...@@ -28,7 +28,7 @@ pub fn build(b: *std.Build) void {...@@ -28,7 +28,7 @@ pub fn build(b: *std.Build) void {
28 .optimize = optimize,28 .optimize = optimize,
29 .target = target,29 .target = target,
30 });30 });
31 lib.addCSourceFile(.{ .file = .{ .path = "shared_lib.c" }, .flags = &.{"-gdwarf"} });31 lib.addCSourceFile(.{ .file = b.path("shared_lib.c"), .flags = &.{"-gdwarf"} });
32 lib.linkLibC();32 lib.linkLibC();
33 exe.linkLibrary(lib);33 exe.linkLibrary(lib);
3434
test/standalone/emit_asm_and_bin/build.zig+1-1
...@@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void {...@@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void {
5 b.default_step = test_step;5 b.default_step = test_step;
66
7 const main = b.addTest(.{7 const main = b.addTest(.{
8 .root_source_file = .{ .path = "main.zig" },8 .root_source_file = b.path("main.zig"),
9 .optimize = b.standardOptimizeOption(.{}),9 .optimize = b.standardOptimizeOption(.{}),
10 });10 });
11 // TODO: actually check these two artifacts for correctness11 // TODO: actually check these two artifacts for correctness
test/standalone/issue_12588/build.zig+1-1
...@@ -8,7 +8,7 @@ pub fn build(b: *std.Build) void {...@@ -8,7 +8,7 @@ pub fn build(b: *std.Build) void {
88
9 const obj = b.addObject(.{9 const obj = b.addObject(.{
10 .name = "main",10 .name = "main",
11 .root_source_file = .{ .path = "main.zig" },11 .root_source_file = b.path("main.zig"),
12 .optimize = optimize,12 .optimize = optimize,
13 .target = b.host,13 .target = b.host,
14 });14 });
test/standalone/issue_13970/build.zig+3-3
...@@ -5,15 +5,15 @@ pub fn build(b: *std.Build) void {...@@ -5,15 +5,15 @@ pub fn build(b: *std.Build) void {
5 b.default_step = test_step;5 b.default_step = test_step;
66
7 const test1 = b.addTest(.{7 const test1 = b.addTest(.{
8 .root_source_file = .{ .path = "test_root/empty.zig" },8 .root_source_file = b.path("test_root/empty.zig"),
9 .test_runner = "src/main.zig",9 .test_runner = "src/main.zig",
10 });10 });
11 const test2 = b.addTest(.{11 const test2 = b.addTest(.{
12 .root_source_file = .{ .path = "src/empty.zig" },12 .root_source_file = b.path("src/empty.zig"),
13 .test_runner = "src/main.zig",13 .test_runner = "src/main.zig",
14 });14 });
15 const test3 = b.addTest(.{15 const test3 = b.addTest(.{
16 .root_source_file = .{ .path = "empty.zig" },16 .root_source_file = b.path("empty.zig"),
17 .test_runner = "src/main.zig",17 .test_runner = "src/main.zig",
18 });18 });
1919
test/standalone/issue_5825/build.zig+1-1
...@@ -16,7 +16,7 @@ pub fn build(b: *std.Build) void {...@@ -16,7 +16,7 @@ pub fn build(b: *std.Build) void {
16 const optimize: std.builtin.OptimizeMode = .Debug;16 const optimize: std.builtin.OptimizeMode = .Debug;
17 const obj = b.addObject(.{17 const obj = b.addObject(.{
18 .name = "issue_5825",18 .name = "issue_5825",
19 .root_source_file = .{ .path = "main.zig" },19 .root_source_file = b.path("main.zig"),
20 .optimize = optimize,20 .optimize = optimize,
21 .target = target,21 .target = target,
22 });22 });
test/standalone/options/build.zig+1-1
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
22
3pub fn build(b: *std.Build) void {3pub fn build(b: *std.Build) void {
4 const main = b.addTest(.{4 const main = b.addTest(.{
5 .root_source_file = .{ .path = "src/main.zig" },5 .root_source_file = b.path("src/main.zig"),
6 .target = b.host,6 .target = b.host,
7 .optimize = .Debug,7 .optimize = .Debug,
8 });8 });
test/standalone/run_output_paths/build.zig created+40
...@@ -0,0 +1,40 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const target = b.standardTargetOptions(.{});
8 const optimize = b.standardOptimizeOption(.{});
9
10 const create_file_exe = b.addExecutable(.{
11 .name = "create_file",
12 .root_source_file = b.path("create_file.zig"),
13 .target = target,
14 .optimize = optimize,
15 });
16
17 const create_first = b.addRunArtifact(create_file_exe);
18 const first_dir = create_first.addOutputDirectoryArg("first");
19 create_first.addArg("hello1.txt");
20 test_step.dependOn(&b.addCheckFile(first_dir.path(b, "hello1.txt"), .{ .expected_matches = &.{
21 std.fs.path.sep_str ++
22 \\first
23 \\hello1.txt
24 \\Hello, world!
25 \\
26 ,
27 } }).step);
28
29 const create_second = b.addRunArtifact(create_file_exe);
30 const second_dir = create_second.addPrefixedOutputDirectoryArg("--dir=", "second");
31 create_second.addArg("hello2.txt");
32 test_step.dependOn(&b.addCheckFile(second_dir.path(b, "hello2.txt"), .{ .expected_matches = &.{
33 std.fs.path.sep_str ++
34 \\second
35 \\hello2.txt
36 \\Hello, world!
37 \\
38 ,
39 } }).step);
40}
test/standalone/run_output_paths/create_file.zig created+19
...@@ -0,0 +1,19 @@
1const std = @import("std");
2
3pub fn main() !void {
4 var args = try std.process.argsWithAllocator(std.heap.page_allocator);
5 _ = args.skip();
6 const dir_name = args.next().?;
7 const dir = try std.fs.cwd().openDir(if (std.mem.startsWith(u8, dir_name, "--dir="))
8 dir_name["--dir=".len..]
9 else
10 dir_name, .{});
11 const file_name = args.next().?;
12 const file = try dir.createFile(file_name, .{});
13 try file.writer().print(
14 \\{s}
15 \\{s}
16 \\Hello, world!
17 \\
18 , .{ dir_name, file_name });
19}
test/standalone/sigpipe/build.zig+1-1
...@@ -29,7 +29,7 @@ pub fn build(b: *std.build.Builder) !void {...@@ -29,7 +29,7 @@ pub fn build(b: *std.build.Builder) !void {
29 options.addOption(bool, "keep_sigpipe", keep_sigpipe);29 options.addOption(bool, "keep_sigpipe", keep_sigpipe);
30 const exe = b.addExecutable(.{30 const exe = b.addExecutable(.{
31 .name = "breakpipe",31 .name = "breakpipe",
32 .root_source_file = .{ .path = "breakpipe.zig" },32 .root_source_file = b.path("breakpipe.zig"),
33 });33 });
34 exe.addOptions("build_options", options);34 exe.addOptions("build_options", options);
35 const run = b.addRunArtifact(exe);35 const run = b.addRunArtifact(exe);
test/standalone/windows_argv/build.zig+5-5
...@@ -11,7 +11,7 @@ pub fn build(b: *std.Build) !void {...@@ -11,7 +11,7 @@ pub fn build(b: *std.Build) !void {
1111
12 const lib_gnu = b.addStaticLibrary(.{12 const lib_gnu = b.addStaticLibrary(.{
13 .name = "toargv-gnu",13 .name = "toargv-gnu",
14 .root_source_file = .{ .path = "lib.zig" },14 .root_source_file = b.path("lib.zig"),
15 .target = b.resolveTargetQuery(.{15 .target = b.resolveTargetQuery(.{
16 .abi = .gnu,16 .abi = .gnu,
17 }),17 }),
...@@ -25,7 +25,7 @@ pub fn build(b: *std.Build) !void {...@@ -25,7 +25,7 @@ pub fn build(b: *std.Build) !void {
25 .optimize = optimize,25 .optimize = optimize,
26 });26 });
27 verify_gnu.addCSourceFile(.{27 verify_gnu.addCSourceFile(.{
28 .file = .{ .path = "verify.c" },28 .file = b.path("verify.c"),
29 .flags = &.{ "-DUNICODE", "-D_UNICODE" },29 .flags = &.{ "-DUNICODE", "-D_UNICODE" },
30 });30 });
31 verify_gnu.mingw_unicode_entry_point = true;31 verify_gnu.mingw_unicode_entry_point = true;
...@@ -34,7 +34,7 @@ pub fn build(b: *std.Build) !void {...@@ -34,7 +34,7 @@ pub fn build(b: *std.Build) !void {
3434
35 const fuzz = b.addExecutable(.{35 const fuzz = b.addExecutable(.{
36 .name = "fuzz",36 .name = "fuzz",
37 .root_source_file = .{ .path = "fuzz.zig" },37 .root_source_file = b.path("fuzz.zig"),
38 .target = b.host,38 .target = b.host,
39 .optimize = optimize,39 .optimize = optimize,
40 });40 });
...@@ -69,7 +69,7 @@ pub fn build(b: *std.Build) !void {...@@ -69,7 +69,7 @@ pub fn build(b: *std.Build) !void {
69 if (has_msvc) {69 if (has_msvc) {
70 const lib_msvc = b.addStaticLibrary(.{70 const lib_msvc = b.addStaticLibrary(.{
71 .name = "toargv-msvc",71 .name = "toargv-msvc",
72 .root_source_file = .{ .path = "lib.zig" },72 .root_source_file = b.path("lib.zig"),
73 .target = b.resolveTargetQuery(.{73 .target = b.resolveTargetQuery(.{
74 .abi = .msvc,74 .abi = .msvc,
75 }),75 }),
...@@ -83,7 +83,7 @@ pub fn build(b: *std.Build) !void {...@@ -83,7 +83,7 @@ pub fn build(b: *std.Build) !void {
83 .optimize = optimize,83 .optimize = optimize,
84 });84 });
85 verify_msvc.addCSourceFile(.{85 verify_msvc.addCSourceFile(.{
86 .file = .{ .path = "verify.c" },86 .file = b.path("verify.c"),
87 .flags = &.{ "-DUNICODE", "-D_UNICODE" },87 .flags = &.{ "-DUNICODE", "-D_UNICODE" },
88 });88 });
89 verify_msvc.linkLibrary(lib_msvc);89 verify_msvc.linkLibrary(lib_msvc);
test/standalone/windows_resources/build.zig+1-1
...@@ -36,7 +36,7 @@ fn add(...@@ -36,7 +36,7 @@ fn add(
36 .file = b.path("res/zig.rc"),36 .file = b.path("res/zig.rc"),
37 .flags = &.{"/c65001"}, // UTF-8 code page37 .flags = &.{"/c65001"}, // UTF-8 code page
38 .include_paths = &.{38 .include_paths = &.{
39 .{ .generated = &generated_h_step.generated_directory },39 .{ .generated = .{ .file = &generated_h_step.generated_directory } },
40 },40 },
41 });41 });
42 exe.rc_includes = switch (rc_includes) {42 exe.rc_includes = switch (rc_includes) {
test/standalone/windows_spawn/build.zig+2-2
...@@ -12,14 +12,14 @@ pub fn build(b: *std.Build) void {...@@ -12,14 +12,14 @@ pub fn build(b: *std.Build) void {
1212
13 const hello = b.addExecutable(.{13 const hello = b.addExecutable(.{
14 .name = "hello",14 .name = "hello",
15 .root_source_file = .{ .path = "hello.zig" },15 .root_source_file = b.path("hello.zig"),
16 .optimize = optimize,16 .optimize = optimize,
17 .target = target,17 .target = target,
18 });18 });
1919
20 const main = b.addExecutable(.{20 const main = b.addExecutable(.{
21 .name = "main",21 .name = "main",
22 .root_source_file = .{ .path = "main.zig" },22 .root_source_file = b.path("main.zig"),
23 .optimize = optimize,23 .optimize = optimize,
24 .target = target,24 .target = target,
25 });25 });