| ... | @@ -206,40 +206,30 @@ pub fn clearEnvironment(self: *RunStep) void { | ... | @@ -206,40 +206,30 @@ pub fn clearEnvironment(self: *RunStep) void { |
| 206 | } | 206 | } |
| 207 | | 207 | |
| 208 | pub fn addPathDir(self: *RunStep, search_path: []const u8) void { | 208 | pub fn addPathDir(self: *RunStep, search_path: []const u8) void { |
| 209 | addPathDirInternal(&self.step, self.step.owner, search_path); | 209 | const b = self.step.owner; |
| 210 | } | 210 | const env_map = getEnvMapInternal(self); |
| 211 | | | |
| 212 | /// For internal use only, users of `RunStep` should use `addPathDir` directly. | | |
| 213 | pub fn addPathDirInternal(step: *Step, builder: *std.Build, search_path: []const u8) void { | | |
| 214 | const env_map = getEnvMapInternal(step, builder.allocator); | | |
| 215 | | 211 | |
| 216 | const key = "PATH"; | 212 | const key = "PATH"; |
| 217 | var prev_path = env_map.get(key); | 213 | var prev_path = env_map.get(key); |
| 218 | | 214 | |
| 219 | if (prev_path) |pp| { | 215 | if (prev_path) |pp| { |
| 220 | const new_path = builder.fmt("{s}" ++ [1]u8{fs.path.delimiter} ++ "{s}", .{ pp, search_path }); | 216 | const new_path = b.fmt("{s}" ++ [1]u8{fs.path.delimiter} ++ "{s}", .{ pp, search_path }); |
| 221 | env_map.put(key, new_path) catch @panic("OOM"); | 217 | env_map.put(key, new_path) catch @panic("OOM"); |
| 222 | } else { | 218 | } else { |
| 223 | env_map.put(key, builder.dupePath(search_path)) catch @panic("OOM"); | 219 | env_map.put(key, b.dupePath(search_path)) catch @panic("OOM"); |
| 224 | } | 220 | } |
| 225 | } | 221 | } |
| 226 | | 222 | |
| 227 | pub fn getEnvMap(self: *RunStep) *EnvMap { | 223 | pub fn getEnvMap(self: *RunStep) *EnvMap { |
| 228 | return getEnvMapInternal(&self.step, self.step.owner.allocator); | 224 | return getEnvMapInternal(self); |
| 229 | } | 225 | } |
| 230 | | 226 | |
| 231 | fn getEnvMapInternal(step: *Step, allocator: Allocator) *EnvMap { | 227 | fn getEnvMapInternal(self: *RunStep) *EnvMap { |
| 232 | const maybe_env_map = switch (step.id) { | 228 | const arena = self.step.owner.allocator; |
| 233 | .run => step.cast(RunStep).?.env_map, | 229 | return self.env_map orelse { |
| 234 | else => unreachable, | 230 | const env_map = arena.create(EnvMap) catch @panic("OOM"); |
| 235 | }; | 231 | env_map.* = process.getEnvMap(arena) catch @panic("unhandled error"); |
| 236 | return maybe_env_map orelse { | 232 | self.env_map = env_map; |
| 237 | const env_map = allocator.create(EnvMap) catch @panic("OOM"); | | |
| 238 | env_map.* = process.getEnvMap(allocator) catch @panic("unhandled error"); | | |
| 239 | switch (step.id) { | | |
| 240 | .run => step.cast(RunStep).?.env_map = env_map, | | |
| 241 | else => unreachable, | | |
| 242 | } | | |
| 243 | return env_map; | 233 | return env_map; |
| 244 | }; | 234 | }; |
| 245 | } | 235 | } |
| ... | @@ -250,6 +240,10 @@ pub fn setEnvironmentVariable(self: *RunStep, key: []const u8, value: []const u8 | ... | @@ -250,6 +240,10 @@ pub fn setEnvironmentVariable(self: *RunStep, key: []const u8, value: []const u8 |
| 250 | env_map.put(b.dupe(key), b.dupe(value)) catch @panic("unhandled error"); | 240 | env_map.put(b.dupe(key), b.dupe(value)) catch @panic("unhandled error"); |
| 251 | } | 241 | } |
| 252 | | 242 | |
| | 243 | pub fn removeEnvironmentVariable(self: *RunStep, key: []const u8) void { |
| | 244 | self.getEnvMap().remove(key); |
| | 245 | } |
| | 246 | |
| 253 | /// Adds a check for exact stderr match. Does not add any other checks. | 247 | /// Adds a check for exact stderr match. Does not add any other checks. |
| 254 | pub fn expectStdErrEqual(self: *RunStep, bytes: []const u8) void { | 248 | pub fn expectStdErrEqual(self: *RunStep, bytes: []const u8) void { |
| 255 | const new_check: StdIo.Check = .{ .expect_stderr_exact = self.step.owner.dupe(bytes) }; | 249 | const new_check: StdIo.Check = .{ .expect_stderr_exact = self.step.owner.dupe(bytes) }; |
| ... | @@ -553,7 +547,7 @@ fn runCommand( | ... | @@ -553,7 +547,7 @@ fn runCommand( |
| 553 | const arena = b.allocator; | 547 | const arena = b.allocator; |
| 554 | | 548 | |
| 555 | try step.handleChildProcUnsupported(self.cwd, argv); | 549 | try step.handleChildProcUnsupported(self.cwd, argv); |
| 556 | try Step.handleVerbose(step.owner, self.cwd, argv); | 550 | try Step.handleVerbose2(step.owner, self.cwd, self.env_map, argv); |
| 557 | | 551 | |
| 558 | const allow_skip = switch (self.stdio) { | 552 | const allow_skip = switch (self.stdio) { |
| 559 | .check, .zig_test => self.skip_foreign_checks, | 553 | .check, .zig_test => self.skip_foreign_checks, |
| ... | @@ -676,10 +670,10 @@ fn runCommand( | ... | @@ -676,10 +670,10 @@ fn runCommand( |
| 676 | | 670 | |
| 677 | if (exe.target.isWindows()) { | 671 | if (exe.target.isWindows()) { |
| 678 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH | 672 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH |
| 679 | RunStep.addPathForDynLibsInternal(&self.step, b, exe); | 673 | self.addPathForDynLibs(exe); |
| 680 | } | 674 | } |
| 681 | | 675 | |
| 682 | try Step.handleVerbose(step.owner, self.cwd, interp_argv.items); | 676 | try Step.handleVerbose2(step.owner, self.cwd, self.env_map, interp_argv.items); |
| 683 | | 677 | |
| 684 | break :term spawnChildAndCollect(self, interp_argv.items, has_side_effects, prog_node) catch |e| { | 678 | break :term spawnChildAndCollect(self, interp_argv.items, has_side_effects, prog_node) catch |e| { |
| 685 | return step.fail("unable to spawn {s}: {s}", .{ | 679 | return step.fail("unable to spawn {s}: {s}", .{ |
| ... | @@ -1177,18 +1171,13 @@ fn evalGeneric(self: *RunStep, child: *std.process.Child) !StdIoResult { | ... | @@ -1177,18 +1171,13 @@ fn evalGeneric(self: *RunStep, child: *std.process.Child) !StdIoResult { |
| 1177 | } | 1171 | } |
| 1178 | | 1172 | |
| 1179 | fn addPathForDynLibs(self: *RunStep, artifact: *CompileStep) void { | 1173 | fn addPathForDynLibs(self: *RunStep, artifact: *CompileStep) void { |
| 1180 | addPathForDynLibsInternal(&self.step, self.step.owner, artifact); | 1174 | const b = self.step.owner; |
| 1181 | } | | |
| 1182 | | | |
| 1183 | /// This should only be used for internal usage, this is called automatically | | |
| 1184 | /// for the user. | | |
| 1185 | pub fn addPathForDynLibsInternal(step: *Step, builder: *std.Build, artifact: *CompileStep) void { | | |
| 1186 | for (artifact.link_objects.items) |link_object| { | 1175 | for (artifact.link_objects.items) |link_object| { |
| 1187 | switch (link_object) { | 1176 | switch (link_object) { |
| 1188 | .other_step => |other| { | 1177 | .other_step => |other| { |
| 1189 | if (other.target.isWindows() and other.isDynamicLibrary()) { | 1178 | if (other.target.isWindows() and other.isDynamicLibrary()) { |
| 1190 | addPathDirInternal(step, builder, fs.path.dirname(other.getOutputSource().getPath(builder)).?); | 1179 | addPathDir(self, fs.path.dirname(other.getOutputSource().getPath(b)).?); |
| 1191 | addPathForDynLibsInternal(step, builder, other); | 1180 | addPathForDynLibs(self, other); |
| 1192 | } | 1181 | } |
| 1193 | }, | 1182 | }, |
| 1194 | else => {}, | 1183 | else => {}, |