| ... | @@ -320,6 +320,14 @@ pub const Builder = struct { | ... | @@ -320,6 +320,14 @@ pub const Builder = struct { |
| 320 | return LibExeObjStep.createTest(self, "test", root_src.dupe(self)); | 320 | return LibExeObjStep.createTest(self, "test", root_src.dupe(self)); |
| 321 | } | 321 | } |
| 322 | | 322 | |
| | 323 | pub fn addTestExe(self: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep { |
| | 324 | return LibExeObjStep.createTestExe(self, name, .{ .path = root_src }); |
| | 325 | } |
| | 326 | |
| | 327 | pub fn addTestExeSource(self: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { |
| | 328 | return LibExeObjStep.createTestExe(self, name, root_src.dupe(self)); |
| | 329 | } |
| | 330 | |
| 323 | pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { | 331 | pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { |
| 324 | return addAssembleSource(self, name, .{ .path = src }); | 332 | return addAssembleSource(self, name, .{ .path = src }); |
| 325 | } | 333 | } |
| ... | @@ -1569,6 +1577,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1569,6 +1577,7 @@ pub const LibExeObjStep = struct { |
| 1569 | lib, | 1577 | lib, |
| 1570 | obj, | 1578 | obj, |
| 1571 | @"test", | 1579 | @"test", |
| | 1580 | test_exe, |
| 1572 | }; | 1581 | }; |
| 1573 | | 1582 | |
| 1574 | pub const SharedLibKind = union(enum) { | 1583 | pub const SharedLibKind = union(enum) { |
| ... | @@ -1617,6 +1626,10 @@ pub const LibExeObjStep = struct { | ... | @@ -1617,6 +1626,10 @@ pub const LibExeObjStep = struct { |
| 1617 | return initExtraArgs(builder, name, root_src, .@"test", null, null); | 1626 | return initExtraArgs(builder, name, root_src, .@"test", null, null); |
| 1618 | } | 1627 | } |
| 1619 | | 1628 | |
| | 1629 | pub fn createTestExe(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { |
| | 1630 | return initExtraArgs(builder, name, root_src, .test_exe, null, null); |
| | 1631 | } |
| | 1632 | |
| 1620 | fn initExtraArgs( | 1633 | fn initExtraArgs( |
| 1621 | builder: *Builder, | 1634 | builder: *Builder, |
| 1622 | name_raw: []const u8, | 1635 | name_raw: []const u8, |
| ... | @@ -1698,7 +1711,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1698,7 +1711,7 @@ pub const LibExeObjStep = struct { |
| 1698 | .output_mode = switch (self.kind) { | 1711 | .output_mode = switch (self.kind) { |
| 1699 | .lib => .Lib, | 1712 | .lib => .Lib, |
| 1700 | .obj => .Obj, | 1713 | .obj => .Obj, |
| 1701 | .exe, .@"test" => .Exe, | 1714 | .exe, .@"test", .test_exe => .Exe, |
| 1702 | }, | 1715 | }, |
| 1703 | .link_mode = if (self.linkage) |some| @as(std.builtin.LinkMode, switch (some) { | 1716 | .link_mode = if (self.linkage) |some| @as(std.builtin.LinkMode, switch (some) { |
| 1704 | .dynamic => .Dynamic, | 1717 | .dynamic => .Dynamic, |
| ... | @@ -1816,7 +1829,7 @@ pub const LibExeObjStep = struct { | ... | @@ -1816,7 +1829,7 @@ pub const LibExeObjStep = struct { |
| 1816 | pub fn producesPdbFile(self: *LibExeObjStep) bool { | 1829 | pub fn producesPdbFile(self: *LibExeObjStep) bool { |
| 1817 | if (!self.target.isWindows() and !self.target.isUefi()) return false; | 1830 | if (!self.target.isWindows() and !self.target.isUefi()) return false; |
| 1818 | if (self.strip) return false; | 1831 | if (self.strip) return false; |
| 1819 | return self.isDynamicLibrary() or self.kind == .exe; | 1832 | return self.isDynamicLibrary() or self.kind == .exe or self.kind == .test_exe; |
| 1820 | } | 1833 | } |
| 1821 | | 1834 | |
| 1822 | pub fn linkLibC(self: *LibExeObjStep) void { | 1835 | pub fn linkLibC(self: *LibExeObjStep) void { |
| ... | @@ -1976,12 +1989,12 @@ pub const LibExeObjStep = struct { | ... | @@ -1976,12 +1989,12 @@ pub const LibExeObjStep = struct { |
| 1976 | } | 1989 | } |
| 1977 | | 1990 | |
| 1978 | pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { | 1991 | pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { |
| 1979 | assert(self.kind == .@"test"); | 1992 | assert(self.kind == .@"test" or self.kind == .test_exe); |
| 1980 | self.name_prefix = self.builder.dupe(text); | 1993 | self.name_prefix = self.builder.dupe(text); |
| 1981 | } | 1994 | } |
| 1982 | | 1995 | |
| 1983 | pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void { | 1996 | pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void { |
| 1984 | assert(self.kind == .@"test"); | 1997 | assert(self.kind == .@"test" or self.kind == .test_exe); |
| 1985 | self.filter = if (text) |t| self.builder.dupe(t) else null; | 1998 | self.filter = if (text) |t| self.builder.dupe(t) else null; |
| 1986 | } | 1999 | } |
| 1987 | | 2000 | |
| ... | @@ -2222,6 +2235,7 @@ pub const LibExeObjStep = struct { | ... | @@ -2222,6 +2235,7 @@ pub const LibExeObjStep = struct { |
| 2222 | .exe => "build-exe", | 2235 | .exe => "build-exe", |
| 2223 | .obj => "build-obj", | 2236 | .obj => "build-obj", |
| 2224 | .@"test" => "test", | 2237 | .@"test" => "test", |
| | 2238 | .test_exe => "test", |
| 2225 | }; | 2239 | }; |
| 2226 | zig_args.append(cmd) catch unreachable; | 2240 | zig_args.append(cmd) catch unreachable; |
| 2227 | | 2241 | |
| ... | @@ -2268,8 +2282,9 @@ pub const LibExeObjStep = struct { | ... | @@ -2268,8 +2282,9 @@ pub const LibExeObjStep = struct { |
| 2268 | .static_path => |static_path| try zig_args.append(static_path.getPath(builder)), | 2282 | .static_path => |static_path| try zig_args.append(static_path.getPath(builder)), |
| 2269 | | 2283 | |
| 2270 | .other_step => |other| switch (other.kind) { | 2284 | .other_step => |other| switch (other.kind) { |
| 2271 | .exe => unreachable, | 2285 | .exe => @panic("Cannot link with an executable build artifact"), |
| 2272 | .@"test" => unreachable, | 2286 | .test_exe => @panic("Cannot link with an executable build artifact"), |
| | 2287 | .@"test" => @panic("Cannot link with a test"), |
| 2273 | .obj => { | 2288 | .obj => { |
| 2274 | try zig_args.append(other.getOutputSource().getPath(builder)); | 2289 | try zig_args.append(other.getOutputSource().getPath(builder)); |
| 2275 | }, | 2290 | }, |
| ... | @@ -2542,89 +2557,93 @@ pub const LibExeObjStep = struct { | ... | @@ -2542,89 +2557,93 @@ pub const LibExeObjStep = struct { |
| 2542 | try zig_args.append(builder.pathFromRoot(version_script)); | 2557 | try zig_args.append(builder.pathFromRoot(version_script)); |
| 2543 | } | 2558 | } |
| 2544 | | 2559 | |
| 2545 | if (self.exec_cmd_args) |exec_cmd_args| { | 2560 | if (self.kind == .@"test") { |
| 2546 | for (exec_cmd_args) |cmd_arg| { | 2561 | if (self.exec_cmd_args) |exec_cmd_args| { |
| 2547 | if (cmd_arg) |arg| { | 2562 | for (exec_cmd_args) |cmd_arg| { |
| 2548 | try zig_args.append("--test-cmd"); | 2563 | if (cmd_arg) |arg| { |
| 2549 | try zig_args.append(arg); | | |
| 2550 | } else { | | |
| 2551 | try zig_args.append("--test-cmd-bin"); | | |
| 2552 | } | | |
| 2553 | } | | |
| 2554 | } else { | | |
| 2555 | const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc; | | |
| 2556 | | | |
| 2557 | switch (self.builder.host.getExternalExecutor(self.target_info, .{ | | |
| 2558 | .qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null, | | |
| 2559 | .link_libc = self.is_linking_libc, | | |
| 2560 | })) { | | |
| 2561 | .native => {}, | | |
| 2562 | .bad_dl, .bad_os_or_cpu => { | | |
| 2563 | try zig_args.append("--test-no-exec"); | | |
| 2564 | }, | | |
| 2565 | .rosetta => if (builder.enable_rosetta) { | | |
| 2566 | try zig_args.append("--test-cmd-bin"); | | |
| 2567 | } else { | | |
| 2568 | try zig_args.append("--test-no-exec"); | | |
| 2569 | }, | | |
| 2570 | .qemu => |bin_name| ok: { | | |
| 2571 | if (builder.enable_qemu) qemu: { | | |
| 2572 | const glibc_dir_arg = if (need_cross_glibc) | | |
| 2573 | builder.glibc_runtimes_dir orelse break :qemu | | |
| 2574 | else | | |
| 2575 | null; | | |
| 2576 | try zig_args.append("--test-cmd"); | 2564 | try zig_args.append("--test-cmd"); |
| 2577 | try zig_args.append(bin_name); | 2565 | try zig_args.append(arg); |
| 2578 | if (glibc_dir_arg) |dir| { | 2566 | } else { |
| 2579 | // TODO look into making this a call to `linuxTriple`. This | 2567 | try zig_args.append("--test-cmd-bin"); |
| 2580 | // needs the directory to be called "i686" rather than | 2568 | } |
| 2581 | // "i386" which is why we do it manually here. | 2569 | } |
| 2582 | const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}"; | 2570 | } else { |
| 2583 | const cpu_arch = self.target.getCpuArch(); | 2571 | const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc; |
| 2584 | const os_tag = self.target.getOsTag(); | 2572 | |
| 2585 | const abi = self.target.getAbi(); | 2573 | switch (self.builder.host.getExternalExecutor(self.target_info, .{ |
| 2586 | const cpu_arch_name: []const u8 = if (cpu_arch == .i386) | 2574 | .qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null, |
| 2587 | "i686" | 2575 | .link_libc = self.is_linking_libc, |
| | 2576 | })) { |
| | 2577 | .native => {}, |
| | 2578 | .bad_dl, .bad_os_or_cpu => { |
| | 2579 | try zig_args.append("--test-no-exec"); |
| | 2580 | }, |
| | 2581 | .rosetta => if (builder.enable_rosetta) { |
| | 2582 | try zig_args.append("--test-cmd-bin"); |
| | 2583 | } else { |
| | 2584 | try zig_args.append("--test-no-exec"); |
| | 2585 | }, |
| | 2586 | .qemu => |bin_name| ok: { |
| | 2587 | if (builder.enable_qemu) qemu: { |
| | 2588 | const glibc_dir_arg = if (need_cross_glibc) |
| | 2589 | builder.glibc_runtimes_dir orelse break :qemu |
| 2588 | else | 2590 | else |
| 2589 | @tagName(cpu_arch); | 2591 | null; |
| 2590 | const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{ | | |
| 2591 | dir, cpu_arch_name, @tagName(os_tag), @tagName(abi), | | |
| 2592 | }); | | |
| 2593 | | | |
| 2594 | try zig_args.append("--test-cmd"); | 2592 | try zig_args.append("--test-cmd"); |
| 2595 | try zig_args.append("-L"); | 2593 | try zig_args.append(bin_name); |
| 2596 | try zig_args.append("--test-cmd"); | 2594 | if (glibc_dir_arg) |dir| { |
| 2597 | try zig_args.append(full_dir); | 2595 | // TODO look into making this a call to `linuxTriple`. This |
| | 2596 | // needs the directory to be called "i686" rather than |
| | 2597 | // "i386" which is why we do it manually here. |
| | 2598 | const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}"; |
| | 2599 | const cpu_arch = self.target.getCpuArch(); |
| | 2600 | const os_tag = self.target.getOsTag(); |
| | 2601 | const abi = self.target.getAbi(); |
| | 2602 | const cpu_arch_name: []const u8 = if (cpu_arch == .i386) |
| | 2603 | "i686" |
| | 2604 | else |
| | 2605 | @tagName(cpu_arch); |
| | 2606 | const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{ |
| | 2607 | dir, cpu_arch_name, @tagName(os_tag), @tagName(abi), |
| | 2608 | }); |
| | 2609 | |
| | 2610 | try zig_args.append("--test-cmd"); |
| | 2611 | try zig_args.append("-L"); |
| | 2612 | try zig_args.append("--test-cmd"); |
| | 2613 | try zig_args.append(full_dir); |
| | 2614 | } |
| | 2615 | try zig_args.append("--test-cmd-bin"); |
| | 2616 | break :ok; |
| 2598 | } | 2617 | } |
| | 2618 | try zig_args.append("--test-no-exec"); |
| | 2619 | }, |
| | 2620 | .wine => |bin_name| if (builder.enable_wine) { |
| | 2621 | try zig_args.append("--test-cmd"); |
| | 2622 | try zig_args.append(bin_name); |
| 2599 | try zig_args.append("--test-cmd-bin"); | 2623 | try zig_args.append("--test-cmd-bin"); |
| 2600 | break :ok; | 2624 | } else { |
| 2601 | } | 2625 | try zig_args.append("--test-no-exec"); |
| 2602 | try zig_args.append("--test-no-exec"); | 2626 | }, |
| 2603 | }, | 2627 | .wasmtime => |bin_name| if (builder.enable_wasmtime) { |
| 2604 | .wine => |bin_name| if (builder.enable_wine) { | 2628 | try zig_args.append("--test-cmd"); |
| 2605 | try zig_args.append("--test-cmd"); | 2629 | try zig_args.append(bin_name); |
| 2606 | try zig_args.append(bin_name); | 2630 | try zig_args.append("--test-cmd"); |
| 2607 | try zig_args.append("--test-cmd-bin"); | 2631 | try zig_args.append("--dir=."); |
| 2608 | } else { | 2632 | try zig_args.append("--test-cmd-bin"); |
| 2609 | try zig_args.append("--test-no-exec"); | 2633 | } else { |
| 2610 | }, | 2634 | try zig_args.append("--test-no-exec"); |
| 2611 | .wasmtime => |bin_name| if (builder.enable_wasmtime) { | 2635 | }, |
| 2612 | try zig_args.append("--test-cmd"); | 2636 | .darling => |bin_name| if (builder.enable_darling) { |
| 2613 | try zig_args.append(bin_name); | 2637 | try zig_args.append("--test-cmd"); |
| 2614 | try zig_args.append("--test-cmd"); | 2638 | try zig_args.append(bin_name); |
| 2615 | try zig_args.append("--dir=."); | 2639 | try zig_args.append("--test-cmd-bin"); |
| 2616 | try zig_args.append("--test-cmd-bin"); | 2640 | } else { |
| 2617 | } else { | 2641 | try zig_args.append("--test-no-exec"); |
| 2618 | try zig_args.append("--test-no-exec"); | 2642 | }, |
| 2619 | }, | 2643 | } |
| 2620 | .darling => |bin_name| if (builder.enable_darling) { | | |
| 2621 | try zig_args.append("--test-cmd"); | | |
| 2622 | try zig_args.append(bin_name); | | |
| 2623 | try zig_args.append("--test-cmd-bin"); | | |
| 2624 | } else { | | |
| 2625 | try zig_args.append("--test-no-exec"); | | |
| 2626 | }, | | |
| 2627 | } | 2644 | } |
| | 2645 | } else if (self.kind == .test_exe) { |
| | 2646 | try zig_args.append("--test-no-exec"); |
| 2628 | } | 2647 | } |
| 2629 | | 2648 | |
| 2630 | for (self.packages.items) |pkg| { | 2649 | for (self.packages.items) |pkg| { |
| ... | @@ -2877,13 +2896,13 @@ pub const InstallArtifactStep = struct { | ... | @@ -2877,13 +2896,13 @@ pub const InstallArtifactStep = struct { |
| 2877 | .step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make), | 2896 | .step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make), |
| 2878 | .artifact = artifact, | 2897 | .artifact = artifact, |
| 2879 | .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { | 2898 | .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { |
| 2880 | .obj => unreachable, | 2899 | .obj => @panic("Cannot install a .obj build artifact."), |
| 2881 | .@"test" => unreachable, | 2900 | .@"test" => @panic("Cannot install a test build artifact, use addTestExe instead."), |
| 2882 | .exe => InstallDir{ .bin = {} }, | 2901 | .exe, .test_exe => InstallDir{ .bin = {} }, |
| 2883 | .lib => InstallDir{ .lib = {} }, | 2902 | .lib => InstallDir{ .lib = {} }, |
| 2884 | }, | 2903 | }, |
| 2885 | .pdb_dir = if (artifact.producesPdbFile()) blk: { | 2904 | .pdb_dir = if (artifact.producesPdbFile()) blk: { |
| 2886 | if (artifact.kind == .exe) { | 2905 | if (artifact.kind == .exe or artifact.kind == .test_exe) { |
| 2887 | break :blk InstallDir{ .bin = {} }; | 2906 | break :blk InstallDir{ .bin = {} }; |
| 2888 | } else { | 2907 | } else { |
| 2889 | break :blk InstallDir{ .lib = {} }; | 2908 | break :blk InstallDir{ .lib = {} }; |