authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-04-09 18:23:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-04-10 15:02:20-07:00
log7fb5a0b18b8620750f71d24152dc6651a0437ae1
tree855688e466a9abb007605cd8e516ac229f74dd3a
parentc4587dc9f46e15d4fb875a7675bc1aa22138c1ab

introduce std.Build.path; deprecate LazyPath.relative

This adds the *std.Build owner to LazyPath so that lazy paths returned from a dependency can be used in the application without friction or footguns. closes #19313

5 files changed, 68 insertions(+), 42 deletions(-)

lib/std/Build.zig+56-36
...@@ -607,17 +607,17 @@ pub fn resolveInstallPrefix(self: *Build, install_prefix: ?[]const u8, dir_list:...@@ -607,17 +607,17 @@ pub fn resolveInstallPrefix(self: *Build, install_prefix: ?[]const u8, dir_list:
607 var h_list = [_][]const u8{ self.install_path, "include" };607 var h_list = [_][]const u8{ self.install_path, "include" };
608608
609 if (dir_list.lib_dir) |dir| {609 if (dir_list.lib_dir) |dir| {
610 if (std.fs.path.isAbsolute(dir)) lib_list[0] = self.dest_dir orelse "";610 if (fs.path.isAbsolute(dir)) lib_list[0] = self.dest_dir orelse "";
611 lib_list[1] = dir;611 lib_list[1] = dir;
612 }612 }
613613
614 if (dir_list.exe_dir) |dir| {614 if (dir_list.exe_dir) |dir| {
615 if (std.fs.path.isAbsolute(dir)) exe_list[0] = self.dest_dir orelse "";615 if (fs.path.isAbsolute(dir)) exe_list[0] = self.dest_dir orelse "";
616 exe_list[1] = dir;616 exe_list[1] = dir;
617 }617 }
618618
619 if (dir_list.include_dir) |dir| {619 if (dir_list.include_dir) |dir| {
620 if (std.fs.path.isAbsolute(dir)) h_list[0] = self.dest_dir orelse "";620 if (fs.path.isAbsolute(dir)) h_list[0] = self.dest_dir orelse "";
621 h_list[1] = dir;621 h_list[1] = dir;
622 }622 }
623623
...@@ -858,7 +858,7 @@ pub const TestOptions = struct {...@@ -858,7 +858,7 @@ pub const TestOptions = struct {
858 /// deprecated: use `.filters = &.{filter}` instead of `.filter = filter`.858 /// deprecated: use `.filters = &.{filter}` instead of `.filter = filter`.
859 filter: ?[]const u8 = null,859 filter: ?[]const u8 = null,
860 filters: []const []const u8 = &.{},860 filters: []const []const u8 = &.{},
861 test_runner: ?[]const u8 = null,861 test_runner: ?LazyPath = null,
862 link_libc: ?bool = null,862 link_libc: ?bool = null,
863 single_threaded: ?bool = null,863 single_threaded: ?bool = null,
864 pic: ?bool = null,864 pic: ?bool = null,
...@@ -1635,6 +1635,18 @@ pub fn truncateFile(self: *Build, dest_path: []const u8) !void {...@@ -1635,6 +1635,18 @@ pub fn truncateFile(self: *Build, dest_path: []const u8) !void {
1635 src_file.close();1635 src_file.close();
1636}1636}
16371637
1638/// References a file or directory relative to the source root.
1639pub fn path(b: *Build, sub_path: []const u8) LazyPath {
1640 assert(!fs.path.isAbsolute(sub_path));
1641 return .{ .src_path = .{
1642 .owner = b,
1643 .sub_path = sub_path,
1644 } };
1645}
1646
1647/// This is low-level implementation details of the build system, not meant to
1648/// be called by users' build scripts. Even in the build system itself it is a
1649/// code smell to call this function.
1638pub fn pathFromRoot(b: *Build, p: []const u8) []u8 {1650pub fn pathFromRoot(b: *Build, p: []const u8) []u8 {
1639 return fs.path.resolve(b.allocator, &.{ b.build_root.path orelse ".", p }) catch @panic("OOM");1651 return fs.path.resolve(b.allocator, &.{ b.build_root.path orelse ".", p }) catch @panic("OOM");
1640}1652}
...@@ -1674,10 +1686,9 @@ pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []con...@@ -1674,10 +1686,9 @@ pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []con
1674 return name;1686 return name;
1675 }1687 }
1676 var it = mem.tokenizeScalar(u8, PATH, fs.path.delimiter);1688 var it = mem.tokenizeScalar(u8, PATH, fs.path.delimiter);
1677 while (it.next()) |path| {1689 while (it.next()) |p| {
1678 const full_path = self.pathJoin(&.{1690 const full_path = self.pathJoin(&.{
1679 path,1691 p, self.fmt("{s}{s}", .{ name, exe_extension }),
1680 self.fmt("{s}{s}", .{ name, exe_extension }),
1681 });1692 });
1682 return fs.realpathAlloc(self.allocator, full_path) catch continue;1693 return fs.realpathAlloc(self.allocator, full_path) catch continue;
1683 }1694 }
...@@ -1687,10 +1698,9 @@ pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []con...@@ -1687,10 +1698,9 @@ pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []con
1687 if (fs.path.isAbsolute(name)) {1698 if (fs.path.isAbsolute(name)) {
1688 return name;1699 return name;
1689 }1700 }
1690 for (paths) |path| {1701 for (paths) |p| {
1691 const full_path = self.pathJoin(&.{1702 const full_path = self.pathJoin(&.{
1692 path,1703 p, self.fmt("{s}{s}", .{ name, exe_extension }),
1693 self.fmt("{s}{s}", .{ name, exe_extension }),
1694 });1704 });
1695 return fs.realpathAlloc(self.allocator, full_path) catch continue;1705 return fs.realpathAlloc(self.allocator, full_path) catch continue;
1696 }1706 }
...@@ -1771,7 +1781,7 @@ pub fn getInstallPath(self: *Build, dir: InstallDir, dest_rel_path: []const u8)...@@ -1771,7 +1781,7 @@ pub fn getInstallPath(self: *Build, dir: InstallDir, dest_rel_path: []const u8)
1771 .bin => self.exe_dir,1781 .bin => self.exe_dir,
1772 .lib => self.lib_dir,1782 .lib => self.lib_dir,
1773 .header => self.h_dir,1783 .header => self.h_dir,
1774 .custom => |path| self.pathJoin(&.{ self.install_path, path }),1784 .custom => |p| self.pathJoin(&.{ self.install_path, p }),
1775 };1785 };
1776 return fs.path.resolve(1786 return fs.path.resolve(
1777 self.allocator,1787 self.allocator,
...@@ -2032,7 +2042,7 @@ fn dependencyInner(...@@ -2032,7 +2042,7 @@ fn dependencyInner(
20322042
2033 const build_root: std.Build.Cache.Directory = .{2043 const build_root: std.Build.Cache.Directory = .{
2034 .path = build_root_string,2044 .path = build_root_string,
2035 .handle = std.fs.cwd().openDir(build_root_string, .{}) catch |err| {2045 .handle = fs.cwd().openDir(build_root_string, .{}) catch |err| {
2036 std.debug.print("unable to open '{s}': {s}\n", .{2046 std.debug.print("unable to open '{s}': {s}\n", .{
2037 build_root_string, @errorName(err),2047 build_root_string, @errorName(err),
2038 });2048 });
...@@ -2093,9 +2103,9 @@ pub const GeneratedFile = struct {...@@ -2093,9 +2103,9 @@ pub const GeneratedFile = struct {
2093// so that we can join it with another path (e.g. build root, cache root, etc.)2103// so that we can join it with another path (e.g. build root, cache root, etc.)
2094//2104//
2095// dirname("") should still be null, because we can't go up any further.2105// dirname("") should still be null, because we can't go up any further.
2096fn dirnameAllowEmpty(path: []const u8) ?[]const u8 {2106fn dirnameAllowEmpty(full_path: []const u8) ?[]const u8 {
2097 return fs.path.dirname(path) orelse {2107 return fs.path.dirname(full_path) orelse {
2098 if (fs.path.isAbsolute(path) or path.len == 0) return null;2108 if (fs.path.isAbsolute(full_path) or full_path.len == 0) return null;
20992109
2100 return "";2110 return "";
2101 };2111 };
...@@ -2117,11 +2127,15 @@ test dirnameAllowEmpty {...@@ -2117,11 +2127,15 @@ test dirnameAllowEmpty {
21172127
2118/// A reference to an existing or future path.2128/// A reference to an existing or future path.
2119pub const LazyPath = union(enum) {2129pub const LazyPath = union(enum) {
2120 /// A source file path relative to build root.2130 /// Deprecated; use the `path` function instead.
2121 /// This should not be an absolute path, but in an older iteration of the zig build
2122 /// system API, it was allowed to be absolute. Absolute paths should use `cwd_relative`.
2123 path: []const u8,2131 path: []const u8,
21242132
2133 /// A source file path relative to build root.
2134 src_path: struct {
2135 owner: *std.Build,
2136 sub_path: []const u8,
2137 },
2138
2125 /// A file that is generated by an interface. Those files usually are2139 /// A file that is generated by an interface. Those files usually are
2126 /// not available until built by a build step.2140 /// not available until built by a build step.
2127 generated: *const GeneratedFile,2141 generated: *const GeneratedFile,
...@@ -2150,11 +2164,10 @@ pub const LazyPath = union(enum) {...@@ -2150,11 +2164,10 @@ pub const LazyPath = union(enum) {
2150 sub_path: []const u8,2164 sub_path: []const u8,
2151 },2165 },
21522166
2153 /// Returns a new file source that will have a relative path to the build root guaranteed.2167 /// Deprecated. Call `path` instead.
2154 /// Asserts the parameter is not an absolute path.2168 pub fn relative(p: []const u8) LazyPath {
2155 pub fn relative(path: []const u8) LazyPath {2169 std.log.warn("deprecated. call std.Build.path instead", .{});
2156 std.debug.assert(!std.fs.path.isAbsolute(path));2170 return .{ .path = p };
2157 return LazyPath{ .path = path };
2158 }2171 }
21592172
2160 /// Returns a lazy path referring to the directory containing this path.2173 /// Returns a lazy path referring to the directory containing this path.
...@@ -2168,13 +2181,16 @@ pub const LazyPath = union(enum) {...@@ -2168,13 +2181,16 @@ pub const LazyPath = union(enum) {
2168 return switch (self) {2181 return switch (self) {
2169 .generated => |gen| .{ .generated_dirname = .{ .generated = gen, .up = 0 } },2182 .generated => |gen| .{ .generated_dirname = .{ .generated = gen, .up = 0 } },
2170 .generated_dirname => |gen| .{ .generated_dirname = .{ .generated = gen.generated, .up = gen.up + 1 } },2183 .generated_dirname => |gen| .{ .generated_dirname = .{ .generated = gen.generated, .up = gen.up + 1 } },
2184 .src_path => |sp| .{ .src_path = .{
2185 .owner = sp.owner,
2186 .sub_path = dirnameAllowEmpty(sp.sub_path) orelse {
2187 dumpBadDirnameHelp(null, null, "dirname() attempted to traverse outside the build root\n", .{}) catch {};
2188 @panic("misconfigured build script");
2189 },
2190 } },
2171 .path => |p| .{2191 .path => |p| .{
2172 .path = dirnameAllowEmpty(p) orelse {2192 .path = dirnameAllowEmpty(p) orelse {
2173 dumpBadDirnameHelp(null, null,2193 dumpBadDirnameHelp(null, null, "dirname() attempted to traverse outside the build root\n", .{}) catch {};
2174 \\dirname() attempted to traverse outside the build root.
2175 \\This is not allowed.
2176 \\
2177 , .{}) catch {};
2178 @panic("misconfigured build script");2194 @panic("misconfigured build script");
2179 },2195 },
2180 },2196 },
...@@ -2195,7 +2211,6 @@ pub const LazyPath = union(enum) {...@@ -2195,7 +2211,6 @@ pub const LazyPath = union(enum) {
2195 } else {2211 } else {
2196 dumpBadDirnameHelp(null, null,2212 dumpBadDirnameHelp(null, null,
2197 \\dirname() attempted to traverse outside the current working directory.2213 \\dirname() attempted to traverse outside the current working directory.
2198 \\This is not allowed.
2199 \\2214 \\
2200 , .{}) catch {};2215 , .{}) catch {};
2201 @panic("misconfigured build script");2216 @panic("misconfigured build script");
...@@ -2207,7 +2222,6 @@ pub const LazyPath = union(enum) {...@@ -2207,7 +2222,6 @@ pub const LazyPath = union(enum) {
2207 .sub_path = dirnameAllowEmpty(dep.sub_path) orelse {2222 .sub_path = dirnameAllowEmpty(dep.sub_path) orelse {
2208 dumpBadDirnameHelp(null, null,2223 dumpBadDirnameHelp(null, null,
2209 \\dirname() attempted to traverse outside the dependency root.2224 \\dirname() attempted to traverse outside the dependency root.
2210 \\This is not allowed.
2211 \\2225 \\
2212 , .{}) catch {};2226 , .{}) catch {};
2213 @panic("misconfigured build script");2227 @panic("misconfigured build script");
...@@ -2220,7 +2234,8 @@ pub const LazyPath = union(enum) {...@@ -2220,7 +2234,8 @@ pub const LazyPath = union(enum) {
2220 /// Either returns the path or `"generated"`.2234 /// Either returns the path or `"generated"`.
2221 pub fn getDisplayName(self: LazyPath) []const u8 {2235 pub fn getDisplayName(self: LazyPath) []const u8 {
2222 return switch (self) {2236 return switch (self) {
2223 .path, .cwd_relative => self.path,2237 .src_path => |sp| sp.sub_path,
2238 .path, .cwd_relative => |p| p,
2224 .generated => "generated",2239 .generated => "generated",
2225 .generated_dirname => "generated",2240 .generated_dirname => "generated",
2226 .dependency => "dependency",2241 .dependency => "dependency",
...@@ -2230,7 +2245,7 @@ pub const LazyPath = union(enum) {...@@ -2230,7 +2245,7 @@ pub const LazyPath = union(enum) {
2230 /// Adds dependencies this file source implies to the given step.2245 /// Adds dependencies this file source implies to the given step.
2231 pub fn addStepDependencies(self: LazyPath, other_step: *Step) void {2246 pub fn addStepDependencies(self: LazyPath, other_step: *Step) void {
2232 switch (self) {2247 switch (self) {
2233 .path, .cwd_relative, .dependency => {},2248 .src_path, .path, .cwd_relative, .dependency => {},
2234 .generated => |gen| other_step.dependOn(gen.step),2249 .generated => |gen| other_step.dependOn(gen.step),
2235 .generated_dirname => |gen| other_step.dependOn(gen.generated.step),2250 .generated_dirname => |gen| other_step.dependOn(gen.generated.step),
2236 }2251 }
...@@ -2250,6 +2265,7 @@ pub const LazyPath = union(enum) {...@@ -2250,6 +2265,7 @@ pub const LazyPath = union(enum) {
2250 pub fn getPath2(self: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 {2265 pub fn getPath2(self: LazyPath, src_builder: *Build, asking_step: ?*Step) []const u8 {
2251 switch (self) {2266 switch (self) {
2252 .path => |p| return src_builder.pathFromRoot(p),2267 .path => |p| return src_builder.pathFromRoot(p),
2268 .src_path => |sp| return sp.owner.pathFromRoot(sp.sub_path),
2253 .cwd_relative => |p| return src_builder.pathFromCwd(p),2269 .cwd_relative => |p| return src_builder.pathFromCwd(p),
2254 .generated => |gen| return gen.path orelse {2270 .generated => |gen| return gen.path orelse {
2255 std.debug.getStderrMutex().lock();2271 std.debug.getStderrMutex().lock();
...@@ -2262,13 +2278,13 @@ pub const LazyPath = union(enum) {...@@ -2262,13 +2278,13 @@ pub const LazyPath = union(enum) {
2262 (src_builder.cache_root.join(src_builder.allocator, &.{"."}) catch @panic("OOM"));2278 (src_builder.cache_root.join(src_builder.allocator, &.{"."}) catch @panic("OOM"));
22632279
2264 const gen_step = gen.generated.step;2280 const gen_step = gen.generated.step;
2265 var path = getPath2(LazyPath{ .generated = gen.generated }, src_builder, asking_step);2281 var p = getPath2(LazyPath{ .generated = gen.generated }, src_builder, asking_step);
2266 var i: usize = 0;2282 var i: usize = 0;
2267 while (i <= gen.up) : (i += 1) {2283 while (i <= gen.up) : (i += 1) {
2268 // path is absolute.2284 // path is absolute.
2269 // dirname will return null only if we're at root.2285 // dirname will return null only if we're at root.
2270 // Typically, we'll stop well before that at the cache root.2286 // Typically, we'll stop well before that at the cache root.
2271 path = fs.path.dirname(path) orelse {2287 p = fs.path.dirname(p) orelse {
2272 dumpBadDirnameHelp(gen_step, asking_step,2288 dumpBadDirnameHelp(gen_step, asking_step,
2273 \\dirname() reached root.2289 \\dirname() reached root.
2274 \\No more directories left to go up.2290 \\No more directories left to go up.
...@@ -2277,7 +2293,7 @@ pub const LazyPath = union(enum) {...@@ -2277,7 +2293,7 @@ pub const LazyPath = union(enum) {
2277 @panic("misconfigured build script");2293 @panic("misconfigured build script");
2278 };2294 };
22792295
2280 if (mem.eql(u8, path, cache_root_path) and i < gen.up) {2296 if (mem.eql(u8, p, cache_root_path) and i < gen.up) {
2281 // If we hit the cache root and there's still more to go,2297 // If we hit the cache root and there's still more to go,
2282 // the script attempted to go too far.2298 // the script attempted to go too far.
2283 dumpBadDirnameHelp(gen_step, asking_step,2299 dumpBadDirnameHelp(gen_step, asking_step,
...@@ -2288,7 +2304,7 @@ pub const LazyPath = union(enum) {...@@ -2288,7 +2304,7 @@ pub const LazyPath = union(enum) {
2288 @panic("misconfigured build script");2304 @panic("misconfigured build script");
2289 }2305 }
2290 }2306 }
2291 return path;2307 return p;
2292 },2308 },
2293 .dependency => |dep| {2309 .dependency => |dep| {
2294 return dep.dependency.builder.pathJoin(&[_][]const u8{2310 return dep.dependency.builder.pathJoin(&[_][]const u8{
...@@ -2302,6 +2318,10 @@ pub const LazyPath = union(enum) {...@@ -2302,6 +2318,10 @@ pub const LazyPath = union(enum) {
2302 /// Duplicates the file source for a given builder.2318 /// Duplicates the file source for a given builder.
2303 pub fn dupe(self: LazyPath, b: *Build) LazyPath {2319 pub fn dupe(self: LazyPath, b: *Build) LazyPath {
2304 return switch (self) {2320 return switch (self) {
2321 .src_path => |sp| .{ .src_path = .{
2322 .owner = sp.owner,
2323 .sub_path = b.dupePath(sp.sub_path),
2324 } },
2305 .path => |p| .{ .path = b.dupePath(p) },2325 .path => |p| .{ .path = b.dupePath(p) },
2306 .cwd_relative => |p| .{ .cwd_relative = b.dupePath(p) },2326 .cwd_relative => |p| .{ .cwd_relative = b.dupePath(p) },
2307 .generated => |gen| .{ .generated = gen },2327 .generated => |gen| .{ .generated = gen },
lib/std/Build/Step/Compile.zig+9-4
...@@ -55,7 +55,7 @@ global_base: ?u64 = null,...@@ -55,7 +55,7 @@ global_base: ?u64 = null,
55zig_lib_dir: ?LazyPath,55zig_lib_dir: ?LazyPath,
56exec_cmd_args: ?[]const ?[]const u8,56exec_cmd_args: ?[]const ?[]const u8,
57filters: []const []const u8,57filters: []const []const u8,
58test_runner: ?[]const u8,58test_runner: ?LazyPath,
59test_server_mode: bool,59test_server_mode: bool,
60wasi_exec_model: ?std.builtin.WasiExecModel = null,60wasi_exec_model: ?std.builtin.WasiExecModel = null,
6161
...@@ -236,7 +236,7 @@ pub const Options = struct {...@@ -236,7 +236,7 @@ pub const Options = struct {
236 version: ?std.SemanticVersion = null,236 version: ?std.SemanticVersion = null,
237 max_rss: usize = 0,237 max_rss: usize = 0,
238 filters: []const []const u8 = &.{},238 filters: []const []const u8 = &.{},
239 test_runner: ?[]const u8 = null,239 test_runner: ?LazyPath = null,
240 use_llvm: ?bool = null,240 use_llvm: ?bool = null,
241 use_lld: ?bool = null,241 use_lld: ?bool = null,
242 zig_lib_dir: ?LazyPath = null,242 zig_lib_dir: ?LazyPath = null,
...@@ -402,7 +402,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -402,7 +402,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
402 .zig_lib_dir = null,402 .zig_lib_dir = null,
403 .exec_cmd_args = null,403 .exec_cmd_args = null,
404 .filters = options.filters,404 .filters = options.filters,
405 .test_runner = options.test_runner,405 .test_runner = null,
406 .test_server_mode = options.test_runner == null,406 .test_server_mode = options.test_runner == null,
407 .rdynamic = false,407 .rdynamic = false,
408 .installed_path = null,408 .installed_path = null,
...@@ -429,6 +429,11 @@ pub fn create(owner: *std.Build, options: Options) *Compile {...@@ -429,6 +429,11 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
429 lp.addStepDependencies(&self.step);429 lp.addStepDependencies(&self.step);
430 }430 }
431431
432 if (options.test_runner) |lp| {
433 self.test_runner = lp.dupe(self.step.owner);
434 lp.addStepDependencies(&self.step);
435 }
436
432 // Only the PE/COFF format has a Resource Table which is where the manifest437 // Only the PE/COFF format has a Resource Table which is where the manifest
433 // gets embedded, so for any other target the manifest file is just ignored.438 // gets embedded, so for any other target the manifest file is just ignored.
434 if (target.ofmt == .coff) {439 if (target.ofmt == .coff) {
...@@ -1402,7 +1407,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {...@@ -1402,7 +1407,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
14021407
1403 if (self.test_runner) |test_runner| {1408 if (self.test_runner) |test_runner| {
1404 try zig_args.append("--test-runner");1409 try zig_args.append("--test-runner");
1405 try zig_args.append(b.pathFromRoot(test_runner));1410 try zig_args.append(test_runner.getPath(b));
1406 }1411 }
14071412
1408 for (b.debug_log_scopes) |log_scope| {1413 for (b.debug_log_scopes) |log_scope| {
lib/std/Build/Step/ConfigHeader.zig+1
...@@ -58,6 +58,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {...@@ -58,6 +58,7 @@ pub fn create(owner: *std.Build, options: Options) *ConfigHeader {
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 .path => |path| path,62 .path => |path| path,
62 .generated, .generated_dirname => break :default_include_path,63 .generated, .generated_dirname => break :default_include_path,
63 .cwd_relative => |sub_path| sub_path,64 .cwd_relative => |sub_path| sub_path,
test/standalone/test_runner_module_imports/build.zig+1-1
...@@ -3,7 +3,7 @@ const std = @import("std");...@@ -3,7 +3,7 @@ const std = @import("std");
3pub fn build(b: *std.Build) void {3pub fn build(b: *std.Build) void {
4 const t = b.addTest(.{4 const t = b.addTest(.{
5 .root_source_file = .{ .path = "src/main.zig" },5 .root_source_file = .{ .path = "src/main.zig" },
6 .test_runner = "test_runner/main.zig",6 .test_runner = b.path("test_runner/main.zig"),
7 });7 });
88
9 const module1 = b.createModule(.{ .root_source_file = .{ .path = "module1/main.zig" } });9 const module1 = b.createModule(.{ .root_source_file = .{ .path = "module1/main.zig" } });
test/standalone/test_runner_path/build.zig+1-1
...@@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void {...@@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void {
9 const test_exe = b.addTest(.{9 const test_exe = b.addTest(.{
10 .root_source_file = .{ .path = "test.zig" },10 .root_source_file = .{ .path = "test.zig" },
11 });11 });
12 test_exe.test_runner = "test_runner.zig";12 test_exe.test_runner = b.path("test_runner.zig");
1313
14 const test_run = b.addRunArtifact(test_exe);14 const test_run = b.addRunArtifact(test_exe);
15 test_step.dependOn(&test_run.step);15 test_step.dependOn(&test_run.step);