| ... | ... | @@ -320,6 +320,14 @@ pub const Builder = struct { |
| 320 | 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 | 331 | pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { |
| 324 | 332 | return addAssembleSource(self, name, .{ .path = src }); |
| 325 | 333 | } |
| ... | ... | @@ -1569,6 +1577,7 @@ pub const LibExeObjStep = struct { |
| 1569 | 1577 | lib, |
| 1570 | 1578 | obj, |
| 1571 | 1579 | @"test", |
| 1580 | test_exe, |
| 1572 | 1581 | }; |
| 1573 | 1582 | |
| 1574 | 1583 | pub const SharedLibKind = union(enum) { |
| ... | ... | @@ -1617,6 +1626,10 @@ pub const LibExeObjStep = struct { |
| 1617 | 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 | 1633 | fn initExtraArgs( |
| 1621 | 1634 | builder: *Builder, |
| 1622 | 1635 | name_raw: []const u8, |
| ... | ... | @@ -1698,7 +1711,7 @@ pub const LibExeObjStep = struct { |
| 1698 | 1711 | .output_mode = switch (self.kind) { |
| 1699 | 1712 | .lib => .Lib, |
| 1700 | 1713 | .obj => .Obj, |
| 1701 | | .exe, .@"test" => .Exe, |
| 1714 | .exe, .@"test", .test_exe => .Exe, |
| 1702 | 1715 | }, |
| 1703 | 1716 | .link_mode = if (self.linkage) |some| @as(std.builtin.LinkMode, switch (some) { |
| 1704 | 1717 | .dynamic => .Dynamic, |
| ... | ... | @@ -1762,7 +1775,7 @@ pub const LibExeObjStep = struct { |
| 1762 | 1775 | /// Creates a `RunStep` with an executable built with `addExecutable`. |
| 1763 | 1776 | /// Add command line arguments with `addArg`. |
| 1764 | 1777 | pub fn run(exe: *LibExeObjStep) *RunStep { |
| 1765 | | assert(exe.kind == .exe); |
| 1778 | assert(exe.kind == .exe or exe.kind == .test_exe); |
| 1766 | 1779 | |
| 1767 | 1780 | // It doesn't have to be native. We catch that if you actually try to run it. |
| 1768 | 1781 | // Consider that this is declarative; the run step may not be run unless a user |
| ... | ... | @@ -1770,6 +1783,10 @@ pub const LibExeObjStep = struct { |
| 1770 | 1783 | const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {s}", .{exe.step.name})); |
| 1771 | 1784 | run_step.addArtifactArg(exe); |
| 1772 | 1785 | |
| 1786 | if (exe.kind == .test_exe) { |
| 1787 | run_step.addArg(exe.builder.zig_exe); |
| 1788 | } |
| 1789 | |
| 1773 | 1790 | if (exe.vcpkg_bin_path) |path| { |
| 1774 | 1791 | run_step.addPathDir(path); |
| 1775 | 1792 | } |
| ... | ... | @@ -1816,7 +1833,7 @@ pub const LibExeObjStep = struct { |
| 1816 | 1833 | pub fn producesPdbFile(self: *LibExeObjStep) bool { |
| 1817 | 1834 | if (!self.target.isWindows() and !self.target.isUefi()) return false; |
| 1818 | 1835 | if (self.strip) return false; |
| 1819 | | return self.isDynamicLibrary() or self.kind == .exe; |
| 1836 | return self.isDynamicLibrary() or self.kind == .exe or self.kind == .test_exe; |
| 1820 | 1837 | } |
| 1821 | 1838 | |
| 1822 | 1839 | pub fn linkLibC(self: *LibExeObjStep) void { |
| ... | ... | @@ -1976,12 +1993,12 @@ pub const LibExeObjStep = struct { |
| 1976 | 1993 | } |
| 1977 | 1994 | |
| 1978 | 1995 | pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { |
| 1979 | | assert(self.kind == .@"test"); |
| 1996 | assert(self.kind == .@"test" or self.kind == .test_exe); |
| 1980 | 1997 | self.name_prefix = self.builder.dupe(text); |
| 1981 | 1998 | } |
| 1982 | 1999 | |
| 1983 | 2000 | pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void { |
| 1984 | | assert(self.kind == .@"test"); |
| 2001 | assert(self.kind == .@"test" or self.kind == .test_exe); |
| 1985 | 2002 | self.filter = if (text) |t| self.builder.dupe(t) else null; |
| 1986 | 2003 | } |
| 1987 | 2004 | |
| ... | ... | @@ -2052,7 +2069,7 @@ pub const LibExeObjStep = struct { |
| 2052 | 2069 | /// Returns the generated header file. |
| 2053 | 2070 | /// This function can only be called for libraries or object files which have `emit_h` set. |
| 2054 | 2071 | pub fn getOutputHSource(self: *LibExeObjStep) FileSource { |
| 2055 | | assert(self.kind != .exe); |
| 2072 | assert(self.kind != .exe and self.kind != .test_exe and self.kind != .@"test"); |
| 2056 | 2073 | assert(self.emit_h); |
| 2057 | 2074 | return FileSource{ .generated = &self.output_h_path_source }; |
| 2058 | 2075 | } |
| ... | ... | @@ -2222,6 +2239,7 @@ pub const LibExeObjStep = struct { |
| 2222 | 2239 | .exe => "build-exe", |
| 2223 | 2240 | .obj => "build-obj", |
| 2224 | 2241 | .@"test" => "test", |
| 2242 | .test_exe => "test", |
| 2225 | 2243 | }; |
| 2226 | 2244 | zig_args.append(cmd) catch unreachable; |
| 2227 | 2245 | |
| ... | ... | @@ -2268,8 +2286,9 @@ pub const LibExeObjStep = struct { |
| 2268 | 2286 | .static_path => |static_path| try zig_args.append(static_path.getPath(builder)), |
| 2269 | 2287 | |
| 2270 | 2288 | .other_step => |other| switch (other.kind) { |
| 2271 | | .exe => unreachable, |
| 2272 | | .@"test" => unreachable, |
| 2289 | .exe => @panic("Cannot link with an executable build artifact"), |
| 2290 | .test_exe => @panic("Cannot link with an executable build artifact"), |
| 2291 | .@"test" => @panic("Cannot link with a test"), |
| 2273 | 2292 | .obj => { |
| 2274 | 2293 | try zig_args.append(other.getOutputSource().getPath(builder)); |
| 2275 | 2294 | }, |
| ... | ... | @@ -2542,89 +2561,93 @@ pub const LibExeObjStep = struct { |
| 2542 | 2561 | try zig_args.append(builder.pathFromRoot(version_script)); |
| 2543 | 2562 | } |
| 2544 | 2563 | |
| 2545 | | if (self.exec_cmd_args) |exec_cmd_args| { |
| 2546 | | for (exec_cmd_args) |cmd_arg| { |
| 2547 | | if (cmd_arg) |arg| { |
| 2548 | | try zig_args.append("--test-cmd"); |
| 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; |
| 2564 | if (self.kind == .@"test") { |
| 2565 | if (self.exec_cmd_args) |exec_cmd_args| { |
| 2566 | for (exec_cmd_args) |cmd_arg| { |
| 2567 | if (cmd_arg) |arg| { |
| 2576 | 2568 | try zig_args.append("--test-cmd"); |
| 2577 | | try zig_args.append(bin_name); |
| 2578 | | if (glibc_dir_arg) |dir| { |
| 2579 | | // TODO look into making this a call to `linuxTriple`. This |
| 2580 | | // needs the directory to be called "i686" rather than |
| 2581 | | // "i386" which is why we do it manually here. |
| 2582 | | const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}"; |
| 2583 | | const cpu_arch = self.target.getCpuArch(); |
| 2584 | | const os_tag = self.target.getOsTag(); |
| 2585 | | const abi = self.target.getAbi(); |
| 2586 | | const cpu_arch_name: []const u8 = if (cpu_arch == .i386) |
| 2587 | | "i686" |
| 2569 | try zig_args.append(arg); |
| 2570 | } else { |
| 2571 | try zig_args.append("--test-cmd-bin"); |
| 2572 | } |
| 2573 | } |
| 2574 | } else { |
| 2575 | const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc; |
| 2576 | |
| 2577 | switch (self.builder.host.getExternalExecutor(self.target_info, .{ |
| 2578 | .qemu_fixes_dl = need_cross_glibc and builder.glibc_runtimes_dir != null, |
| 2579 | .link_libc = self.is_linking_libc, |
| 2580 | })) { |
| 2581 | .native => {}, |
| 2582 | .bad_dl, .bad_os_or_cpu => { |
| 2583 | try zig_args.append("--test-no-exec"); |
| 2584 | }, |
| 2585 | .rosetta => if (builder.enable_rosetta) { |
| 2586 | try zig_args.append("--test-cmd-bin"); |
| 2587 | } else { |
| 2588 | try zig_args.append("--test-no-exec"); |
| 2589 | }, |
| 2590 | .qemu => |bin_name| ok: { |
| 2591 | if (builder.enable_qemu) qemu: { |
| 2592 | const glibc_dir_arg = if (need_cross_glibc) |
| 2593 | builder.glibc_runtimes_dir orelse break :qemu |
| 2588 | 2594 | else |
| 2589 | | @tagName(cpu_arch); |
| 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"); |
| 2595 | | try zig_args.append("-L"); |
| 2595 | null; |
| 2596 | 2596 | try zig_args.append("--test-cmd"); |
| 2597 | | try zig_args.append(full_dir); |
| 2597 | try zig_args.append(bin_name); |
| 2598 | if (glibc_dir_arg) |dir| { |
| 2599 | // TODO look into making this a call to `linuxTriple`. This |
| 2600 | // needs the directory to be called "i686" rather than |
| 2601 | // "i386" which is why we do it manually here. |
| 2602 | const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}"; |
| 2603 | const cpu_arch = self.target.getCpuArch(); |
| 2604 | const os_tag = self.target.getOsTag(); |
| 2605 | const abi = self.target.getAbi(); |
| 2606 | const cpu_arch_name: []const u8 = if (cpu_arch == .i386) |
| 2607 | "i686" |
| 2608 | else |
| 2609 | @tagName(cpu_arch); |
| 2610 | const full_dir = try std.fmt.allocPrint(builder.allocator, fmt_str, .{ |
| 2611 | dir, cpu_arch_name, @tagName(os_tag), @tagName(abi), |
| 2612 | }); |
| 2613 | |
| 2614 | try zig_args.append("--test-cmd"); |
| 2615 | try zig_args.append("-L"); |
| 2616 | try zig_args.append("--test-cmd"); |
| 2617 | try zig_args.append(full_dir); |
| 2618 | } |
| 2619 | try zig_args.append("--test-cmd-bin"); |
| 2620 | break :ok; |
| 2598 | 2621 | } |
| 2622 | try zig_args.append("--test-no-exec"); |
| 2623 | }, |
| 2624 | .wine => |bin_name| if (builder.enable_wine) { |
| 2625 | try zig_args.append("--test-cmd"); |
| 2626 | try zig_args.append(bin_name); |
| 2599 | 2627 | try zig_args.append("--test-cmd-bin"); |
| 2600 | | break :ok; |
| 2601 | | } |
| 2602 | | try zig_args.append("--test-no-exec"); |
| 2603 | | }, |
| 2604 | | .wine => |bin_name| if (builder.enable_wine) { |
| 2605 | | try zig_args.append("--test-cmd"); |
| 2606 | | try zig_args.append(bin_name); |
| 2607 | | try zig_args.append("--test-cmd-bin"); |
| 2608 | | } else { |
| 2609 | | try zig_args.append("--test-no-exec"); |
| 2610 | | }, |
| 2611 | | .wasmtime => |bin_name| if (builder.enable_wasmtime) { |
| 2612 | | try zig_args.append("--test-cmd"); |
| 2613 | | try zig_args.append(bin_name); |
| 2614 | | try zig_args.append("--test-cmd"); |
| 2615 | | try zig_args.append("--dir=."); |
| 2616 | | try zig_args.append("--test-cmd-bin"); |
| 2617 | | } else { |
| 2618 | | try zig_args.append("--test-no-exec"); |
| 2619 | | }, |
| 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 | | }, |
| 2628 | } else { |
| 2629 | try zig_args.append("--test-no-exec"); |
| 2630 | }, |
| 2631 | .wasmtime => |bin_name| if (builder.enable_wasmtime) { |
| 2632 | try zig_args.append("--test-cmd"); |
| 2633 | try zig_args.append(bin_name); |
| 2634 | try zig_args.append("--test-cmd"); |
| 2635 | try zig_args.append("--dir=."); |
| 2636 | try zig_args.append("--test-cmd-bin"); |
| 2637 | } else { |
| 2638 | try zig_args.append("--test-no-exec"); |
| 2639 | }, |
| 2640 | .darling => |bin_name| if (builder.enable_darling) { |
| 2641 | try zig_args.append("--test-cmd"); |
| 2642 | try zig_args.append(bin_name); |
| 2643 | try zig_args.append("--test-cmd-bin"); |
| 2644 | } else { |
| 2645 | try zig_args.append("--test-no-exec"); |
| 2646 | }, |
| 2647 | } |
| 2627 | 2648 | } |
| 2649 | } else if (self.kind == .test_exe) { |
| 2650 | try zig_args.append("--test-no-exec"); |
| 2628 | 2651 | } |
| 2629 | 2652 | |
| 2630 | 2653 | for (self.packages.items) |pkg| { |
| ... | ... | @@ -2877,13 +2900,13 @@ pub const InstallArtifactStep = struct { |
| 2877 | 2900 | .step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make), |
| 2878 | 2901 | .artifact = artifact, |
| 2879 | 2902 | .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { |
| 2880 | | .obj => unreachable, |
| 2881 | | .@"test" => unreachable, |
| 2882 | | .exe => InstallDir{ .bin = {} }, |
| 2903 | .obj => @panic("Cannot install a .obj build artifact."), |
| 2904 | .@"test" => @panic("Cannot install a test build artifact, use addTestExe instead."), |
| 2905 | .exe, .test_exe => InstallDir{ .bin = {} }, |
| 2883 | 2906 | .lib => InstallDir{ .lib = {} }, |
| 2884 | 2907 | }, |
| 2885 | 2908 | .pdb_dir = if (artifact.producesPdbFile()) blk: { |
| 2886 | | if (artifact.kind == .exe) { |
| 2909 | if (artifact.kind == .exe or artifact.kind == .test_exe) { |
| 2887 | 2910 | break :blk InstallDir{ .bin = {} }; |
| 2888 | 2911 | } else { |
| 2889 | 2912 | break :blk InstallDir{ .lib = {} }; |