| author | |
| committer | |
| log | c6d37f389591e722f59ca7f2b719ec8cfc0a9984 |
| tree | 797d146e58652575739b35c824d5bbe16c2227b6 |
| parent | 1a63d26836f5c87e45280772b8ba9c822ba75b78 |
I had this idea to make b.dupe() also intern the strings since they will
be ultimately serialized to Configuration. Unfortunately the idea does
not work, because although a process-lived arena is used for the
string_bytes ArrayList of the Configuration.Wip, when the ArrayList is
resized, Allocator.free() memsets the freed memory to undefined, even
though it still technically lives due to being in a process-scoped
arena. So this commit will need to be partially reverted. However, I
kept it for posterity, and there are some more changes which I will now
note below.
- dupePaths: don't rewrite backslashes to forward slashes. backslashes
are valid in filenames on non-windows systems.
- always compile configurer in single-threaded mode
- use arena allocator for everything, no gpa for anything
- construct the Configuration.Wip instance earlier, so some stuff can be
prepopulated as desired.
- don't forget to flush9 files changed, 174 insertions(+), 162 deletions(-)
BRANCH_TODO+1-1| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | * remove Cache from configurer | ||
| 1 | * implement the build options | 2 | * implement the build options |
| 2 | * don't forget to add -listen arg back | 3 | * don't forget to add -listen arg back |
| 3 | * get zig init template working | 4 | * get zig init template working |
| 4 | * finish migrating the rest of the build steps | 5 | * finish migrating the rest of the build steps |
| 5 | * make zig-pkg path root configurable in maker (make sure --system still works) | 6 | * make zig-pkg path root configurable in maker (make sure --system still works) |
| 6 | * eliminate calls to getPath, getPath2, getPath3 | 7 | * eliminate calls to getPath, getPath2, getPath3 |
| 7 | * replace b.dupe() with string internment | ||
| 8 | * solve the TODOs added in this branch | 8 | * solve the TODOs added in this branch |
| 9 | * get zig tests passing | 9 | * get zig tests passing |
| 10 | * test a bunch of third party projects / help people migrate | 10 | * test a bunch of third party projects / help people migrate |
lib/compiler/configurer.zig+23-25| ... | @@ -24,31 +24,22 @@ pub const std_options: std.Options = .{ | ... | @@ -24,31 +24,22 @@ pub const std_options: std.Options = .{ |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | pub fn main(init: process.Init.Minimal) !void { | 26 | pub fn main(init: process.Init.Minimal) !void { |
| 27 | // The build runner is often short-lived, but thanks to `--watch` and `--webui`, that's not | 27 | var arena_allocator: std.heap.ArenaAllocator = .init(std.heap.page_allocator); |
| 28 | // always the case. So, we do need a true gpa for some things. | 28 | defer arena_allocator.deinit(); |
| 29 | var debug_gpa_state: std.heap.DebugAllocator(.{ | 29 | const arena = arena_allocator.allocator(); |
| 30 | // We'd rather have `zig build` run faster than catch harmless leaks in | 30 | |
| 31 | // the user's build.zig script. | 31 | // The configurer is always short-lived because all it does is serialize |
| 32 | .stack_trace_frames = 0, | 32 | // the configuration, which is picked up by a separate maker process. |
| 33 | }) = .init; | 33 | var threaded: std.Io.Threaded = .init(arena, .{ |
| 34 | defer _ = debug_gpa_state.deinit(); | ||
| 35 | const gpa = debug_gpa_state.allocator(); | ||
| 36 | |||
| 37 | var threaded: std.Io.Threaded = .init(gpa, .{ | ||
| 38 | .environ = init.environ, | 34 | .environ = init.environ, |
| 39 | .argv0 = .init(init.args), | 35 | .argv0 = .init(init.args), |
| 40 | }); | 36 | }); |
| 41 | defer threaded.deinit(); | 37 | defer threaded.deinit(); |
| 42 | const io = threaded.io(); | 38 | const io = threaded.io(); |
| 43 | 39 | ||
| 44 | // ...but we'll back our arena by `std.heap.page_allocator` for efficiency. | ||
| 45 | var arena_allocator: std.heap.ArenaAllocator = .init(std.heap.page_allocator); | ||
| 46 | defer arena_allocator.deinit(); | ||
| 47 | const arena = arena_allocator.allocator(); | ||
| 48 | |||
| 49 | const args = try init.args.toSlice(arena); | 40 | const args = try init.args.toSlice(arena); |
| 50 | 41 | ||
| 51 | // skip my own exe name | 42 | // Skip own executable name. |
| 52 | var arg_idx: usize = 1; | 43 | var arg_idx: usize = 1; |
| 53 | 44 | ||
| 54 | const zig_exe = expectArgOrFatal(args, &arg_idx, "--zig"); | 45 | const zig_exe = expectArgOrFatal(args, &arg_idx, "--zig"); |
| ... | @@ -84,7 +75,7 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -84,7 +75,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 84 | .arena = arena, | 75 | .arena = arena, |
| 85 | .cache = .{ | 76 | .cache = .{ |
| 86 | .io = io, | 77 | .io = io, |
| 87 | .gpa = gpa, | 78 | .gpa = arena, |
| 88 | .manifest_dir = try local_cache_directory.handle.createDirPathOpen(io, "h", .{}), | 79 | .manifest_dir = try local_cache_directory.handle.createDirPathOpen(io, "h", .{}), |
| 89 | .cwd = try process.currentPathAlloc(io, arena), | 80 | .cwd = try process.currentPathAlloc(io, arena), |
| 90 | }, | 81 | }, |
| ... | @@ -97,7 +88,18 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -97,7 +88,18 @@ pub fn main(init: process.Init.Minimal) !void { |
| 97 | .result = try std.zig.system.resolveTargetQuery(io, .{}), | 88 | .result = try std.zig.system.resolveTargetQuery(io, .{}), |
| 98 | }, | 89 | }, |
| 99 | .generated_files = .empty, | 90 | .generated_files = .empty, |
| 91 | |||
| 92 | // Created before running the user's configure script so that some things | ||
| 93 | // can be added during script execution such as strings. | ||
| 94 | // | ||
| 95 | // Use of arena here is load-bearing because `std.Build.dupe` is | ||
| 96 | // implemented by string internment, and then returning the interned | ||
| 97 | // slice. When the string bytes array is reallocated, that reference | ||
| 98 | // must stay alive. | ||
| 99 | .wip_configuration = .init(arena), | ||
| 100 | }; | 100 | }; |
| 101 | assert(try graph.wip_configuration.addString("") == .empty); | ||
| 102 | assert(try graph.wip_configuration.addString("root") == .root); | ||
| 101 | 103 | ||
| 102 | graph.cache.addPrefix(.{ .path = null, .handle = cwd }); | 104 | graph.cache.addPrefix(.{ .path = null, .handle = cwd }); |
| 103 | graph.cache.addPrefix(build_root_directory); | 105 | graph.cache.addPrefix(build_root_directory); |
| ... | @@ -200,19 +202,15 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -200,19 +202,15 @@ pub fn main(init: process.Init.Minimal) !void { |
| 200 | fatal(" access the help menu with 'zig build -h'", .{}); | 202 | fatal(" access the help menu with 'zig build -h'", .{}); |
| 201 | } | 203 | } |
| 202 | 204 | ||
| 203 | var wc: Configuration.Wip = .init(gpa); | 205 | try serializeSystemIntegrationOptions(&graph, &graph.wip_configuration); |
| 204 | defer wc.deinit(); | ||
| 205 | assert(try wc.addString("") == .empty); | ||
| 206 | assert(try wc.addString("root") == .root); | ||
| 207 | |||
| 208 | try serializeSystemIntegrationOptions(&graph, &wc); | ||
| 209 | 206 | ||
| 210 | var stdout_buffer: [1024]u8 = undefined; | 207 | var stdout_buffer: [1024]u8 = undefined; |
| 211 | var file_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); | 208 | var file_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); |
| 212 | serialize(builder, &wc, &file_writer.interface) catch |err| switch (err) { | 209 | serialize(builder, &graph.wip_configuration, &file_writer.interface) catch |err| switch (err) { |
| 213 | error.WriteFailed => fatal("failed to write configuration output: {t}", .{file_writer.err.?}), | 210 | error.WriteFailed => fatal("failed to write configuration output: {t}", .{file_writer.err.?}), |
| 214 | error.OutOfMemory => |e| return e, | 211 | error.OutOfMemory => |e| return e, |
| 215 | }; | 212 | }; |
| 213 | file_writer.flush() catch |err| fatal("failed to write configuration output: {t}", .{err}); | ||
| 216 | 214 | ||
| 217 | // This executable is short-lived and run in Debug mode, so we'd rather | 215 | // This executable is short-lived and run in Debug mode, so we'd rather |
| 218 | // have `zig build` run faster than catch resource leaks in the user's | 216 | // have `zig build` run faster than catch resource leaks in the user's |
lib/std/Build.zig+38-37| ... | @@ -115,11 +115,37 @@ pub const Graph = struct { | ... | @@ -115,11 +115,37 @@ pub const Graph = struct { |
| 115 | 115 | ||
| 116 | /// Indexes correspond to `Configuration.GeneratedFileIndex`. | 116 | /// Indexes correspond to `Configuration.GeneratedFileIndex`. |
| 117 | generated_files: std.ArrayList(*Step), | 117 | generated_files: std.ArrayList(*Step), |
| 118 | wip_configuration: Configuration.Wip, | ||
| 118 | 119 | ||
| 119 | pub fn addGeneratedFile(graph: *Graph, owner: *Step) Configuration.GeneratedFileIndex { | 120 | pub fn addGeneratedFile(graph: *Graph, owner: *Step) Configuration.GeneratedFileIndex { |
| 120 | graph.generated_files.append(graph.arena, owner) catch @panic("OOM"); | 121 | graph.generated_files.append(graph.arena, owner) catch @panic("OOM"); |
| 121 | return @enumFromInt(graph.generated_files.items.len - 1); | 122 | return @enumFromInt(graph.generated_files.items.len - 1); |
| 122 | } | 123 | } |
| 124 | |||
| 125 | pub fn dupeString(graph: *Graph, bytes: []const u8) [:0]const u8 { | ||
| 126 | // This code assumes the `Configuration.Wip` uses arena allocation such | ||
| 127 | // that references to string_bytes never die even when the ArrayList is | ||
| 128 | // reallocated. | ||
| 129 | const wc = &graph.wip_configuration; | ||
| 130 | const i = wc.addString(bytes) catch @panic("OOM"); | ||
| 131 | return wc.string_bytes.items[@intFromEnum(i)..][0..bytes.len :0]; | ||
| 132 | } | ||
| 133 | |||
| 134 | pub fn dupePath(graph: *Graph, bytes: []const u8) [:0]const u8 { | ||
| 135 | if (builtin.os.tag != .windows) return dupeString(graph, bytes); | ||
| 136 | const arena = graph.arena; | ||
| 137 | const the_copy = arena.dupe(u8, bytes) catch @panic("OOM"); | ||
| 138 | defer arena.free(the_copy); | ||
| 139 | mem.replaceScalar(u8, the_copy, '/', '\\'); | ||
| 140 | return dupeString(graph, the_copy); | ||
| 141 | } | ||
| 142 | |||
| 143 | pub fn dupeStrings(graph: *Graph, strings: []const []const u8) []const []const u8 { | ||
| 144 | const arena = graph.arena; | ||
| 145 | const array = arena.alloc([]const u8, strings.len) catch @panic("OOM"); | ||
| 146 | for (array, strings) |*dest, source| dest.* = dupeString(graph, source); | ||
| 147 | return array; | ||
| 148 | } | ||
| 123 | }; | 149 | }; |
| 124 | 150 | ||
| 125 | const AvailableDeps = []const struct { []const u8, []const u8 }; | 151 | const AvailableDeps = []const struct { []const u8, []const u8 }; |
| ... | @@ -869,36 +895,18 @@ pub fn addConfigHeader( | ... | @@ -869,36 +895,18 @@ pub fn addConfigHeader( |
| 869 | return config_header_step; | 895 | return config_header_step; |
| 870 | } | 896 | } |
| 871 | 897 | ||
| 872 | /// Allocator.dupe without the need to handle out of memory. | 898 | pub fn dupe(b: *Build, bytes: []const u8) [:0]const u8 { |
| 873 | pub fn dupe(b: *Build, bytes: []const u8) []u8 { | 899 | return b.graph.dupeString(bytes); |
| 874 | return dupeInner(b.allocator, bytes); | ||
| 875 | } | ||
| 876 | |||
| 877 | pub fn dupeInner(allocator: Allocator, bytes: []const u8) []u8 { | ||
| 878 | return allocator.dupe(u8, bytes) catch @panic("OOM"); | ||
| 879 | } | 900 | } |
| 880 | 901 | ||
| 881 | /// Duplicates an array of strings without the need to handle out of memory. | 902 | /// Duplicates an array of strings without the need to handle out of memory. |
| 882 | pub fn dupeStrings(b: *Build, strings: []const []const u8) [][]u8 { | 903 | pub fn dupeStrings(b: *Build, strings: []const []const u8) []const []const u8 { |
| 883 | const array = b.allocator.alloc([]u8, strings.len) catch @panic("OOM"); | 904 | return b.graph.dupeStrings(strings); |
| 884 | for (array, strings) |*dest, source| dest.* = b.dupe(source); | ||
| 885 | return array; | ||
| 886 | } | ||
| 887 | |||
| 888 | /// Duplicates a path and converts all slashes to the OS's canonical path separator. | ||
| 889 | pub fn dupePath(b: *Build, bytes: []const u8) []u8 { | ||
| 890 | return dupePathInner(b.allocator, bytes); | ||
| 891 | } | 905 | } |
| 892 | 906 | ||
| 893 | fn dupePathInner(allocator: Allocator, bytes: []const u8) []u8 { | 907 | /// Duplicates a path, canonicalizing path separators. |
| 894 | const the_copy = dupeInner(allocator, bytes); | 908 | pub fn dupePath(b: *Build, bytes: []const u8) [:0]const u8 { |
| 895 | for (the_copy) |*byte| { | 909 | return b.graph.dupePath(bytes); |
| 896 | switch (byte.*) { | ||
| 897 | '/', '\\' => byte.* = fs.path.sep, | ||
| 898 | else => {}, | ||
| 899 | } | ||
| 900 | } | ||
| 901 | return the_copy; | ||
| 902 | } | 910 | } |
| 903 | 911 | ||
| 904 | pub fn addWriteFile(b: *Build, file_path: []const u8, data: []const u8) *Step.WriteFile { | 912 | pub fn addWriteFile(b: *Build, file_path: []const u8, data: []const u8) *Step.WriteFile { |
| ... | @@ -2268,25 +2276,18 @@ pub const LazyPath = union(enum) { | ... | @@ -2268,25 +2276,18 @@ pub const LazyPath = union(enum) { |
| 2268 | /// | 2276 | /// |
| 2269 | /// The `b` parameter is only used for its allocator. All *Build instances | 2277 | /// The `b` parameter is only used for its allocator. All *Build instances |
| 2270 | /// share the same allocator. | 2278 | /// share the same allocator. |
| 2271 | pub fn dupe(lazy_path: LazyPath, b: *Build) LazyPath { | 2279 | pub fn dupe(lazy_path: LazyPath, graph: *Graph) LazyPath { |
| 2272 | return lazy_path.dupeInner(b.allocator); | ||
| 2273 | } | ||
| 2274 | |||
| 2275 | fn dupeInner(lazy_path: LazyPath, allocator: Allocator) LazyPath { | ||
| 2276 | return switch (lazy_path) { | 2280 | return switch (lazy_path) { |
| 2277 | .src_path => |sp| .{ .src_path = .{ | 2281 | .src_path => |sp| .{ .src_path = .{ .owner = sp.owner, .sub_path = sp.owner.dupePath(sp.sub_path) } }, |
| 2278 | .owner = sp.owner, | 2282 | .cwd_relative => |p| .{ .cwd_relative = graph.dupePath(p) }, |
| 2279 | .sub_path = sp.owner.dupePath(sp.sub_path), | ||
| 2280 | } }, | ||
| 2281 | .cwd_relative => |p| .{ .cwd_relative = dupePathInner(allocator, p) }, | ||
| 2282 | .generated => |gen| .{ .generated = .{ | 2283 | .generated => |gen| .{ .generated = .{ |
| 2283 | .index = gen.index, | 2284 | .index = gen.index, |
| 2284 | .up = gen.up, | 2285 | .up = gen.up, |
| 2285 | .sub_path = dupePathInner(allocator, gen.sub_path), | 2286 | .sub_path = graph.dupePath(gen.sub_path), |
| 2286 | } }, | 2287 | } }, |
| 2287 | .dependency => |dep| .{ .dependency = .{ | 2288 | .dependency => |dep| .{ .dependency = .{ |
| 2288 | .dependency = dep.dependency, | 2289 | .dependency = dep.dependency, |
| 2289 | .sub_path = dupePathInner(allocator, dep.sub_path), | 2290 | .sub_path = graph.dupePath(dep.sub_path), |
| 2290 | } }, | 2291 | } }, |
| 2291 | }; | 2292 | }; |
| 2292 | } | 2293 | } |
lib/std/Build/Configuration.zig-7| ... | @@ -1419,13 +1419,6 @@ pub const Path = extern struct { | ... | @@ -1419,13 +1419,6 @@ pub const Path = extern struct { |
| 1419 | global_cache, | 1419 | global_cache, |
| 1420 | build_root, | 1420 | build_root, |
| 1421 | }; | 1421 | }; |
| 1422 | |||
| 1423 | pub fn toCachePath(path: Path, c: *const Configuration, arena: Allocator) std.Build.Cache.Path { | ||
| 1424 | _ = c; | ||
| 1425 | _ = arena; | ||
| 1426 | _ = path; | ||
| 1427 | @panic("TODO"); | ||
| 1428 | } | ||
| 1429 | }; | 1422 | }; |
| 1430 | 1423 | ||
| 1431 | pub const InstallDestDir = enum(u32) { | 1424 | pub const InstallDestDir = enum(u32) { |
lib/std/Build/Module.zig+4-3| ... | @@ -240,13 +240,14 @@ pub fn init( | ... | @@ -240,13 +240,14 @@ pub fn init( |
| 240 | owner: *std.Build, | 240 | owner: *std.Build, |
| 241 | value: union(enum) { options: CreateOptions, existing: *const Module }, | 241 | value: union(enum) { options: CreateOptions, existing: *const Module }, |
| 242 | ) void { | 242 | ) void { |
| 243 | const allocator = owner.allocator; | 243 | const graph = owner.graph; |
| 244 | const arena = graph.arena; | ||
| 244 | 245 | ||
| 245 | switch (value) { | 246 | switch (value) { |
| 246 | .options => |options| { | 247 | .options => |options| { |
| 247 | m.* = .{ | 248 | m.* = .{ |
| 248 | .owner = owner, | 249 | .owner = owner, |
| 249 | .root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null, | 250 | .root_source_file = if (options.root_source_file) |lp| lp.dupe(graph) else null, |
| 250 | .import_table = .empty, | 251 | .import_table = .empty, |
| 251 | .resolved_target = options.target, | 252 | .resolved_target = options.target, |
| 252 | .optimize = options.optimize, | 253 | .optimize = options.optimize, |
| ... | @@ -277,7 +278,7 @@ pub fn init( | ... | @@ -277,7 +278,7 @@ pub fn init( |
| 277 | .no_builtin = options.no_builtin, | 278 | .no_builtin = options.no_builtin, |
| 278 | }; | 279 | }; |
| 279 | 280 | ||
| 280 | m.import_table.ensureUnusedCapacity(allocator, options.imports.len) catch @panic("OOM"); | 281 | m.import_table.ensureUnusedCapacity(arena, options.imports.len) catch @panic("OOM"); |
| 281 | for (options.imports) |dep| { | 282 | for (options.imports) |dep| { |
| 282 | m.import_table.putAssumeCapacity(dep.name, dep.module); | 283 | m.import_table.putAssumeCapacity(dep.name, dep.module); |
| 283 | } | 284 | } |
lib/std/Build/Step/Compile.zig+35-31| ... | @@ -296,10 +296,10 @@ pub const HeaderInstallation = union(enum) { | ... | @@ -296,10 +296,10 @@ pub const HeaderInstallation = union(enum) { |
| 296 | source: LazyPath, | 296 | source: LazyPath, |
| 297 | dest_rel_path: []const u8, | 297 | dest_rel_path: []const u8, |
| 298 | 298 | ||
| 299 | pub fn dupe(file: File, b: *std.Build) File { | 299 | pub fn dupe(file: File, graph: *std.Build.Graph) File { |
| 300 | return .{ | 300 | return .{ |
| 301 | .source = file.source.dupe(b), | 301 | .source = file.source.dupe(graph), |
| 302 | .dest_rel_path = b.dupePath(file.dest_rel_path), | 302 | .dest_rel_path = graph.dupePath(file.dest_rel_path), |
| 303 | }; | 303 | }; |
| 304 | } | 304 | } |
| 305 | }; | 305 | }; |
| ... | @@ -424,13 +424,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile { | ... | @@ -424,13 +424,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 424 | }; | 424 | }; |
| 425 | 425 | ||
| 426 | if (options.zig_lib_dir) |lp| { | 426 | if (options.zig_lib_dir) |lp| { |
| 427 | compile.zig_lib_dir = lp.dupe(compile.step.owner); | 427 | compile.zig_lib_dir = lp.dupe(graph); |
| 428 | lp.addStepDependencies(&compile.step); | 428 | lp.addStepDependencies(&compile.step); |
| 429 | } | 429 | } |
| 430 | 430 | ||
| 431 | if (options.test_runner) |runner| { | 431 | if (options.test_runner) |runner| { |
| 432 | compile.test_runner = .{ | 432 | compile.test_runner = .{ |
| 433 | .path = runner.path.dupe(compile.step.owner), | 433 | .path = runner.path.dupe(graph), |
| 434 | .mode = runner.mode, | 434 | .mode = runner.mode, |
| 435 | }; | 435 | }; |
| 436 | runner.path.addStepDependencies(&compile.step); | 436 | runner.path.addStepDependencies(&compile.step); |
| ... | @@ -440,20 +440,20 @@ pub fn create(owner: *std.Build, options: Options) *Compile { | ... | @@ -440,20 +440,20 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 440 | // gets embedded, so for any other target the manifest file is just ignored. | 440 | // gets embedded, so for any other target the manifest file is just ignored. |
| 441 | if (target.ofmt == .coff) { | 441 | if (target.ofmt == .coff) { |
| 442 | if (options.win32_manifest) |lp| { | 442 | if (options.win32_manifest) |lp| { |
| 443 | compile.win32_manifest = lp.dupe(compile.step.owner); | 443 | compile.win32_manifest = lp.dupe(graph); |
| 444 | lp.addStepDependencies(&compile.step); | 444 | lp.addStepDependencies(&compile.step); |
| 445 | } | 445 | } |
| 446 | if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic) { | 446 | if (compile.kind == .lib and compile.linkage != null and compile.linkage.? == .dynamic) { |
| 447 | // Building a Win32 DLL, check for win32 .def file. | 447 | // Building a Win32 DLL, check for win32 .def file. |
| 448 | if (options.win32_module_definition) |lp| { | 448 | if (options.win32_module_definition) |lp| { |
| 449 | compile.win32_module_definition = lp.dupe(compile.step.owner); | 449 | compile.win32_module_definition = lp.dupe(graph); |
| 450 | lp.addStepDependencies(&compile.step); | 450 | lp.addStepDependencies(&compile.step); |
| 451 | } | 451 | } |
| 452 | } | 452 | } |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | if (options.entitlements) |lp| { | 455 | if (options.entitlements) |lp| { |
| 456 | compile.entitlements = lp.dupe(compile.step.owner); | 456 | compile.entitlements = lp.dupe(graph); |
| 457 | lp.addStepDependencies(&compile.step); | 457 | lp.addStepDependencies(&compile.step); |
| 458 | } | 458 | } |
| 459 | 459 | ||
| ... | @@ -464,12 +464,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile { | ... | @@ -464,12 +464,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 464 | /// When a module links with this artifact, all headers marked for installation are added to that | 464 | /// When a module links with this artifact, all headers marked for installation are added to that |
| 465 | /// module's include search path. | 465 | /// module's include search path. |
| 466 | pub fn installHeader(cs: *Compile, source: LazyPath, dest_rel_path: []const u8) void { | 466 | pub fn installHeader(cs: *Compile, source: LazyPath, dest_rel_path: []const u8) void { |
| 467 | const b = cs.step.owner; | 467 | const graph = cs.step.owner.graph; |
| 468 | const arena = graph.arena; | ||
| 468 | const installation: HeaderInstallation = .{ .file = .{ | 469 | const installation: HeaderInstallation = .{ .file = .{ |
| 469 | .source = source.dupe(b), | 470 | .source = source.dupe(graph), |
| 470 | .dest_rel_path = b.dupePath(dest_rel_path), | 471 | .dest_rel_path = graph.dupePath(dest_rel_path), |
| 471 | } }; | 472 | } }; |
| 472 | cs.installed_headers.append(b.allocator, installation) catch @panic("OOM"); | 473 | cs.installed_headers.append(arena, installation) catch @panic("OOM"); |
| 473 | cs.addHeaderInstallationToIncludeTree(installation); | 474 | cs.addHeaderInstallationToIncludeTree(installation); |
| 474 | installation.getSource().addStepDependencies(&cs.step); | 475 | installation.getSource().addStepDependencies(&cs.step); |
| 475 | } | 476 | } |
| ... | @@ -483,13 +484,14 @@ pub fn installHeadersDirectory( | ... | @@ -483,13 +484,14 @@ pub fn installHeadersDirectory( |
| 483 | dest_rel_path: []const u8, | 484 | dest_rel_path: []const u8, |
| 484 | options: HeaderInstallation.Directory.Options, | 485 | options: HeaderInstallation.Directory.Options, |
| 485 | ) void { | 486 | ) void { |
| 486 | const b = cs.step.owner; | 487 | const graph = cs.step.owner.graph; |
| 488 | const arena = graph.arena; | ||
| 487 | const installation: HeaderInstallation = .{ .directory = .{ | 489 | const installation: HeaderInstallation = .{ .directory = .{ |
| 488 | .source = source.dupe(b), | 490 | .source = source.dupe(graph), |
| 489 | .dest_rel_path = b.dupePath(dest_rel_path), | 491 | .dest_rel_path = graph.dupePath(dest_rel_path), |
| 490 | .options = options.dupe(b), | 492 | .options = options.dupe(graph), |
| 491 | } }; | 493 | } }; |
| 492 | cs.installed_headers.append(b.allocator, installation) catch @panic("OOM"); | 494 | cs.installed_headers.append(arena, installation) catch @panic("OOM"); |
| 493 | cs.addHeaderInstallationToIncludeTree(installation); | 495 | cs.addHeaderInstallationToIncludeTree(installation); |
| 494 | installation.getSource().addStepDependencies(&cs.step); | 496 | installation.getSource().addStepDependencies(&cs.step); |
| 495 | } | 497 | } |
| ... | @@ -506,9 +508,10 @@ pub fn installConfigHeader(cs: *Compile, config_header: *Step.ConfigHeader) void | ... | @@ -506,9 +508,10 @@ pub fn installConfigHeader(cs: *Compile, config_header: *Step.ConfigHeader) void |
| 506 | /// module's include search path. | 508 | /// module's include search path. |
| 507 | pub fn installLibraryHeaders(cs: *Compile, lib: *Compile) void { | 509 | pub fn installLibraryHeaders(cs: *Compile, lib: *Compile) void { |
| 508 | assert(lib.kind == .lib); | 510 | assert(lib.kind == .lib); |
| 509 | const arena = cs.owner.allocator; | 511 | const graph = cs.step.owner.graph; |
| 512 | const arena = graph.arena; | ||
| 510 | for (lib.installed_headers.items) |installation| { | 513 | for (lib.installed_headers.items) |installation| { |
| 511 | const installation_copy = installation.dupe(lib.step.owner); | 514 | const installation_copy = installation.dupe(graph); |
| 512 | cs.installed_headers.append(arena, installation_copy) catch @panic("OOM"); | 515 | cs.installed_headers.append(arena, installation_copy) catch @panic("OOM"); |
| 513 | cs.addHeaderInstallationToIncludeTree(installation_copy); | 516 | cs.addHeaderInstallationToIncludeTree(installation_copy); |
| 514 | installation_copy.getSource().addStepDependencies(&cs.step); | 517 | installation_copy.getSource().addStepDependencies(&cs.step); |
| ... | @@ -556,21 +559,21 @@ pub fn addObjCopy(cs: *Compile, options: Step.ObjCopy.Options) *Step.ObjCopy { | ... | @@ -556,21 +559,21 @@ pub fn addObjCopy(cs: *Compile, options: Step.ObjCopy.Options) *Step.ObjCopy { |
| 556 | } | 559 | } |
| 557 | 560 | ||
| 558 | pub fn setLinkerScript(compile: *Compile, source: LazyPath) void { | 561 | pub fn setLinkerScript(compile: *Compile, source: LazyPath) void { |
| 559 | const b = compile.step.owner; | 562 | const graph = compile.step.owner.graph; |
| 560 | compile.linker_script = source.dupe(b); | 563 | compile.linker_script = source.dupe(graph); |
| 561 | source.addStepDependencies(&compile.step); | 564 | source.addStepDependencies(&compile.step); |
| 562 | } | 565 | } |
| 563 | 566 | ||
| 564 | pub fn setVersionScript(compile: *Compile, source: LazyPath) void { | 567 | pub fn setVersionScript(compile: *Compile, source: LazyPath) void { |
| 565 | const b = compile.step.owner; | 568 | const graph = compile.step.owner.graph; |
| 566 | compile.version_script = source.dupe(b); | 569 | compile.version_script = source.dupe(graph); |
| 567 | source.addStepDependencies(&compile.step); | 570 | source.addStepDependencies(&compile.step); |
| 568 | } | 571 | } |
| 569 | 572 | ||
| 570 | pub fn forceUndefinedSymbol(compile: *Compile, symbol_name: []const u8) void { | 573 | pub fn forceUndefinedSymbol(compile: *Compile, symbol_name: []const u8) void { |
| 571 | const b = compile.step.owner; | 574 | const graph = compile.step.owner.graph; |
| 572 | const arena = b.allocator; | 575 | const arena = graph.allocator; |
| 573 | compile.force_undefined_symbols.put(arena, b.dupe(symbol_name), {}) catch @panic("OOM"); | 576 | compile.force_undefined_symbols.put(arena, graph.dupeString(symbol_name), {}) catch @panic("OOM"); |
| 574 | } | 577 | } |
| 575 | 578 | ||
| 576 | /// Returns whether the library, executable, or object depends on a particular system library. | 579 | /// Returns whether the library, executable, or object depends on a particular system library. |
| ... | @@ -655,9 +658,9 @@ pub fn setVerboseCC(compile: *Compile, value: bool) void { | ... | @@ -655,9 +658,9 @@ pub fn setVerboseCC(compile: *Compile, value: bool) void { |
| 655 | } | 658 | } |
| 656 | 659 | ||
| 657 | pub fn setLibCFile(compile: *Compile, libc_file: ?LazyPath) void { | 660 | pub fn setLibCFile(compile: *Compile, libc_file: ?LazyPath) void { |
| 658 | const b = compile.step.owner; | 661 | const graph = compile.step.owner.graph; |
| 659 | if (libc_file) |f| { | 662 | if (libc_file) |f| { |
| 660 | compile.libc_file = f.dupe(b); | 663 | compile.libc_file = f.dupe(graph); |
| 661 | f.addStepDependencies(&compile.step); | 664 | f.addStepDependencies(&compile.step); |
| 662 | } else { | 665 | } else { |
| 663 | compile.libc_file = null; | 666 | compile.libc_file = null; |
| ... | @@ -733,11 +736,12 @@ pub fn getEmittedLlvmBc(compile: *Compile) LazyPath { | ... | @@ -733,11 +736,12 @@ pub fn getEmittedLlvmBc(compile: *Compile) LazyPath { |
| 733 | } | 736 | } |
| 734 | 737 | ||
| 735 | pub fn setExecCmd(compile: *Compile, args: []const ?[]const u8) void { | 738 | pub fn setExecCmd(compile: *Compile, args: []const ?[]const u8) void { |
| 736 | const b = compile.step.owner; | 739 | const graph = compile.step.owner.graph; |
| 740 | const arena = graph.arena; | ||
| 737 | assert(compile.kind == .@"test"); | 741 | assert(compile.kind == .@"test"); |
| 738 | const duped_args = b.allocator.alloc(?[]u8, args.len) catch @panic("OOM"); | 742 | const duped_args = arena.alloc(?[]u8, args.len) catch @panic("OOM"); |
| 739 | for (args, 0..) |arg, i| { | 743 | for (args, 0..) |arg, i| { |
| 740 | duped_args[i] = if (arg) |a| b.dupe(a) else null; | 744 | duped_args[i] = if (arg) |a| graph.dupeString(a) else null; |
| 741 | } | 745 | } |
| 742 | compile.exec_cmd_args = duped_args; | 746 | compile.exec_cmd_args = duped_args; |
| 743 | } | 747 | } |
lib/std/Build/Step/Run.zig+57-43| ... | @@ -139,7 +139,7 @@ pub const Arg = union(enum) { | ... | @@ -139,7 +139,7 @@ pub const Arg = union(enum) { |
| 139 | lazy_path: PrefixedLazyPath, | 139 | lazy_path: PrefixedLazyPath, |
| 140 | decorated_directory: DecoratedLazyPath, | 140 | decorated_directory: DecoratedLazyPath, |
| 141 | file_content: PrefixedLazyPath, | 141 | file_content: PrefixedLazyPath, |
| 142 | bytes: []u8, | 142 | bytes: [:0]const u8, |
| 143 | output_file: *Output, | 143 | output_file: *Output, |
| 144 | output_directory: *Output, | 144 | output_directory: *Output, |
| 145 | /// The arguments passed after "--" on the "zig build" CLI. | 145 | /// The arguments passed after "--" on the "zig build" CLI. |
| ... | @@ -228,13 +228,14 @@ pub fn addArtifactArg(run: *Run, artifact: *Step.Compile) void { | ... | @@ -228,13 +228,14 @@ pub fn addArtifactArg(run: *Run, artifact: *Step.Compile) void { |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Compile) void { | 230 | pub fn addPrefixedArtifactArg(run: *Run, prefix: []const u8, artifact: *Step.Compile) void { |
| 231 | const b = run.step.owner; | 231 | const graph = run.step.owner.graph; |
| 232 | const arena = graph.arena; | ||
| 232 | 233 | ||
| 233 | const prefixed_artifact: PrefixedArtifact = .{ | 234 | const prefixed_artifact: PrefixedArtifact = .{ |
| 234 | .prefix = b.dupe(prefix), | 235 | .prefix = graph.dupeString(prefix), |
| 235 | .artifact = artifact, | 236 | .artifact = artifact, |
| 236 | }; | 237 | }; |
| 237 | run.argv.append(b.allocator, .{ .artifact = prefixed_artifact }) catch @panic("OOM"); | 238 | run.argv.append(arena, .{ .artifact = prefixed_artifact }) catch @panic("OOM"); |
| 238 | 239 | ||
| 239 | const bin_file = artifact.getEmittedBin(); | 240 | const bin_file = artifact.getEmittedBin(); |
| 240 | bin_file.addStepDependencies(&run.step); | 241 | bin_file.addStepDependencies(&run.step); |
| ... | @@ -279,8 +280,8 @@ pub fn addPrefixedOutputFileArg( | ... | @@ -279,8 +280,8 @@ pub fn addPrefixedOutputFileArg( |
| 279 | 280 | ||
| 280 | const output = arena.create(Output) catch @panic("OOM"); | 281 | const output = arena.create(Output) catch @panic("OOM"); |
| 281 | output.* = .{ | 282 | output.* = .{ |
| 282 | .prefix = b.dupe(prefix), | 283 | .prefix = graph.dupeString(prefix), |
| 283 | .basename = b.dupe(basename), | 284 | .basename = graph.dupeString(basename), |
| 284 | .generated_file = graph.addGeneratedFile(&run.step), | 285 | .generated_file = graph.addGeneratedFile(&run.step), |
| 285 | }; | 286 | }; |
| 286 | run.argv.append(arena, .{ .output_file = output }) catch @panic("OOM"); | 287 | run.argv.append(arena, .{ .output_file = output }) catch @panic("OOM"); |
| ... | @@ -318,13 +319,14 @@ pub fn addFileArg(run: *Run, lp: std.Build.LazyPath) void { | ... | @@ -318,13 +319,14 @@ pub fn addFileArg(run: *Run, lp: std.Build.LazyPath) void { |
| 318 | /// * `addFileArg` - same thing but without the prefix | 319 | /// * `addFileArg` - same thing but without the prefix |
| 319 | /// * `addOutputFileArg` - for files generated by the child process | 320 | /// * `addOutputFileArg` - for files generated by the child process |
| 320 | pub fn addPrefixedFileArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { | 321 | pub fn addPrefixedFileArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { |
| 321 | const b = run.step.owner; | 322 | const graph = run.step.owner.graph; |
| 323 | const arena = graph.arena; | ||
| 322 | 324 | ||
| 323 | const prefixed_file_source: PrefixedLazyPath = .{ | 325 | const prefixed_file_source: PrefixedLazyPath = .{ |
| 324 | .prefix = b.dupe(prefix), | 326 | .prefix = graph.dupeString(prefix), |
| 325 | .lazy_path = lp.dupe(b), | 327 | .lazy_path = lp.dupe(graph), |
| 326 | }; | 328 | }; |
| 327 | run.argv.append(b.allocator, .{ .lazy_path = prefixed_file_source }) catch @panic("OOM"); | 329 | run.argv.append(arena, .{ .lazy_path = prefixed_file_source }) catch @panic("OOM"); |
| 328 | lp.addStepDependencies(&run.step); | 330 | lp.addStepDependencies(&run.step); |
| 329 | } | 331 | } |
| 330 | 332 | ||
| ... | @@ -365,7 +367,8 @@ pub fn addFileContentArg(run: *Run, lp: std.Build.LazyPath) void { | ... | @@ -365,7 +367,8 @@ pub fn addFileContentArg(run: *Run, lp: std.Build.LazyPath) void { |
| 365 | /// Related: | 367 | /// Related: |
| 366 | /// * `addFileContentArg` - same thing but without the prefix | 368 | /// * `addFileContentArg` - same thing but without the prefix |
| 367 | pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { | 369 | pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { |
| 368 | const b = run.step.owner; | 370 | const graph = run.step.owner.graph; |
| 371 | const arena = graph.arena; | ||
| 369 | 372 | ||
| 370 | // Some parts of this step's configure phase API rely on the first argument being somewhat | 373 | // Some parts of this step's configure phase API rely on the first argument being somewhat |
| 371 | // transparent/readable, but the content of the file specified by `lp` remains completely | 374 | // transparent/readable, but the content of the file specified by `lp` remains completely |
| ... | @@ -375,10 +378,10 @@ pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.La | ... | @@ -375,10 +378,10 @@ pub fn addPrefixedFileContentArg(run: *Run, prefix: []const u8, lp: std.Build.La |
| 375 | } | 378 | } |
| 376 | 379 | ||
| 377 | const prefixed_file_source: PrefixedLazyPath = .{ | 380 | const prefixed_file_source: PrefixedLazyPath = .{ |
| 378 | .prefix = b.dupe(prefix), | 381 | .prefix = graph.dupeString(prefix), |
| 379 | .lazy_path = lp.dupe(b), | 382 | .lazy_path = lp.dupe(graph), |
| 380 | }; | 383 | }; |
| 381 | run.argv.append(b.allocator, .{ .file_content = prefixed_file_source }) catch @panic("OOM"); | 384 | run.argv.append(arena, .{ .file_content = prefixed_file_source }) catch @panic("OOM"); |
| 382 | lp.addStepDependencies(&run.step); | 385 | lp.addStepDependencies(&run.step); |
| 383 | } | 386 | } |
| 384 | 387 | ||
| ... | @@ -415,18 +418,19 @@ pub fn addPrefixedOutputDirectoryArg( | ... | @@ -415,18 +418,19 @@ pub fn addPrefixedOutputDirectoryArg( |
| 415 | basename: []const u8, | 418 | basename: []const u8, |
| 416 | ) std.Build.LazyPath { | 419 | ) std.Build.LazyPath { |
| 417 | if (basename.len == 0) @panic("basename must not be empty"); | 420 | if (basename.len == 0) @panic("basename must not be empty"); |
| 418 | const b = run.step.owner; | 421 | const graph = run.step.owner.graph; |
| 422 | const arena = graph.arena; | ||
| 419 | 423 | ||
| 420 | const output = b.allocator.create(Output) catch @panic("OOM"); | 424 | const output = arena.create(Output) catch @panic("OOM"); |
| 421 | output.* = .{ | 425 | output.* = .{ |
| 422 | .prefix = b.dupe(prefix), | 426 | .prefix = graph.dupeString(prefix), |
| 423 | .basename = b.dupe(basename), | 427 | .basename = graph.dupeString(basename), |
| 424 | .generated_file = .{ .step = &run.step }, | 428 | .generated_file = .{ .step = &run.step }, |
| 425 | }; | 429 | }; |
| 426 | run.argv.append(b.allocator, .{ .output_directory = output }) catch @panic("OOM"); | 430 | run.argv.append(arena, .{ .output_directory = output }) catch @panic("OOM"); |
| 427 | 431 | ||
| 428 | if (run.rename_step_with_output_arg) { | 432 | if (run.rename_step_with_output_arg) { |
| 429 | run.setName(b.fmt("{s} ({s})", .{ run.step.name, basename })); | 433 | run.setName(std.fmt.allocPrint(arena, "{s} ({s})", .{ run.step.name, basename }) catch @panic("OOM")); |
| 430 | } | 434 | } |
| 431 | 435 | ||
| 432 | return .{ .generated = .{ .file = &output.generated_file } }; | 436 | return .{ .generated = .{ .file = &output.generated_file } }; |
| ... | @@ -437,10 +441,11 @@ pub fn addDirectoryArg(run: *Run, lazy_directory: std.Build.LazyPath) void { | ... | @@ -437,10 +441,11 @@ pub fn addDirectoryArg(run: *Run, lazy_directory: std.Build.LazyPath) void { |
| 437 | } | 441 | } |
| 438 | 442 | ||
| 439 | pub fn addPrefixedDirectoryArg(run: *Run, prefix: []const u8, lazy_directory: std.Build.LazyPath) void { | 443 | pub fn addPrefixedDirectoryArg(run: *Run, prefix: []const u8, lazy_directory: std.Build.LazyPath) void { |
| 440 | const b = run.step.owner; | 444 | const graph = run.step.owner.graph; |
| 441 | run.argv.append(b.allocator, .{ .decorated_directory = .{ | 445 | const arena = graph.arena; |
| 442 | .prefix = b.dupe(prefix), | 446 | run.argv.append(arena, .{ .decorated_directory = .{ |
| 443 | .lazy_path = lazy_directory.dupe(b), | 447 | .prefix = graph.dupeString(prefix), |
| 448 | .lazy_path = lazy_directory.dupe(graph), | ||
| 444 | .suffix = "", | 449 | .suffix = "", |
| 445 | } }) catch @panic("OOM"); | 450 | } }) catch @panic("OOM"); |
| 446 | lazy_directory.addStepDependencies(&run.step); | 451 | lazy_directory.addStepDependencies(&run.step); |
| ... | @@ -452,11 +457,12 @@ pub fn addDecoratedDirectoryArg( | ... | @@ -452,11 +457,12 @@ pub fn addDecoratedDirectoryArg( |
| 452 | lazy_directory: std.Build.LazyPath, | 457 | lazy_directory: std.Build.LazyPath, |
| 453 | suffix: []const u8, | 458 | suffix: []const u8, |
| 454 | ) void { | 459 | ) void { |
| 455 | const b = run.step.owner; | 460 | const graph = run.step.owner.graph; |
| 456 | run.argv.append(b.allocator, .{ .decorated_directory = .{ | 461 | const arena = graph.arena; |
| 457 | .prefix = b.dupe(prefix), | 462 | run.argv.append(arena, .{ .decorated_directory = .{ |
| 458 | .lazy_path = lazy_directory.dupe(b), | 463 | .prefix = graph.dupeString(prefix), |
| 459 | .suffix = b.dupe(suffix), | 464 | .lazy_path = lazy_directory.dupe(graph), |
| 465 | .suffix = graph.dupeString(suffix), | ||
| 460 | } }) catch @panic("OOM"); | 466 | } }) catch @panic("OOM"); |
| 461 | lazy_directory.addStepDependencies(&run.step); | 467 | lazy_directory.addStepDependencies(&run.step); |
| 462 | } | 468 | } |
| ... | @@ -479,8 +485,8 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co | ... | @@ -479,8 +485,8 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co |
| 479 | 485 | ||
| 480 | const dep_file = arena.create(Output) catch @panic("OOM"); | 486 | const dep_file = arena.create(Output) catch @panic("OOM"); |
| 481 | dep_file.* = .{ | 487 | dep_file.* = .{ |
| 482 | .prefix = b.dupe(prefix), | 488 | .prefix = graph.dupeString(prefix), |
| 483 | .basename = b.dupe(basename), | 489 | .basename = graph.dupeString(basename), |
| 484 | .generated_file = graph.addGeneratedFile(&run.step), | 490 | .generated_file = graph.addGeneratedFile(&run.step), |
| 485 | }; | 491 | }; |
| 486 | 492 | ||
| ... | @@ -492,8 +498,9 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co | ... | @@ -492,8 +498,9 @@ pub fn addPrefixedDepFileOutputArg(run: *Run, prefix: []const u8, basename: []co |
| 492 | } | 498 | } |
| 493 | 499 | ||
| 494 | pub fn addArg(run: *Run, arg: []const u8) void { | 500 | pub fn addArg(run: *Run, arg: []const u8) void { |
| 495 | const b = run.step.owner; | 501 | const graph = run.step.owner.graph; |
| 496 | run.argv.append(b.allocator, .{ .bytes = b.dupe(arg) }) catch @panic("OOM"); | 502 | const arena = graph.arena; |
| 503 | run.argv.append(arena, .{ .bytes = graph.dupeString(arg) }) catch @panic("OOM"); | ||
| 497 | } | 504 | } |
| 498 | 505 | ||
| 499 | pub fn addArgs(run: *Run, args: []const []const u8) void { | 506 | pub fn addArgs(run: *Run, args: []const []const u8) void { |
| ... | @@ -509,8 +516,9 @@ pub fn setStdIn(run: *Run, stdin: StdIn) void { | ... | @@ -509,8 +516,9 @@ pub fn setStdIn(run: *Run, stdin: StdIn) void { |
| 509 | } | 516 | } |
| 510 | 517 | ||
| 511 | pub fn setCwd(run: *Run, cwd: Build.LazyPath) void { | 518 | pub fn setCwd(run: *Run, cwd: Build.LazyPath) void { |
| 519 | const graph = run.step.owner.graph; | ||
| 512 | cwd.addStepDependencies(&run.step); | 520 | cwd.addStepDependencies(&run.step); |
| 513 | run.cwd = cwd.dupe(run.step.owner); | 521 | run.cwd = cwd.dupe(graph); |
| 514 | } | 522 | } |
| 515 | 523 | ||
| 516 | pub fn clearEnvironment(run: *Run) void { | 524 | pub fn clearEnvironment(run: *Run) void { |
| ... | @@ -580,24 +588,28 @@ pub fn removeEnvironmentVariable(run: *Run, key: []const u8) void { | ... | @@ -580,24 +588,28 @@ pub fn removeEnvironmentVariable(run: *Run, key: []const u8) void { |
| 580 | 588 | ||
| 581 | /// Adds a check for exact stderr match. Does not add any other checks. | 589 | /// Adds a check for exact stderr match. Does not add any other checks. |
| 582 | pub fn expectStdErrEqual(run: *Run, bytes: []const u8) void { | 590 | pub fn expectStdErrEqual(run: *Run, bytes: []const u8) void { |
| 583 | run.addCheck(.{ .expect_stderr_exact = run.step.owner.dupe(bytes) }); | 591 | const graph = run.step.owner.graph; |
| 592 | run.addCheck(.{ .expect_stderr_exact = graph.dupeString(bytes) }); | ||
| 584 | } | 593 | } |
| 585 | 594 | ||
| 586 | pub fn expectStdErrMatch(run: *Run, bytes: []const u8) void { | 595 | pub fn expectStdErrMatch(run: *Run, bytes: []const u8) void { |
| 587 | run.addCheck(.{ .expect_stderr_match = run.step.owner.dupe(bytes) }); | 596 | const graph = run.step.owner.graph; |
| 597 | run.addCheck(.{ .expect_stderr_match = graph.dupeString(bytes) }); | ||
| 588 | } | 598 | } |
| 589 | 599 | ||
| 590 | /// Adds a check for exact stdout match as well as a check for exit code 0, if | 600 | /// Adds a check for exact stdout match as well as a check for exit code 0, if |
| 591 | /// there is not already an expected termination check. | 601 | /// there is not already an expected termination check. |
| 592 | pub fn expectStdOutEqual(run: *Run, bytes: []const u8) void { | 602 | pub fn expectStdOutEqual(run: *Run, bytes: []const u8) void { |
| 593 | run.addCheck(.{ .expect_stdout_exact = run.step.owner.dupe(bytes) }); | 603 | const graph = run.step.owner.graph; |
| 604 | run.addCheck(.{ .expect_stdout_exact = graph.dupeString(bytes) }); | ||
| 594 | if (!run.hasTermCheck()) run.expectExitCode(0); | 605 | if (!run.hasTermCheck()) run.expectExitCode(0); |
| 595 | } | 606 | } |
| 596 | 607 | ||
| 597 | /// Adds a check for stdout match as well as a check for exit code 0, if there | 608 | /// Adds a check for stdout match as well as a check for exit code 0, if there |
| 598 | /// is not already an expected termination check. | 609 | /// is not already an expected termination check. |
| 599 | pub fn expectStdOutMatch(run: *Run, bytes: []const u8) void { | 610 | pub fn expectStdOutMatch(run: *Run, bytes: []const u8) void { |
| 600 | run.addCheck(.{ .expect_stdout_match = run.step.owner.dupe(bytes) }); | 611 | const graph = run.step.owner.graph; |
| 612 | run.addCheck(.{ .expect_stdout_match = graph.dupeString(bytes) }); | ||
| 601 | if (!run.hasTermCheck()) run.expectExitCode(0); | 613 | if (!run.hasTermCheck()) run.expectExitCode(0); |
| 602 | } | 614 | } |
| 603 | 615 | ||
| ... | @@ -641,7 +653,7 @@ pub fn captureStdErr(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa | ... | @@ -641,7 +653,7 @@ pub fn captureStdErr(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa |
| 641 | captured.* = .{ | 653 | captured.* = .{ |
| 642 | .output = .{ | 654 | .output = .{ |
| 643 | .prefix = "", | 655 | .prefix = "", |
| 644 | .basename = if (options.basename) |basename| b.dupe(basename) else "stderr", | 656 | .basename = if (options.basename) |basename| graph.dupeString(basename) else "stderr", |
| 645 | .generated_file = graph.addGeneratedFile(&run.step), | 657 | .generated_file = graph.addGeneratedFile(&run.step), |
| 646 | }, | 658 | }, |
| 647 | .trim_whitespace = options.trim_whitespace, | 659 | .trim_whitespace = options.trim_whitespace, |
| ... | @@ -664,7 +676,7 @@ pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa | ... | @@ -664,7 +676,7 @@ pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa |
| 664 | captured.* = .{ | 676 | captured.* = .{ |
| 665 | .output = .{ | 677 | .output = .{ |
| 666 | .prefix = "", | 678 | .prefix = "", |
| 667 | .basename = if (options.basename) |basename| b.dupe(basename) else "stdout", | 679 | .basename = if (options.basename) |basename| graph.dupeString(basename) else "stdout", |
| 668 | .generated_file = graph.addGeneratedFile(&run.step), | 680 | .generated_file = graph.addGeneratedFile(&run.step), |
| 669 | }, | 681 | }, |
| 670 | .trim_whitespace = options.trim_whitespace, | 682 | .trim_whitespace = options.trim_whitespace, |
| ... | @@ -678,7 +690,9 @@ pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa | ... | @@ -678,7 +690,9 @@ pub fn captureStdOut(run: *Run, options: CapturedStdIo.Options) std.Build.LazyPa |
| 678 | /// If the Run step is determined to have side-effects, the Run step is always | 690 | /// If the Run step is determined to have side-effects, the Run step is always |
| 679 | /// executed when it appears in the build graph, regardless of whether this | 691 | /// executed when it appears in the build graph, regardless of whether this |
| 680 | /// file has been modified. | 692 | /// file has been modified. |
| 681 | pub fn addFileInput(self: *Run, file_input: std.Build.LazyPath) void { | 693 | pub fn addFileInput(run: *Run, file_input: std.Build.LazyPath) void { |
| 682 | file_input.addStepDependencies(&self.step); | 694 | const graph = run.step.owner.graph; |
| 683 | self.file_inputs.append(self.step.owner.allocator, file_input.dupe(self.step.owner)) catch @panic("OOM"); | 695 | const arena = graph.arena; |
| 696 | file_input.addStepDependencies(&run.step); | ||
| 697 | run.file_inputs.append(arena, file_input.dupe(graph)) catch @panic("OOM"); | ||
| 684 | } | 698 | } |
lib/std/Build/Step/WriteFile.zig+15-15| ... | @@ -55,10 +55,10 @@ pub const Directory = struct { | ... | @@ -55,10 +55,10 @@ pub const Directory = struct { |
| 55 | /// `exclude_extensions` takes precedence over `include_extensions`. | 55 | /// `exclude_extensions` takes precedence over `include_extensions`. |
| 56 | include_extensions: ?[]const []const u8 = null, | 56 | include_extensions: ?[]const []const u8 = null, |
| 57 | 57 | ||
| 58 | pub fn dupe(opts: Options, b: *std.Build) Options { | 58 | pub fn dupe(opts: Options, graph: *std.Build.Graph) Options { |
| 59 | return .{ | 59 | return .{ |
| 60 | .exclude_extensions = b.dupeStrings(opts.exclude_extensions), | 60 | .exclude_extensions = graph.dupeStrings(opts.exclude_extensions), |
| 61 | .include_extensions = if (opts.include_extensions) |incs| b.dupeStrings(incs) else null, | 61 | .include_extensions = if (opts.include_extensions) |incs| graph.dupeStrings(incs) else null, |
| 62 | }; | 62 | }; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| ... | @@ -103,13 +103,13 @@ pub fn create(owner: *std.Build) *WriteFile { | ... | @@ -103,13 +103,13 @@ pub fn create(owner: *std.Build) *WriteFile { |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | pub fn add(write_file: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.LazyPath { | 105 | pub fn add(write_file: *WriteFile, sub_path: []const u8, bytes: []const u8) std.Build.LazyPath { |
| 106 | const b = write_file.step.owner; | 106 | const graph = write_file.step.owner.graph; |
| 107 | const gpa = b.allocator; | 107 | const arena = graph.arena; |
| 108 | const file = File{ | 108 | const file: File = .{ |
| 109 | .sub_path = b.dupePath(sub_path), | 109 | .sub_path = graph.dupePath(sub_path), |
| 110 | .contents = .{ .bytes = b.dupe(bytes) }, | 110 | .contents = .{ .bytes = graph.dupeString(bytes) }, |
| 111 | }; | 111 | }; |
| 112 | write_file.files.append(gpa, file) catch @panic("OOM"); | 112 | write_file.files.append(arena, file) catch @panic("OOM"); |
| 113 | write_file.maybeUpdateName(); | 113 | write_file.maybeUpdateName(); |
| 114 | return .{ | 114 | return .{ |
| 115 | .generated = .{ | 115 | .generated = .{ |
| ... | @@ -154,14 +154,14 @@ pub fn addCopyDirectory( | ... | @@ -154,14 +154,14 @@ pub fn addCopyDirectory( |
| 154 | sub_path: []const u8, | 154 | sub_path: []const u8, |
| 155 | options: Directory.Options, | 155 | options: Directory.Options, |
| 156 | ) std.Build.LazyPath { | 156 | ) std.Build.LazyPath { |
| 157 | const b = write_file.step.owner; | 157 | const graph = write_file.step.owner.graph; |
| 158 | const gpa = b.allocator; | 158 | const arena = graph.arena; |
| 159 | const dir = Directory{ | 159 | const dir = Directory{ |
| 160 | .source = source.dupe(b), | 160 | .source = source.dupe(graph), |
| 161 | .sub_path = b.dupePath(sub_path), | 161 | .sub_path = graph.dupePath(sub_path), |
| 162 | .options = options.dupe(b), | 162 | .options = options.dupe(graph), |
| 163 | }; | 163 | }; |
| 164 | write_file.directories.append(gpa, dir) catch @panic("OOM"); | 164 | write_file.directories.append(arena, dir) catch @panic("OOM"); |
| 165 | 165 | ||
| 166 | write_file.maybeUpdateName(); | 166 | write_file.maybeUpdateName(); |
| 167 | source.addStepDependencies(&write_file.step); | 167 | source.addStepDependencies(&write_file.step); |
src/main.zig+1| ... | @@ -5356,6 +5356,7 @@ fn cmdBuild( | ... | @@ -5356,6 +5356,7 @@ fn cmdBuild( |
| 5356 | .cc_argv = &.{}, | 5356 | .cc_argv = &.{}, |
| 5357 | .inherited = .{ | 5357 | .inherited = .{ |
| 5358 | .resolved_target = resolved_target, | 5358 | .resolved_target = resolved_target, |
| 5359 | .single_threaded = true, | ||
| 5359 | }, | 5360 | }, |
| 5360 | .global = config, | 5361 | .global = config, |
| 5361 | .parent = null, | 5362 | .parent = null, |