| author | |
| committer | |
| log | 5152987072ef2d030a704d2b4ca9cebd757d4cec |
| tree | b203a8bed0888cc490f2c524975446755a9ce485 |
| parent | 2597da02544c05f7de6c209d9d4d509b74e63f73 |
| parent | 8b2949e372e615886b9087b06187878452421724 |
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/3640915 files changed, 577 insertions(+), 416 deletions(-)
lib/compiler/Maker.zig+18-6| ... | ... | @@ -2119,7 +2119,7 @@ fn markFailedStepsDirty(maker: *Maker) void { |
| 2119 | 2119 | for (all_steps) |step_index| { |
| 2120 | 2120 | const step = maker.stepByIndex(step_index); |
| 2121 | 2121 | switch (step.state) { |
| 2122 | .dependency_failure, .failure, .skipped => _ = maker.invalidateResult(step), | |
| 2122 | .dependency_failure, .dependency_skipped, .failure, .skipped => _ = maker.invalidateResult(step), | |
| 2123 | 2123 | else => continue, |
| 2124 | 2124 | } |
| 2125 | 2125 | } |
| ... | ... | @@ -2334,7 +2334,7 @@ fn makeSteps( |
| 2334 | 2334 | .precheck_unstarted => unreachable, |
| 2335 | 2335 | .precheck_started => unreachable, |
| 2336 | 2336 | .precheck_done => unreachable, |
| 2337 | .dependency_failure => pending_count += 1, | |
| 2337 | .dependency_failure, .dependency_skipped => pending_count += 1, | |
| 2338 | 2338 | .success => success_count += 1, |
| 2339 | 2339 | .skipped, .skipped_oom => skipped_count += 1, |
| 2340 | 2340 | .failure => { |
| ... | ... | @@ -2580,10 +2580,14 @@ fn makeStep( |
| 2580 | 2580 | |
| 2581 | 2581 | .failure, |
| 2582 | 2582 | .dependency_failure, |
| 2583 | .skipped_oom, | |
| 2584 | 2583 | => break .dependency_failure, |
| 2585 | 2584 | |
| 2586 | .success, .skipped => {}, | |
| 2585 | .dependency_skipped, | |
| 2586 | .skipped_oom, | |
| 2587 | .skipped, | |
| 2588 | => break .dependency_skipped, | |
| 2589 | ||
| 2590 | .success => {}, | |
| 2587 | 2591 | } |
| 2588 | 2592 | } else if (Step.make(step_index, maker, step_prog_node)) state: { |
| 2589 | 2593 | break :state .success; |
| ... | ... | @@ -2602,11 +2606,12 @@ fn makeStep( |
| 2602 | 2606 | |
| 2603 | 2607 | .failure, |
| 2604 | 2608 | .dependency_failure, |
| 2609 | .dependency_skipped, | |
| 2605 | 2610 | .skipped_oom, |
| 2611 | .skipped, | |
| 2606 | 2612 | => false, |
| 2607 | 2613 | |
| 2608 | 2614 | .success, |
| 2609 | .skipped, | |
| 2610 | 2615 | => true, |
| 2611 | 2616 | }; |
| 2612 | 2617 | |
| ... | ... | @@ -2623,7 +2628,7 @@ fn makeStep( |
| 2623 | 2628 | .precheck_done => unreachable, |
| 2624 | 2629 | .success => .success, |
| 2625 | 2630 | .failure, .dependency_failure => .failure, |
| 2626 | .skipped => .skipped, | |
| 2631 | .dependency_skipped, .skipped => .skipped, | |
| 2627 | 2632 | .skipped_oom => .skipped_oom, |
| 2628 | 2633 | }; |
| 2629 | 2634 | serveBuildStepCompleted( |
| ... | ... | @@ -2777,6 +2782,12 @@ fn printStepStatus(maker: *Maker, step_index: Configuration.Step.Index, stderr: |
| 2777 | 2782 | try stderr.setColor(.reset); |
| 2778 | 2783 | }, |
| 2779 | 2784 | |
| 2785 | .dependency_skipped => { | |
| 2786 | try stderr.setColor(.dim); | |
| 2787 | try writer.writeAll(" transitive skip\n"); | |
| 2788 | try stderr.setColor(.reset); | |
| 2789 | }, | |
| 2790 | ||
| 2780 | 2791 | .success => { |
| 2781 | 2792 | try stderr.setColor(.green); |
| 2782 | 2793 | if (s.result_cached) { |
| ... | ... | @@ -3023,6 +3034,7 @@ fn constructGraphAndCheckForDependencyLoop( |
| 3023 | 3034 | |
| 3024 | 3035 | // These don't happen until we actually run the step graph. |
| 3025 | 3036 | .dependency_failure => unreachable, |
| 3037 | .dependency_skipped => unreachable, | |
| 3026 | 3038 | .success => unreachable, |
| 3027 | 3039 | .failure => unreachable, |
| 3028 | 3040 | .skipped => unreachable, |
lib/compiler/Maker/Step.zig+3| ... | ... | @@ -163,6 +163,9 @@ pub const State = enum { |
| 163 | 163 | /// be re-evaluated. |
| 164 | 164 | precheck_done, |
| 165 | 165 | dependency_failure, |
| 166 | /// Handled exactly the same as `dependency_failure` except communicates | |
| 167 | /// that the dependency didn't fail but rather was skipped. | |
| 168 | dependency_skipped, | |
| 166 | 169 | success, |
| 167 | 170 | failure, |
| 168 | 171 | /// This state indicates that the step did not complete, however, it also did not fail, |
lib/compiler/Maker/Step/Run.zig+33| ... | ... | @@ -187,6 +187,11 @@ pub fn make( |
| 187 | 187 | man.hash.addListOfBytes(run_args); |
| 188 | 188 | } |
| 189 | 189 | }, |
| 190 | .enable_darling => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), | |
| 191 | .enable_qemu => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), | |
| 192 | .enable_rosetta => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), | |
| 193 | .enable_wasmtime => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), | |
| 194 | .enable_wine => thirdPartyToggle(&man.hash, &argv_list, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), | |
| 190 | 195 | } |
| 191 | 196 | } |
| 192 | 197 | |
| ... | ... | @@ -351,6 +356,29 @@ pub fn make( |
| 351 | 356 | step.clearFailedCommand(gpa); |
| 352 | 357 | } |
| 353 | 358 | |
| 359 | fn thirdPartyToggle( | |
| 360 | man_hash: ?*Cache.HashHelper, | |
| 361 | argv_list: *std.ArrayList([]const u8), | |
| 362 | conf: *const Configuration, | |
| 363 | setting: bool, | |
| 364 | enable: ?Configuration.String, | |
| 365 | disable: ?Configuration.String, | |
| 366 | ) void { | |
| 367 | if (setting) { | |
| 368 | if (enable) |string| { | |
| 369 | const slice = string.slice(conf); | |
| 370 | if (man_hash) |h| h.addBytesZ(slice); | |
| 371 | argv_list.appendAssumeCapacity(slice); | |
| 372 | } | |
| 373 | } else { | |
| 374 | if (disable) |string| { | |
| 375 | const slice = string.slice(conf); | |
| 376 | if (man_hash) |h| h.addBytesZ(slice); | |
| 377 | argv_list.appendAssumeCapacity(slice); | |
| 378 | } | |
| 379 | } | |
| 380 | } | |
| 381 | ||
| 354 | 382 | /// Reads stdout of a Zig test process until a termination condition is reached: |
| 355 | 383 | /// * A write fails, indicating the child unexpectedly closed stdin |
| 356 | 384 | /// * A test (or a response from the test runner) times out |
| ... | ... | @@ -1535,6 +1563,11 @@ pub fn rerunInFuzzMode( |
| 1535 | 1563 | .output_file => unreachable, |
| 1536 | 1564 | .output_directory => unreachable, |
| 1537 | 1565 | .passthru => unreachable, |
| 1566 | .enable_darling => thirdPartyToggle(null, &argv_list, conf, graph.enable_darling, arg.prefix.value, arg.suffix.value), | |
| 1567 | .enable_qemu => thirdPartyToggle(null, &argv_list, conf, graph.enable_qemu, arg.prefix.value, arg.suffix.value), | |
| 1568 | .enable_rosetta => thirdPartyToggle(null, &argv_list, conf, graph.enable_rosetta, arg.prefix.value, arg.suffix.value), | |
| 1569 | .enable_wasmtime => thirdPartyToggle(null, &argv_list, conf, graph.enable_wasmtime, arg.prefix.value, arg.suffix.value), | |
| 1570 | .enable_wine => thirdPartyToggle(null, &argv_list, conf, graph.enable_wine, arg.prefix.value, arg.suffix.value), | |
| 1538 | 1571 | } |
| 1539 | 1572 | } |
| 1540 | 1573 |
lib/std/Build.zig-16| ... | ... | @@ -45,17 +45,6 @@ debug_log_scopes: []const []const u8 = &.{}, |
| 45 | 45 | /// Set to 0 to disable stack collection. |
| 46 | 46 | debug_stack_frames_count: u8 = 8, |
| 47 | 47 | |
| 48 | /// Experimental. Use system Darling installation to run cross compiled macOS build artifacts. | |
| 49 | enable_darling: bool = false, | |
| 50 | /// Use system QEMU installation to run cross compiled foreign architecture build artifacts. | |
| 51 | enable_qemu: bool = false, | |
| 52 | /// Darwin. Use Rosetta to run x86_64 macOS build artifacts on arm64 macOS. | |
| 53 | enable_rosetta: bool = false, | |
| 54 | /// Use system Wasmtime installation to run cross compiled wasm/wasi build artifacts. | |
| 55 | enable_wasmtime: bool = false, | |
| 56 | /// Use system Wine installation to run cross compiled Windows build artifacts. | |
| 57 | enable_wine: bool = false, | |
| 58 | ||
| 59 | 48 | dep_prefix: []const u8 = "", |
| 60 | 49 | |
| 61 | 50 | modules: std.array_hash_map.String(*Module), |
| ... | ... | @@ -388,11 +377,6 @@ fn createChild( |
| 388 | 377 | .default_step = undefined, |
| 389 | 378 | .top_level_steps = .{}, |
| 390 | 379 | .debug_log_scopes = parent.debug_log_scopes, |
| 391 | .enable_darling = parent.enable_darling, | |
| 392 | .enable_qemu = parent.enable_qemu, | |
| 393 | .enable_rosetta = parent.enable_rosetta, | |
| 394 | .enable_wasmtime = parent.enable_wasmtime, | |
| 395 | .enable_wine = parent.enable_wine, | |
| 396 | 380 | .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }), |
| 397 | 381 | .modules = .empty, |
| 398 | 382 | .named_writefiles = .empty, |
lib/std/Build/Configuration.zig+7| ... | ... | @@ -626,6 +626,13 @@ pub const Step = extern struct { |
| 626 | 626 | output_file, |
| 627 | 627 | output_directory, |
| 628 | 628 | passthru, |
| 629 | /// `prefix` contains the enabled string. | |
| 630 | /// `suffix` contains the disabled string. | |
| 631 | enable_darling, | |
| 632 | enable_qemu, | |
| 633 | enable_rosetta, | |
| 634 | enable_wasmtime, | |
| 635 | enable_wine, | |
| 629 | 636 | }; |
| 630 | 637 | |
| 631 | 638 | pub const Index = IndexType(@This()); |
lib/std/Build/Serialize.zig+95| ... | ... | @@ -1017,6 +1017,101 @@ fn initArgsList(s: *Serialize, args: []const Step.Run.Arg) ![]const Configuratio |
| 1017 | 1017 | .producer = .{ .value = null }, |
| 1018 | 1018 | .generated = .{ .value = null }, |
| 1019 | 1019 | }, |
| 1020 | .enable_darling => |a| .{ | |
| 1021 | .flags = .{ | |
| 1022 | .tag = .enable_darling, | |
| 1023 | .prefix = a.enabled != null, | |
| 1024 | .suffix = a.disabled != null, | |
| 1025 | .basename = false, | |
| 1026 | .path = false, | |
| 1027 | .producer = false, | |
| 1028 | .generated = false, | |
| 1029 | .dep_file = false, | |
| 1030 | .make_absolute = false, | |
| 1031 | }, | |
| 1032 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | |
| 1033 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | |
| 1034 | .basename = .{ .value = null }, | |
| 1035 | .path = .{ .value = null }, | |
| 1036 | .producer = .{ .value = null }, | |
| 1037 | .generated = .{ .value = null }, | |
| 1038 | }, | |
| 1039 | .enable_qemu => |a| .{ | |
| 1040 | .flags = .{ | |
| 1041 | .tag = .enable_qemu, | |
| 1042 | .prefix = a.enabled != null, | |
| 1043 | .suffix = a.disabled != null, | |
| 1044 | .basename = false, | |
| 1045 | .path = false, | |
| 1046 | .producer = false, | |
| 1047 | .generated = false, | |
| 1048 | .dep_file = false, | |
| 1049 | .make_absolute = false, | |
| 1050 | }, | |
| 1051 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | |
| 1052 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | |
| 1053 | .basename = .{ .value = null }, | |
| 1054 | .path = .{ .value = null }, | |
| 1055 | .producer = .{ .value = null }, | |
| 1056 | .generated = .{ .value = null }, | |
| 1057 | }, | |
| 1058 | .enable_rosetta => |a| .{ | |
| 1059 | .flags = .{ | |
| 1060 | .tag = .enable_rosetta, | |
| 1061 | .prefix = a.enabled != null, | |
| 1062 | .suffix = a.disabled != null, | |
| 1063 | .basename = false, | |
| 1064 | .path = false, | |
| 1065 | .producer = false, | |
| 1066 | .generated = false, | |
| 1067 | .dep_file = false, | |
| 1068 | .make_absolute = false, | |
| 1069 | }, | |
| 1070 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | |
| 1071 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | |
| 1072 | .basename = .{ .value = null }, | |
| 1073 | .path = .{ .value = null }, | |
| 1074 | .producer = .{ .value = null }, | |
| 1075 | .generated = .{ .value = null }, | |
| 1076 | }, | |
| 1077 | .enable_wasmtime => |a| .{ | |
| 1078 | .flags = .{ | |
| 1079 | .tag = .enable_wasmtime, | |
| 1080 | .prefix = a.enabled != null, | |
| 1081 | .suffix = a.disabled != null, | |
| 1082 | .basename = false, | |
| 1083 | .path = false, | |
| 1084 | .producer = false, | |
| 1085 | .generated = false, | |
| 1086 | .dep_file = false, | |
| 1087 | .make_absolute = false, | |
| 1088 | }, | |
| 1089 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | |
| 1090 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | |
| 1091 | .basename = .{ .value = null }, | |
| 1092 | .path = .{ .value = null }, | |
| 1093 | .producer = .{ .value = null }, | |
| 1094 | .generated = .{ .value = null }, | |
| 1095 | }, | |
| 1096 | .enable_wine => |a| .{ | |
| 1097 | .flags = .{ | |
| 1098 | .tag = .enable_wine, | |
| 1099 | .prefix = a.enabled != null, | |
| 1100 | .suffix = a.disabled != null, | |
| 1101 | .basename = false, | |
| 1102 | .path = false, | |
| 1103 | .producer = false, | |
| 1104 | .generated = false, | |
| 1105 | .dep_file = false, | |
| 1106 | .make_absolute = false, | |
| 1107 | }, | |
| 1108 | .prefix = .{ .value = try s.addOptionalString(a.enabled) }, | |
| 1109 | .suffix = .{ .value = try s.addOptionalString(a.disabled) }, | |
| 1110 | .basename = .{ .value = null }, | |
| 1111 | .path = .{ .value = null }, | |
| 1112 | .producer = .{ .value = null }, | |
| 1113 | .generated = .{ .value = null }, | |
| 1114 | }, | |
| 1020 | 1115 | }); |
| 1021 | 1116 | } |
| 1022 | 1117 | return result; |
lib/std/Build/Step/Run.zig+55| ... | ... | @@ -68,9 +68,11 @@ rename_step_with_output_arg: bool, |
| 68 | 68 | /// executed binary will not fail the build if the binary cannot be executed |
| 69 | 69 | /// due to being for a foreign binary to the host system which is running the |
| 70 | 70 | /// build graph. |
| 71 | /// | |
| 71 | 72 | /// Command-line arguments such as -fqemu and -fwasmtime may affect whether a |
| 72 | 73 | /// binary is detected as foreign, as well as system configuration such as |
| 73 | 74 | /// Rosetta (macOS) and binfmt_misc (Linux). |
| 75 | /// | |
| 74 | 76 | /// If this Run step is considered to have side-effects, then this flag does |
| 75 | 77 | /// nothing. |
| 76 | 78 | skip_foreign_checks: bool, |
| ... | ... | @@ -149,6 +151,19 @@ pub const Arg = union(enum) { |
| 149 | 151 | output_directory: *Output, |
| 150 | 152 | /// The arguments passed after "--" on the "zig build" CLI. |
| 151 | 153 | passthru, |
| 154 | ||
| 155 | enable_darling: ToggleFlags, | |
| 156 | enable_qemu: ToggleFlags, | |
| 157 | enable_rosetta: ToggleFlags, | |
| 158 | enable_wasmtime: ToggleFlags, | |
| 159 | enable_wine: ToggleFlags, | |
| 160 | }; | |
| 161 | ||
| 162 | pub const ToggleFlags = struct { | |
| 163 | /// The string to pass when enabled, or null to omit the arg. | |
| 164 | enabled: ?[]const u8 = null, | |
| 165 | /// The string to pass when disabled, or null to omit the arg. | |
| 166 | disabled: ?[]const u8 = null, | |
| 152 | 167 | }; |
| 153 | 168 | |
| 154 | 169 | pub const DecoratedArtifact = struct { |
| ... | ... | @@ -576,6 +591,46 @@ pub fn addPassthruArgs(run: *Run) void { |
| 576 | 591 | run.argv.append(arena, .passthru) catch @panic("OOM"); |
| 577 | 592 | } |
| 578 | 593 | |
| 594 | /// Appends a custom string to the command line depending on the `-fdarling` | |
| 595 | /// value passed to `zig build`. | |
| 596 | pub fn addThirdPartyEnabledArgDarling(run: *Run, toggle_flags: ToggleFlags) void { | |
| 597 | const graph = run.step.owner.graph; | |
| 598 | const arena = graph.arena; | |
| 599 | run.argv.append(arena, .{ .enable_darling = toggle_flags }) catch @panic("OOM"); | |
| 600 | } | |
| 601 | ||
| 602 | /// Appends a custom string to the command line depending on the `-fqemu` | |
| 603 | /// value passed to `zig build`. | |
| 604 | pub fn addThirdPartyEnabledArgQemu(run: *Run, toggle_flags: ToggleFlags) void { | |
| 605 | const graph = run.step.owner.graph; | |
| 606 | const arena = graph.arena; | |
| 607 | run.argv.append(arena, .{ .enable_qemu = toggle_flags }) catch @panic("OOM"); | |
| 608 | } | |
| 609 | ||
| 610 | /// Appends a custom string to the command line depending on the `-frosetta` | |
| 611 | /// value passed to `zig build`. | |
| 612 | pub fn addThirdPartyEnabledArgRosetta(run: *Run, toggle_flags: ToggleFlags) void { | |
| 613 | const graph = run.step.owner.graph; | |
| 614 | const arena = graph.arena; | |
| 615 | run.argv.append(arena, .{ .enable_rosetta = toggle_flags }) catch @panic("OOM"); | |
| 616 | } | |
| 617 | ||
| 618 | /// Appends a custom string to the command line depending on the `-fwasmtime` | |
| 619 | /// value passed to `zig build`. | |
| 620 | pub fn addThirdPartyEnabledArgWasmtime(run: *Run, toggle_flags: ToggleFlags) void { | |
| 621 | const graph = run.step.owner.graph; | |
| 622 | const arena = graph.arena; | |
| 623 | run.argv.append(arena, .{ .enable_wasmtime = toggle_flags }) catch @panic("OOM"); | |
| 624 | } | |
| 625 | ||
| 626 | /// Appends a custom string to the command line depending on the `-fwine` | |
| 627 | /// value passed to `zig build`. | |
| 628 | pub fn addThirdPartyEnabledArgWine(run: *Run, toggle_flags: ToggleFlags) void { | |
| 629 | const graph = run.step.owner.graph; | |
| 630 | const arena = graph.arena; | |
| 631 | run.argv.append(arena, .{ .enable_wine = toggle_flags }) catch @panic("OOM"); | |
| 632 | } | |
| 633 | ||
| 579 | 634 | pub fn setStdIn(run: *Run, stdin: StdIn) void { |
| 580 | 635 | switch (stdin) { |
| 581 | 636 | .lazy_path => |lazy_path| lazy_path.addStepDependencies(&run.step), |
test/error_traces.zig+41-2| ... | ... | @@ -1,7 +1,10 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | const Context = @import("tests.zig").ErrorTracesContext; | |
| 2 | 3 | |
| 3 | pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target.Os.Tag) void { | |
| 4 | pub fn addCases(cases: *Context, params: *const Context.CaseParameters, target: *const std.Target) void { | |
| 4 | 5 | cases.addCase(.{ |
| 6 | .params = params, | |
| 7 | .target = target, | |
| 5 | 8 | .name = "return", |
| 6 | 9 | .source = |
| 7 | 10 | \\pub fn main() !void { |
| ... | ... | @@ -17,6 +20,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 17 | 20 | }); |
| 18 | 21 | |
| 19 | 22 | cases.addCase(.{ |
| 23 | .params = params, | |
| 24 | .target = target, | |
| 20 | 25 | .name = "try return", |
| 21 | 26 | .source = |
| 22 | 27 | \\fn foo() !void { |
| ... | ... | @@ -44,6 +49,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 44 | 49 | }, |
| 45 | 50 | }); |
| 46 | 51 | cases.addCase(.{ |
| 52 | .params = params, | |
| 53 | .target = target, | |
| 47 | 54 | .name = "non-error return pops error trace", |
| 48 | 55 | .source = |
| 49 | 56 | \\fn bar() !void { |
| ... | ... | @@ -70,6 +77,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 70 | 77 | }); |
| 71 | 78 | |
| 72 | 79 | cases.addCase(.{ |
| 80 | .params = params, | |
| 81 | .target = target, | |
| 73 | 82 | .name = "continue in while loop", |
| 74 | 83 | .source = |
| 75 | 84 | \\fn foo() !void { |
| ... | ... | @@ -93,6 +102,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 93 | 102 | }); |
| 94 | 103 | |
| 95 | 104 | cases.addCase(.{ |
| 105 | .params = params, | |
| 106 | .target = target, | |
| 96 | 107 | .name = "for loop pops error return trace", |
| 97 | 108 | .source = |
| 98 | 109 | \\fn foo() !void { return error.FooError; } |
| ... | ... | @@ -123,6 +134,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 123 | 134 | }); |
| 124 | 135 | |
| 125 | 136 | cases.addCase(.{ |
| 137 | .params = params, | |
| 138 | .target = target, | |
| 126 | 139 | .name = "implicit continue in for loop pops stale error return trace", |
| 127 | 140 | .source = |
| 128 | 141 | \\fn foo() !void { return error.FooError; } |
| ... | ... | @@ -154,6 +167,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 154 | 167 | }); |
| 155 | 168 | |
| 156 | 169 | cases.addCase(.{ |
| 170 | .params = params, | |
| 171 | .target = target, | |
| 157 | 172 | .name = "while loop pops error return trace", |
| 158 | 173 | .source = |
| 159 | 174 | \\fn foo() !void { return error.FooError; } |
| ... | ... | @@ -186,6 +201,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 186 | 201 | }); |
| 187 | 202 | |
| 188 | 203 | cases.addCase(.{ |
| 204 | .params = params, | |
| 205 | .target = target, | |
| 189 | 206 | .name = "implicit continue in while loop pops stale error return trace", |
| 190 | 207 | .source = |
| 191 | 208 | \\fn foo() !void { return error.FooError; } |
| ... | ... | @@ -219,6 +236,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 219 | 236 | }); |
| 220 | 237 | |
| 221 | 238 | cases.addCase(.{ |
| 239 | .params = params, | |
| 240 | .target = target, | |
| 222 | 241 | .name = "try return + handled catch/if-else", |
| 223 | 242 | .source = |
| 224 | 243 | \\fn foo() !void { |
| ... | ... | @@ -251,6 +270,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 251 | 270 | }); |
| 252 | 271 | |
| 253 | 272 | cases.addCase(.{ |
| 273 | .params = params, | |
| 274 | .target = target, | |
| 254 | 275 | .name = "break from inline loop pops error return trace", |
| 255 | 276 | .source = |
| 256 | 277 | \\fn foo() !void { return error.FooBar; } |
| ... | ... | @@ -276,6 +297,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 276 | 297 | }); |
| 277 | 298 | |
| 278 | 299 | cases.addCase(.{ |
| 300 | .params = params, | |
| 301 | .target = target, | |
| 279 | 302 | .name = "catch and re-throw error", |
| 280 | 303 | .source = |
| 281 | 304 | \\fn foo() !void { |
| ... | ... | @@ -304,6 +327,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 304 | 327 | }); |
| 305 | 328 | |
| 306 | 329 | cases.addCase(.{ |
| 330 | .params = params, | |
| 331 | .target = target, | |
| 307 | 332 | .name = "errors stored in var do not contribute to error trace", |
| 308 | 333 | .source = |
| 309 | 334 | \\fn foo() !void { |
| ... | ... | @@ -328,6 +353,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 328 | 353 | }); |
| 329 | 354 | |
| 330 | 355 | cases.addCase(.{ |
| 356 | .params = params, | |
| 357 | .target = target, | |
| 331 | 358 | .name = "error stored in const has trace preserved for duration of block", |
| 332 | 359 | .source = |
| 333 | 360 | \\fn foo() !void { return error.TheSkyIsFalling; } |
| ... | ... | @@ -376,6 +403,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 376 | 403 | }); |
| 377 | 404 | |
| 378 | 405 | cases.addCase(.{ |
| 406 | .params = params, | |
| 407 | .target = target, | |
| 379 | 408 | .name = "error passed to function has its trace preserved for duration of the call", |
| 380 | 409 | .source = |
| 381 | 410 | \\pub fn expectError(expected_error: anyerror, actual_error: anyerror!void) !void { |
| ... | ... | @@ -418,6 +447,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 418 | 447 | }); |
| 419 | 448 | |
| 420 | 449 | cases.addCase(.{ |
| 450 | .params = params, | |
| 451 | .target = target, | |
| 421 | 452 | .name = "try return from within catch", |
| 422 | 453 | .source = |
| 423 | 454 | \\fn foo() !void { |
| ... | ... | @@ -455,6 +486,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 455 | 486 | }); |
| 456 | 487 | |
| 457 | 488 | cases.addCase(.{ |
| 489 | .params = params, | |
| 490 | .target = target, | |
| 458 | 491 | .name = "try return from within if-else", |
| 459 | 492 | .source = |
| 460 | 493 | \\fn foo() !void { |
| ... | ... | @@ -492,6 +525,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 492 | 525 | }); |
| 493 | 526 | |
| 494 | 527 | cases.addCase(.{ |
| 528 | .params = params, | |
| 529 | .target = target, | |
| 495 | 530 | .name = "try try return return", |
| 496 | 531 | .source = |
| 497 | 532 | \\fn foo() !void { |
| ... | ... | @@ -534,6 +569,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 534 | 569 | }); |
| 535 | 570 | |
| 536 | 571 | cases.addCase(.{ |
| 572 | .params = params, | |
| 573 | .target = target, | |
| 537 | 574 | .name = "error union switch with call operand", |
| 538 | 575 | .source = |
| 539 | 576 | \\pub fn main() !void { |
| ... | ... | @@ -579,6 +616,8 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 579 | 616 | }); |
| 580 | 617 | |
| 581 | 618 | cases.addCase(.{ |
| 619 | .params = params, | |
| 620 | .target = target, | |
| 582 | 621 | .name = "trace through inline call", |
| 583 | 622 | // The main function has two inline calls to ensure |
| 584 | 623 | // that inlinees in PDBs are properly deduplicated. |
| ... | ... | @@ -595,7 +634,7 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target. |
| 595 | 634 | \\} |
| 596 | 635 | , |
| 597 | 636 | .expect_error = "ThisIsSoSad", |
| 598 | .expect_trace = switch (os) { | |
| 637 | .expect_trace = switch (target.os.tag) { | |
| 599 | 638 | // LLVM doesn't emit column info in the binary annotations for inlinee callees in PDBs, |
| 600 | 639 | // so our expected result is slightly different for Windows than on other operating |
| 601 | 640 | // systems. |
test/src/ErrorTrace.zig+119-52| ... | ... | @@ -1,11 +1,81 @@ |
| 1 | const ErrorTrace = @This(); | |
| 2 | ||
| 3 | const builtin = @import("builtin"); | |
| 4 | ||
| 5 | const std = @import("std"); | |
| 6 | const Step = std.Build.Step; | |
| 7 | const OptimizeMode = std.lang.Optimize; | |
| 8 | const mem = std.mem; | |
| 9 | ||
| 10 | const error_traces_cases = @import("../error_traces.zig"); | |
| 11 | ||
| 1 | 12 | b: *std.Build, |
| 2 | 13 | step: *Step, |
| 3 | 14 | test_filters: []const []const u8, |
| 4 | targets: []const std.Build.ResolvedTarget, | |
| 15 | skip_non_native: bool, | |
| 5 | 16 | optimize_modes: []const OptimizeMode, |
| 6 | 17 | convert_exe: *std.Build.Step.Compile, |
| 7 | 18 | |
| 19 | pub const CaseParameters = @import("StackTrace.zig").CaseParameters; | |
| 20 | ||
| 21 | const param_sets = [_]CaseParameters{ | |
| 22 | .{}, | |
| 23 | .{ | |
| 24 | .link_libc = true, | |
| 25 | }, | |
| 26 | .{ | |
| 27 | .use_llvm = true, | |
| 28 | .use_lld = true, | |
| 29 | }, | |
| 30 | .{ | |
| 31 | .pie = true, | |
| 32 | }, | |
| 33 | .{ | |
| 34 | .target = .{ | |
| 35 | .cpu_arch = .aarch64, | |
| 36 | .os_tag = .windows, | |
| 37 | .abi = .msvc, | |
| 38 | }, | |
| 39 | }, | |
| 40 | .{ | |
| 41 | .target = .{ | |
| 42 | .cpu_arch = .x86_64, | |
| 43 | .os_tag = .windows, | |
| 44 | .abi = .gnu, | |
| 45 | }, | |
| 46 | }, | |
| 47 | .{ | |
| 48 | .target = .{ | |
| 49 | .cpu_arch = .x86, | |
| 50 | .os_tag = .windows, | |
| 51 | .abi = .msvc, | |
| 52 | }, | |
| 53 | }, | |
| 54 | .{ | |
| 55 | .target = .{ | |
| 56 | .cpu_arch = .aarch64, | |
| 57 | .os_tag = .macos, | |
| 58 | }, | |
| 59 | }, | |
| 60 | .{ | |
| 61 | .target = .{ | |
| 62 | .cpu_arch = .s390x, | |
| 63 | .os_tag = .linux, | |
| 64 | .abi = .none, | |
| 65 | }, | |
| 66 | }, | |
| 67 | .{ | |
| 68 | .target = .{ | |
| 69 | .cpu_arch = .loongarch32, | |
| 70 | .os_tag = .linux, | |
| 71 | .abi = .none, | |
| 72 | }, | |
| 73 | }, | |
| 74 | }; | |
| 75 | ||
| 8 | 76 | pub const Case = struct { |
| 77 | params: *const CaseParameters, | |
| 78 | target: *const std.Target, | |
| 9 | 79 | name: []const u8, |
| 10 | 80 | source: []const u8, |
| 11 | 81 | expect_error: []const u8, |
| ... | ... | @@ -22,50 +92,47 @@ pub const Case = struct { |
| 22 | 92 | pub const Backend = enum { llvm, selfhosted }; |
| 23 | 93 | }; |
| 24 | 94 | |
| 25 | pub fn addCase(self: *ErrorTrace, case: Case) void { | |
| 26 | for (self.targets) |*target| { | |
| 27 | const triple: ?[]const u8 = if (target.query.isNative()) null else t: { | |
| 28 | break :t target.query.zigTriple(self.b.graph.arena) catch @panic("OOM"); | |
| 29 | }; | |
| 30 | for (self.optimize_modes) |optimize| { | |
| 31 | self.addCaseConfig(case, target, triple, optimize, .llvm); | |
| 32 | } | |
| 33 | if (shouldTestNonLlvm(&target.result)) { | |
| 34 | for (self.optimize_modes) |optimize| { | |
| 35 | self.addCaseConfig(case, target, triple, optimize, .selfhosted); | |
| 36 | } | |
| 95 | pub fn addCases(self: *ErrorTrace) void { | |
| 96 | const b = self.b; | |
| 97 | ||
| 98 | for (&param_sets) |*params| { | |
| 99 | const resolved_target = b.resolveTargetQuery(params.target); | |
| 100 | ||
| 101 | if (self.skip_non_native and !resolved_target.query.isNative()) continue; | |
| 102 | ||
| 103 | // To avoid redundant testing, skip cross-compilation targets matching the host. | |
| 104 | if (resolved_target.result.os.tag == builtin.target.os.tag and | |
| 105 | resolved_target.result.cpu.arch == builtin.target.cpu.arch) | |
| 106 | { | |
| 107 | continue; | |
| 37 | 108 | } |
| 38 | } | |
| 39 | } | |
| 40 | 109 | |
| 41 | fn shouldTestNonLlvm(target: *const std.Target) bool { | |
| 42 | if (comptime builtin.cpu.arch.endian() == .big) return false; // https://github.com/ziglang/zig/issues/25961 | |
| 43 | return switch (target.cpu.arch) { | |
| 44 | .x86_64 => switch (target.ofmt) { | |
| 45 | .elf => !target.os.tag.isBSD() and target.os.tag != .illumos, | |
| 46 | else => false, | |
| 47 | }, | |
| 48 | else => false, | |
| 49 | }; | |
| 110 | for (self.optimize_modes) |optimize| { | |
| 111 | if (optimize == params.optimize) break; | |
| 112 | } else return; | |
| 113 | ||
| 114 | error_traces_cases.addCases(self, params, &resolved_target.result); | |
| 115 | } | |
| 50 | 116 | } |
| 51 | 117 | |
| 52 | fn addCaseConfig( | |
| 53 | self: *ErrorTrace, | |
| 54 | case: Case, | |
| 55 | target: *const std.Build.ResolvedTarget, | |
| 56 | triple: ?[]const u8, | |
| 57 | optimize: OptimizeMode, | |
| 58 | backend: Case.Backend, | |
| 59 | ) void { | |
| 118 | /// Called from test/error_traces.zig | |
| 119 | pub fn addCase(self: *ErrorTrace, case: Case) void { | |
| 60 | 120 | const b = self.b; |
| 121 | const params = case.params; | |
| 122 | const target = case.target; | |
| 123 | const target_query = params.target; | |
| 124 | ||
| 125 | const triple: ?[]const u8 = if (target_query.isNative()) null else t: { | |
| 126 | break :t target_query.zigTriple(self.b.graph.arena) catch @panic("OOM"); | |
| 127 | }; | |
| 61 | 128 | |
| 62 | 129 | const error_tracing: bool = tracing: { |
| 63 | if (optimize == .debug) break :tracing true; | |
| 64 | if (backend != .llvm) break :tracing true; | |
| 65 | if (optimize == .small) break :tracing false; | |
| 130 | if (params.optimize == .debug) break :tracing true; | |
| 131 | if (params.use_llvm == false) break :tracing true; | |
| 132 | if (params.optimize == .small) break :tracing false; | |
| 66 | 133 | for (case.disable_trace_optimized) |disable| { |
| 67 | 134 | const d_arch, const d_os = disable; |
| 68 | if (target.result.cpu.arch == d_arch and target.result.os.tag == d_os) { | |
| 135 | if (target.cpu.arch == d_arch and target.os.tag == d_os) { | |
| 69 | 136 | // This particular configuration cannot do error tracing in optimized LLVM builds. |
| 70 | 137 | break :tracing false; |
| 71 | 138 | } |
| ... | ... | @@ -73,12 +140,19 @@ fn addCaseConfig( |
| 73 | 140 | break :tracing true; |
| 74 | 141 | }; |
| 75 | 142 | |
| 76 | const annotated_case_name = b.fmt("check {s} ({s}{s}{s} {s})", .{ | |
| 143 | const backend_string = if (params.use_llvm == true) | |
| 144 | "-llvm" | |
| 145 | else if (params.use_llvm == false) | |
| 146 | "-selfhosted" | |
| 147 | else | |
| 148 | ""; | |
| 149 | ||
| 150 | const annotated_case_name = b.fmt("check {s} ({s}{s}{t}{s})", .{ | |
| 77 | 151 | case.name, |
| 78 | 152 | triple orelse "", |
| 79 | 153 | if (triple != null) " " else "", |
| 80 | @tagName(optimize), | |
| 81 | @tagName(backend), | |
| 154 | params.optimize, | |
| 155 | backend_string, | |
| 82 | 156 | }); |
| 83 | 157 | if (self.test_filters.len > 0) { |
| 84 | 158 | for (self.test_filters) |test_filter| { |
| ... | ... | @@ -92,19 +166,18 @@ fn addCaseConfig( |
| 92 | 166 | .name = "test", |
| 93 | 167 | .root_module = b.createModule(.{ |
| 94 | 168 | .root_source_file = source_zig, |
| 95 | .optimize = optimize, | |
| 96 | .target = target.*, | |
| 169 | .optimize = params.optimize, | |
| 170 | .target = .{ .result = target.*, .query = target_query }, | |
| 97 | 171 | .error_tracing = error_tracing, |
| 98 | 172 | .strip = false, |
| 99 | 173 | }), |
| 100 | .use_llvm = switch (backend) { | |
| 101 | .llvm => true, | |
| 102 | .selfhosted => false, | |
| 103 | }, | |
| 174 | .use_llvm = params.use_llvm, | |
| 175 | .use_lld = params.use_lld, | |
| 104 | 176 | }); |
| 105 | 177 | exe.bundle_ubsan_rt = false; |
| 106 | 178 | |
| 107 | 179 | const run = b.addRunArtifact(exe); |
| 180 | run.skip_foreign_checks = true; | |
| 108 | 181 | run.removeEnvironmentVariable("CLICOLOR_FORCE"); |
| 109 | 182 | run.setEnvironmentVariable("NO_COLOR", "1"); |
| 110 | 183 | run.expectExitCode(1); |
| ... | ... | @@ -116,16 +189,10 @@ fn addCaseConfig( |
| 116 | 189 | }; |
| 117 | 190 | |
| 118 | 191 | const check_run = b.addRunArtifact(self.convert_exe); |
| 192 | check_run.skip_foreign_checks = true; | |
| 119 | 193 | check_run.setName(annotated_case_name); |
| 120 | 194 | check_run.addFileArg(run.captureStdErr(.{})); |
| 121 | 195 | check_run.expectStdOutEqual(expected_stderr); |
| 122 | 196 | |
| 123 | 197 | self.step.dependOn(&check_run.step); |
| 124 | 198 | } |
| 125 | ||
| 126 | const ErrorTrace = @This(); | |
| 127 | const std = @import("std"); | |
| 128 | const builtin = @import("builtin"); | |
| 129 | const Step = std.Build.Step; | |
| 130 | const OptimizeMode = std.builtin.OptimizeMode; | |
| 131 | const mem = std.mem; |
test/src/StackTrace.zig+155-92| ... | ... | @@ -1,10 +1,91 @@ |
| 1 | const StackTrace = @This(); | |
| 2 | ||
| 3 | const builtin = @import("builtin"); | |
| 4 | ||
| 5 | const std = @import("std"); | |
| 6 | const Step = std.Build.Step; | |
| 7 | const OptimizeMode = std.lang.Optimize; | |
| 8 | const mem = std.mem; | |
| 9 | ||
| 10 | const stack_traces_cases = @import("../stack_traces.zig"); | |
| 11 | ||
| 1 | 12 | b: *std.Build, |
| 2 | 13 | step: *Step, |
| 3 | 14 | test_filters: []const []const u8, |
| 4 | targets: []const std.Build.ResolvedTarget, | |
| 15 | skip_non_native: bool, | |
| 5 | 16 | convert_exe: *std.Build.Step.Compile, |
| 6 | 17 | |
| 18 | pub const CaseParameters = struct { | |
| 19 | target: std.Target.Query = .{}, | |
| 20 | optimize: std.builtin.OptimizeMode = .debug, | |
| 21 | link_libc: ?bool = null, | |
| 22 | use_llvm: ?bool = null, | |
| 23 | use_lld: ?bool = null, | |
| 24 | pie: ?bool = null, | |
| 25 | /// To enable this coverage, one of two things needs to happen: | |
| 26 | /// * The compiler needs to gain the ability to strip only debug info (not symbols) | |
| 27 | /// * `std.Build.Step.ObjCopy` needs to be un-regressed | |
| 28 | strip: ?bool = false, | |
| 29 | }; | |
| 30 | ||
| 31 | const param_sets = [_]CaseParameters{ | |
| 32 | .{}, | |
| 33 | .{ | |
| 34 | .link_libc = true, | |
| 35 | }, | |
| 36 | .{ | |
| 37 | .use_llvm = true, | |
| 38 | .use_lld = true, | |
| 39 | }, | |
| 40 | .{ | |
| 41 | .pie = true, | |
| 42 | }, | |
| 43 | .{ | |
| 44 | .target = .{ | |
| 45 | .cpu_arch = .aarch64, | |
| 46 | .os_tag = .windows, | |
| 47 | .abi = .msvc, | |
| 48 | }, | |
| 49 | }, | |
| 50 | .{ | |
| 51 | .target = .{ | |
| 52 | .cpu_arch = .x86_64, | |
| 53 | .os_tag = .windows, | |
| 54 | .abi = .gnu, | |
| 55 | }, | |
| 56 | }, | |
| 57 | .{ | |
| 58 | .target = .{ | |
| 59 | .cpu_arch = .x86, | |
| 60 | .os_tag = .windows, | |
| 61 | .abi = .msvc, | |
| 62 | }, | |
| 63 | }, | |
| 64 | .{ | |
| 65 | .target = .{ | |
| 66 | .cpu_arch = .aarch64, | |
| 67 | .os_tag = .macos, | |
| 68 | }, | |
| 69 | }, | |
| 70 | .{ | |
| 71 | .target = .{ | |
| 72 | .cpu_arch = .s390x, | |
| 73 | .os_tag = .linux, | |
| 74 | .abi = .none, | |
| 75 | }, | |
| 76 | }, | |
| 77 | .{ | |
| 78 | .target = .{ | |
| 79 | .cpu_arch = .loongarch32, | |
| 80 | .os_tag = .linux, | |
| 81 | .abi = .none, | |
| 82 | }, | |
| 83 | }, | |
| 84 | }; | |
| 85 | ||
| 7 | 86 | const Config = struct { |
| 87 | params: *const CaseParameters, | |
| 88 | target: *const std.Target, | |
| 8 | 89 | name: []const u8, |
| 9 | 90 | source: []const u8, |
| 10 | 91 | /// Whether this test case expects to have unwind tables / frame pointers. |
| ... | ... | @@ -26,42 +107,37 @@ const Config = struct { |
| 26 | 107 | expect_strip: []const u8, |
| 27 | 108 | }; |
| 28 | 109 | |
| 29 | pub fn addCase(self: *StackTrace, config: Config) void { | |
| 30 | for (self.targets) |*target| { | |
| 31 | addCaseTarget( | |
| 32 | self, | |
| 33 | config, | |
| 34 | target, | |
| 35 | if (target.query.isNative()) null else t: { | |
| 36 | break :t target.query.zigTriple(self.b.graph.arena) catch @panic("OOM"); | |
| 37 | }, | |
| 38 | ); | |
| 110 | pub fn addCases(self: *StackTrace) void { | |
| 111 | const b = self.b; | |
| 112 | ||
| 113 | for (&param_sets) |*params| { | |
| 114 | const resolved_target = b.resolveTargetQuery(params.target); | |
| 115 | ||
| 116 | if (self.skip_non_native and !resolved_target.query.isNative()) continue; | |
| 117 | ||
| 118 | // To avoid redundant testing, skip cross-compilation targets matching the host. | |
| 119 | if (resolved_target.result.os.tag == builtin.target.os.tag and | |
| 120 | resolved_target.result.cpu.arch == builtin.target.cpu.arch) | |
| 121 | { | |
| 122 | continue; | |
| 123 | } | |
| 124 | ||
| 125 | stack_traces_cases.addCases(self, params, &resolved_target.result); | |
| 39 | 126 | } |
| 40 | 127 | } |
| 41 | fn addCaseTarget( | |
| 42 | self: *StackTrace, | |
| 43 | config: Config, | |
| 44 | target: *const std.Build.ResolvedTarget, | |
| 45 | triple: ?[]const u8, | |
| 46 | ) void { | |
| 47 | const both_backends = b: { | |
| 48 | if (comptime builtin.cpu.arch.endian() == .big) break :b false; // https://github.com/ziglang/zig/issues/25961 | |
| 49 | break :b switch (target.result.cpu.arch) { | |
| 50 | .x86_64 => switch (target.result.ofmt) { | |
| 51 | .elf => !target.result.os.tag.isBSD() and target.result.os.tag != .illumos, | |
| 52 | else => false, | |
| 53 | }, | |
| 54 | else => false, | |
| 55 | }; | |
| 56 | }; | |
| 57 | const both_pie = switch (target.result.os.tag) { | |
| 58 | .fuchsia => false, | |
| 59 | else => true, | |
| 128 | ||
| 129 | /// Called from test/stack_traces.zig | |
| 130 | pub fn addCase(self: *StackTrace, config: Config) void { | |
| 131 | const params = config.params; | |
| 132 | const target = config.target; | |
| 133 | const target_query = config.params.target; | |
| 134 | ||
| 135 | const triple: ?[]const u8 = if (target_query.isNative()) null else t: { | |
| 136 | break :t target_query.zigTriple(self.b.graph.arena) catch @panic("OOM"); | |
| 60 | 137 | }; |
| 61 | const both_libc = !std.os.targetRequiresLibC(&target.result); | |
| 62 | 138 | |
| 63 | 139 | // See `std.debug.StackIterator.fp_usability` logic. |
| 64 | const fp_usability: enum { useless, unsafe, safe, ideal } = switch (target.result.cpu.arch) { | |
| 140 | const fp_usability: enum { useless, unsafe, safe, ideal } = switch (target.cpu.arch) { | |
| 65 | 141 | .alpha, |
| 66 | 142 | .csky, |
| 67 | 143 | .microblaze, |
| ... | ... | @@ -83,20 +159,15 @@ fn addCaseTarget( |
| 83 | 159 | .sparc, |
| 84 | 160 | .sparc64, |
| 85 | 161 | => .ideal, |
| 86 | .aarch64 => if (target.result.os.tag.isDarwin()) .safe else .unsafe, | |
| 162 | .aarch64 => if (target.os.tag.isDarwin()) .safe else .unsafe, | |
| 87 | 163 | else => .unsafe, |
| 88 | 164 | }; |
| 89 | const supports_unwind_tables = switch (target.result.os.tag) { | |
| 165 | const supports_unwind_tables = switch (target.os.tag) { | |
| 90 | 166 | // x86-windows just has no way to do stack unwinding other then using frame pointers. |
| 91 | .windows => target.result.cpu.arch != .x86, | |
| 167 | .windows => target.cpu.arch != .x86, | |
| 92 | 168 | else => true, |
| 93 | 169 | }; |
| 94 | 170 | |
| 95 | const use_llvm_vals: []const bool = if (both_backends) &.{ true, false } else &.{true}; | |
| 96 | const pie_vals: []const ?bool = if (both_pie) &.{ true, false } else &.{null}; | |
| 97 | const link_libc_vals: []const ?bool = if (both_libc) &.{ true, false } else &.{null}; | |
| 98 | const strip_debug_vals: []const bool = &.{ true, false }; | |
| 99 | ||
| 100 | 171 | const UnwindInfo = packed struct(u2) { |
| 101 | 172 | tables: bool, |
| 102 | 173 | fp: bool, |
| ... | ... | @@ -126,43 +197,33 @@ fn addCaseTarget( |
| 126 | 197 | }, |
| 127 | 198 | }; |
| 128 | 199 | |
| 129 | for (use_llvm_vals) |use_llvm| { | |
| 130 | for (pie_vals) |pie| { | |
| 131 | for (link_libc_vals) |link_libc| { | |
| 132 | for (strip_debug_vals) |strip_debug| { | |
| 133 | for (unwind_info_vals) |unwind_info| { | |
| 134 | if (unwind_info.tables and !supports_unwind_tables) continue; | |
| 135 | self.addCaseInstance( | |
| 136 | target, | |
| 137 | triple, | |
| 138 | config.name, | |
| 139 | config.source, | |
| 140 | use_llvm, | |
| 141 | pie, | |
| 142 | link_libc, | |
| 143 | strip_debug, | |
| 144 | !unwind_info.tables and supports_unwind_tables, | |
| 145 | !unwind_info.fp, | |
| 146 | config.expect_panic, | |
| 147 | if (strip_debug) config.expect_strip else config.expect, | |
| 148 | ); | |
| 149 | } | |
| 150 | } | |
| 151 | } | |
| 152 | } | |
| 200 | for (unwind_info_vals) |unwind_info| { | |
| 201 | if (unwind_info.tables and !supports_unwind_tables) continue; | |
| 202 | const strip = params.strip orelse switch (params.optimize) { | |
| 203 | .debug, .fast, .safe => false, | |
| 204 | .small => true, | |
| 205 | }; | |
| 206 | self.addCaseInstance( | |
| 207 | .{ .result = target.*, .query = target_query }, | |
| 208 | triple, | |
| 209 | config.name, | |
| 210 | config.source, | |
| 211 | params, | |
| 212 | !unwind_info.tables and supports_unwind_tables, | |
| 213 | !unwind_info.fp, | |
| 214 | config.expect_panic, | |
| 215 | if (strip) config.expect_strip else config.expect, | |
| 216 | ); | |
| 153 | 217 | } |
| 154 | 218 | } |
| 155 | 219 | |
| 156 | 220 | fn addCaseInstance( |
| 157 | 221 | self: *StackTrace, |
| 158 | target: *const std.Build.ResolvedTarget, | |
| 222 | resolved_target: std.Build.ResolvedTarget, | |
| 159 | 223 | triple: ?[]const u8, |
| 160 | 224 | name: []const u8, |
| 161 | 225 | source: []const u8, |
| 162 | use_llvm: bool, | |
| 163 | pie: ?bool, | |
| 164 | link_libc: ?bool, | |
| 165 | strip_debug: bool, | |
| 226 | params: *const CaseParameters, | |
| 166 | 227 | strip_unwind: bool, |
| 167 | 228 | omit_frame_pointer: bool, |
| 168 | 229 | expect_panic: bool, |
| ... | ... | @@ -170,13 +231,6 @@ fn addCaseInstance( |
| 170 | 231 | ) void { |
| 171 | 232 | const b = self.b; |
| 172 | 233 | |
| 173 | if (strip_debug) { | |
| 174 | // To enable this coverage, one of two things needs to happen: | |
| 175 | // * The compiler needs to gain the ability to strip only debug info (not symbols) | |
| 176 | // * `std.Build.Step.ObjCopy` needs to be un-regressed | |
| 177 | return; | |
| 178 | } | |
| 179 | ||
| 180 | 234 | if (strip_unwind) { |
| 181 | 235 | // To enable this coverage, `std.Build.Step.ObjCopy` needs to be un-regressed and gain the |
| 182 | 236 | // ability to remove individual sections. `-fno-unwind-tables` is insufficient because it |
| ... | ... | @@ -187,14 +241,28 @@ fn addCaseInstance( |
| 187 | 241 | return; |
| 188 | 242 | } |
| 189 | 243 | |
| 244 | const backend_string = if (params.use_llvm == true) | |
| 245 | " llvm" | |
| 246 | else if (params.use_llvm == false) | |
| 247 | " selfhosted" | |
| 248 | else | |
| 249 | ""; | |
| 250 | ||
| 251 | const strip_string = if (params.strip == true) | |
| 252 | " strip" | |
| 253 | else if (params.strip == false) | |
| 254 | " unstripped" | |
| 255 | else | |
| 256 | ""; | |
| 257 | ||
| 190 | 258 | const annotated_case_name = b.fmt("check {s} ({s}{s}{s}{s}{s}{s}{s}{s})", .{ |
| 191 | 259 | name, |
| 192 | 260 | triple orelse "", |
| 193 | 261 | if (triple != null) " " else "", |
| 194 | if (use_llvm) "llvm" else "selfhosted", | |
| 195 | if (pie == true) " pie" else "", | |
| 196 | if (link_libc == true) " libc" else "", | |
| 197 | if (strip_debug) " strip" else "", | |
| 262 | backend_string, | |
| 263 | if (params.pie == true) " pie" else "", | |
| 264 | if (params.link_libc == true) " libc" else "", | |
| 265 | strip_string, | |
| 198 | 266 | if (strip_unwind) " no_unwind" else "", |
| 199 | 267 | if (omit_frame_pointer) " no_fp" else "", |
| 200 | 268 | }); |
| ... | ... | @@ -211,24 +279,26 @@ fn addCaseInstance( |
| 211 | 279 | .root_module = b.createModule(.{ |
| 212 | 280 | .root_source_file = source_zig, |
| 213 | 281 | .optimize = .Debug, |
| 214 | .target = target.*, | |
| 282 | .target = resolved_target, | |
| 215 | 283 | .omit_frame_pointer = omit_frame_pointer, |
| 216 | .link_libc = link_libc, | |
| 284 | .link_libc = params.link_libc, | |
| 217 | 285 | .unwind_tables = if (strip_unwind) .none else null, |
| 218 | 286 | // make panics single-threaded so that they don't include a thread ID |
| 219 | 287 | .single_threaded = expect_panic, |
| 220 | 288 | }), |
| 221 | .use_llvm = use_llvm, | |
| 289 | .use_llvm = params.use_llvm, | |
| 290 | .use_lld = params.use_lld, | |
| 222 | 291 | }); |
| 223 | exe.pie = pie; | |
| 292 | exe.pie = params.pie; | |
| 224 | 293 | exe.bundle_ubsan_rt = false; |
| 225 | 294 | |
| 226 | 295 | const run = b.addRunArtifact(exe); |
| 296 | run.skip_foreign_checks = true; | |
| 227 | 297 | run.removeEnvironmentVariable("CLICOLOR_FORCE"); |
| 228 | 298 | run.setEnvironmentVariable("NO_COLOR", "1"); |
| 229 | 299 | run.addCheck(.{ .expect_term = term: { |
| 230 | 300 | if (!expect_panic) break :term .{ .exited = 0 }; |
| 231 | if (target.result.os.tag == .windows) break :term .{ .exited = 3 }; | |
| 301 | if (resolved_target.result.os.tag == .windows) break :term .{ .exited = 3 }; | |
| 232 | 302 | break :term .{ .signal = @fromBackingInt(@intCast(6)) }; |
| 233 | 303 | } }); |
| 234 | 304 | run.expectStdOutEqual(""); |
| ... | ... | @@ -241,10 +311,3 @@ fn addCaseInstance( |
| 241 | 311 | |
| 242 | 312 | self.step.dependOn(&check_run.step); |
| 243 | 313 | } |
| 244 | ||
| 245 | const StackTrace = @This(); | |
| 246 | const std = @import("std"); | |
| 247 | const builtin = @import("builtin"); | |
| 248 | const Step = std.Build.Step; | |
| 249 | const OptimizeMode = std.builtin.OptimizeMode; | |
| 250 | const mem = std.mem; |
test/stack_traces.zig+24-5| ... | ... | @@ -1,7 +1,10 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | const Context = @import("tests.zig").StackTracesContext; | |
| 2 | 3 | |
| 3 | pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target.Os.Tag) void { | |
| 4 | pub fn addCases(cases: *Context, params: *const Context.CaseParameters, target: *const std.Target) void { | |
| 4 | 5 | cases.addCase(.{ |
| 6 | .params = params, | |
| 7 | .target = target, | |
| 5 | 8 | .name = "simple panic", |
| 6 | 9 | .source = |
| 7 | 10 | \\pub fn main() void { |
| ... | ... | @@ -33,6 +36,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 33 | 36 | }); |
| 34 | 37 | |
| 35 | 38 | cases.addCase(.{ |
| 39 | .params = params, | |
| 40 | .target = target, | |
| 36 | 41 | .name = "simple panic with no unwind strategy", |
| 37 | 42 | .source = |
| 38 | 43 | \\pub fn main() void { |
| ... | ... | @@ -50,6 +55,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 50 | 55 | }); |
| 51 | 56 | |
| 52 | 57 | cases.addCase(.{ |
| 58 | .params = params, | |
| 59 | .target = target, | |
| 53 | 60 | .name = "dump current trace", |
| 54 | 61 | .source = |
| 55 | 62 | \\pub fn main() void { |
| ... | ... | @@ -89,6 +96,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 89 | 96 | }); |
| 90 | 97 | |
| 91 | 98 | cases.addCase(.{ |
| 99 | .params = params, | |
| 100 | .target = target, | |
| 92 | 101 | .name = "dump current trace with no unwind strategy", |
| 93 | 102 | .source = |
| 94 | 103 | \\pub fn main() void { |
| ... | ... | @@ -114,6 +123,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 114 | 123 | }); |
| 115 | 124 | |
| 116 | 125 | cases.addCase(.{ |
| 126 | .params = params, | |
| 127 | .target = target, | |
| 117 | 128 | .name = "dump captured trace", |
| 118 | 129 | .source = |
| 119 | 130 | \\pub fn main() void { |
| ... | ... | @@ -155,6 +166,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 155 | 166 | }); |
| 156 | 167 | |
| 157 | 168 | cases.addCase(.{ |
| 169 | .params = params, | |
| 170 | .target = target, | |
| 158 | 171 | .name = "dump captured trace with no unwind strategy", |
| 159 | 172 | .source = |
| 160 | 173 | \\pub fn main() void { |
| ... | ... | @@ -180,6 +193,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 180 | 193 | }); |
| 181 | 194 | |
| 182 | 195 | cases.addCase(.{ |
| 196 | .params = params, | |
| 197 | .target = target, | |
| 183 | 198 | .name = "dump captured trace on thread", |
| 184 | 199 | .source = |
| 185 | 200 | \\pub fn main() !void { |
| ... | ... | @@ -225,6 +240,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 225 | 240 | }); |
| 226 | 241 | |
| 227 | 242 | cases.addCase(.{ |
| 243 | .params = params, | |
| 244 | .target = target, | |
| 228 | 245 | .name = "simple inline panic", |
| 229 | 246 | // The main function has two inline calls to ensure |
| 230 | 247 | // that inlinees in PDBs are properly deduplicated. |
| ... | ... | @@ -240,7 +257,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 240 | 257 | , |
| 241 | 258 | .unwind = .any, |
| 242 | 259 | .expect_panic = true, |
| 243 | .expect = switch (os) { | |
| 260 | .expect = switch (target.os.tag) { | |
| 244 | 261 | // LLVM doesn't emit column info in the binary annotations for inlinee callees in PDBs, |
| 245 | 262 | // so the first location has only a row. |
| 246 | 263 | .windows => |
| ... | ... | @@ -262,7 +279,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 262 | 279 | \\ ^ |
| 263 | 280 | , |
| 264 | 281 | }, |
| 265 | .expect_strip = switch (os) { | |
| 282 | .expect_strip = switch (target.os.tag) { | |
| 266 | 283 | .windows => |
| 267 | 284 | \\panic: oh no |
| 268 | 285 | \\???:?:?: [address] in source.foo |
| ... | ... | @@ -279,6 +296,8 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 279 | 296 | |
| 280 | 297 | // Make sure all inline calls are resolved and in the right order! |
| 281 | 298 | cases.addCase(.{ |
| 299 | .params = params, | |
| 300 | .target = target, | |
| 282 | 301 | .name = "nested inline panic", |
| 283 | 302 | .source = |
| 284 | 303 | \\pub fn main() void { |
| ... | ... | @@ -298,7 +317,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 298 | 317 | .unwind = .any, |
| 299 | 318 | .expect_panic = true, |
| 300 | 319 | // This switch serves a similar purpose as in "inline panic". |
| 301 | .expect = switch (os) { | |
| 320 | .expect = switch (target.os.tag) { | |
| 302 | 321 | .windows => |
| 303 | 322 | \\panic: oh no |
| 304 | 323 | \\source.zig:11: [address] in baz |
| ... | ... | @@ -322,7 +341,7 @@ pub fn addCases(cases: *@import("tests.zig").StackTracesContext, os: std.Target. |
| 322 | 341 | \\ ^ |
| 323 | 342 | , |
| 324 | 343 | }, |
| 325 | .expect_strip = switch (os) { | |
| 344 | .expect_strip = switch (target.os.tag) { | |
| 326 | 345 | .windows => |
| 327 | 346 | \\panic: oh no |
| 328 | 347 | \\???:?:?: [address] in baz |
test/standalone/build.zig.zon-3| ... | ... | @@ -187,9 +187,6 @@ |
| 187 | 187 | .posix = .{ |
| 188 | 188 | .path = "posix", |
| 189 | 189 | }, |
| 190 | .debug_io_color = .{ | |
| 191 | .path = "debug_io_color", | |
| 192 | }, | |
| 193 | 190 | .elf2 = .{ |
| 194 | 191 | .path = "elf2", |
| 195 | 192 | }, |
test/standalone/debug_io_color/build.zig deleted-95| ... | ... | @@ -1,95 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub fn build(b: *std.Build) void { | |
| 4 | const test_step = b.step("test", "Test"); | |
| 5 | b.default_step = test_step; | |
| 6 | ||
| 7 | // Most targets handle color the same way, regardless of whether libc is linked. | |
| 8 | const native_target = b.graph.host; | |
| 9 | addTestCases(test_step, native_target, false); | |
| 10 | addTestCases(test_step, native_target, true); | |
| 11 | ||
| 12 | // WASI behaves differently depending on whether libc is linked. | |
| 13 | if (b.enable_wasmtime) { | |
| 14 | const wasi_target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .wasi }); | |
| 15 | addTestCases(test_step, wasi_target, false); | |
| 16 | addTestCases(test_step, wasi_target, true); | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | fn addTestCases( | |
| 21 | test_step: *std.Build.Step, | |
| 22 | target: std.Build.ResolvedTarget, | |
| 23 | link_libc: bool, | |
| 24 | ) void { | |
| 25 | const b = test_step.owner; | |
| 26 | const exe = b.addExecutable(.{ | |
| 27 | .name = b.fmt("{s}{s}", .{ @tagName(target.result.os.tag), if (link_libc) "-libc" else "" }), | |
| 28 | .root_module = b.createModule(.{ | |
| 29 | .root_source_file = b.path("main.zig"), | |
| 30 | .target = target, | |
| 31 | .link_libc = link_libc, | |
| 32 | }), | |
| 33 | }); | |
| 34 | ||
| 35 | // Should reflect 'std.process.Environ.Block' and 'std.Io.Threaded.init_single_threaded'. | |
| 36 | const debug_io_can_read_environ = switch (target.result.os.tag) { | |
| 37 | .windows => true, | |
| 38 | .wasi, .emscripten => link_libc, | |
| 39 | .freestanding, .other => false, | |
| 40 | else => true, | |
| 41 | }; | |
| 42 | ||
| 43 | // Don't forget to account for whether the build process's stderr supports color. | |
| 44 | const parent_stderr_color_enabled = (std.Io.Terminal.Mode.detect(b.graph.io, .stderr(), false, false) catch unreachable) != .no_color; | |
| 45 | ||
| 46 | _ = addTestCase(test_step, exe, "neither", .inherit, .manual, parent_stderr_color_enabled); | |
| 47 | _ = addTestCase(test_step, exe, "neither", .redirect, .manual, false); | |
| 48 | _ = addTestCase(test_step, exe, "no_color", .inherit, .disable, if (debug_io_can_read_environ) false else parent_stderr_color_enabled); | |
| 49 | _ = addTestCase(test_step, exe, "no_color", .redirect, .disable, false); | |
| 50 | _ = addTestCase(test_step, exe, "clicolor_force", .inherit, .enable, if (debug_io_can_read_environ) true else parent_stderr_color_enabled); | |
| 51 | _ = addTestCase(test_step, exe, "clicolor_force", .redirect, .enable, debug_io_can_read_environ); | |
| 52 | ||
| 53 | const both = addTestCase(test_step, exe, "both", .inherit, .manual, if (debug_io_can_read_environ) false else parent_stderr_color_enabled); | |
| 54 | both.setEnvironmentVariable("NO_COLOR", "1"); | |
| 55 | both.setEnvironmentVariable("CLICOLOR_FORCE", "1"); | |
| 56 | ||
| 57 | const both_redirected = addTestCase(test_step, exe, "both", .redirect, .manual, false); | |
| 58 | both_redirected.setEnvironmentVariable("NO_COLOR", "1"); | |
| 59 | both_redirected.setEnvironmentVariable("CLICOLOR_FORCE", "1"); | |
| 60 | } | |
| 61 | ||
| 62 | fn addTestCase( | |
| 63 | test_step: *std.Build.Step, | |
| 64 | exe: *std.Build.Step.Compile, | |
| 65 | test_case_name: []const u8, | |
| 66 | stderr: enum { inherit, redirect }, | |
| 67 | run_step_color: std.Build.Step.Run.Color, | |
| 68 | expected_color_enabled: bool, | |
| 69 | ) *std.Build.Step.Run { | |
| 70 | const b = test_step.owner; | |
| 71 | const step_name = b.fmt("{s} {s}{s}", .{ | |
| 72 | exe.name, | |
| 73 | test_case_name, | |
| 74 | if (stderr == .redirect) "-redirect" else "", | |
| 75 | }); | |
| 76 | const run_exe = b.addRunArtifact(exe); | |
| 77 | run_exe.setName(b.fmt("run {s}", .{step_name})); | |
| 78 | ||
| 79 | run_exe.failing_to_execute_foreign_is_an_error = false; | |
| 80 | if (stderr == .redirect) run_exe.expectStdErrMatch(""); | |
| 81 | ||
| 82 | run_exe.clearEnvironment(); | |
| 83 | run_exe.color = run_step_color; | |
| 84 | ||
| 85 | // Build system quirk: Currently, Run step stdout checks will also redirect stderr, so as a | |
| 86 | // workaround we use a CheckFile step instead. We must also mark the Run step as having side | |
| 87 | // effects, to ensure the parent stderr is inherited when not explicitly redirected. | |
| 88 | run_exe.has_side_effects = true; | |
| 89 | const stdout = run_exe.captureStdOut(.{}); | |
| 90 | const check_file = b.addCheckFile(stdout, .{ .expected_exact = if (expected_color_enabled) "true" else "false" }); | |
| 91 | check_file.setName(b.fmt("check {s}", .{step_name})); | |
| 92 | test_step.dependOn(&check_file.step); | |
| 93 | ||
| 94 | return run_exe; | |
| 95 | } |
test/standalone/debug_io_color/main.zig deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub fn main() !void { | |
| 4 | const stderr = std.debug.lockStderr(&.{}); | |
| 5 | defer std.debug.unlockStderr(); | |
| 6 | try std.Io.File.stdout().writeStreamingAll(std.Options.debug_io, if (stderr.terminal_mode != .no_color) "true" else "false"); | |
| 7 | } |
test/tests.zig+27-138| ... | ... | @@ -6,8 +6,6 @@ const OptimizeMode = std.builtin.OptimizeMode; |
| 6 | 6 | const Step = std.Build.Step; |
| 7 | 7 | |
| 8 | 8 | // Cases |
| 9 | const error_traces = @import("error_traces.zig"); | |
| 10 | const stack_traces = @import("stack_traces.zig"); | |
| 11 | 9 | const llvm_ir = @import("llvm_ir.zig"); |
| 12 | 10 | const libc = @import("libc.zig"); |
| 13 | 11 | const link = @import("link.zig"); |
| ... | ... | @@ -2381,59 +2379,7 @@ pub fn isNative(actual_target: *const std.Build.ResolvedTarget, host: *const std |
| 2381 | 2379 | return true; |
| 2382 | 2380 | } |
| 2383 | 2381 | |
| 2384 | /// For stack trace tests, we only test native by default, because external executors are pretty | |
| 2385 | /// unreliable at stack tracing. However, if there's a 32-bit equivalent target which the host can | |
| 2386 | /// trivially run, we may as well at least test that! | |
| 2387 | fn nativeAndCompatible32bit(b: *std.Build, skip_non_native: bool) []const std.Build.ResolvedTarget { | |
| 2388 | const host = b.graph.host.result; | |
| 2389 | const only_native = (&b.graph.host)[0..1]; | |
| 2390 | if (skip_non_native) return only_native; | |
| 2391 | const arch32 = compatible32bitArch(&b.graph.host.result) orelse return only_native; | |
| 2392 | return b.graph.arena.dupe(std.Build.ResolvedTarget, &.{ | |
| 2393 | b.graph.host, | |
| 2394 | b.resolveTargetQuery(.{ .cpu_arch = arch32, .os_tag = host.os.tag }), | |
| 2395 | }) catch @panic("OOM"); | |
| 2396 | } | |
| 2397 | ||
| 2398 | fn wineAndCompatible32bit(b: *std.Build, skip_non_native: bool) []const std.Build.ResolvedTarget { | |
| 2399 | var targets: std.ArrayList(std.Build.ResolvedTarget) = .empty; | |
| 2400 | ||
| 2401 | const host = b.graph.host.result; | |
| 2402 | ||
| 2403 | targets.append(b.graph.arena, b.resolveTargetQuery(.{ | |
| 2404 | .cpu_arch = host.cpu.arch, | |
| 2405 | .os_tag = .windows, | |
| 2406 | })) catch @panic("OOM"); | |
| 2407 | if (!skip_non_native) { | |
| 2408 | if (compatible32bitArch(&b.graph.host.result)) |arch| { | |
| 2409 | targets.append(b.graph.arena, b.resolveTargetQuery(.{ | |
| 2410 | .cpu_arch = arch, | |
| 2411 | .os_tag = .windows, | |
| 2412 | })) catch @panic("OOM"); | |
| 2413 | } | |
| 2414 | } | |
| 2415 | ||
| 2416 | return targets.toOwnedSlice(b.graph.arena) catch @panic("OOM"); | |
| 2417 | } | |
| 2418 | ||
| 2419 | fn darlingTargets(b: *std.Build) []const std.Build.ResolvedTarget { | |
| 2420 | var targets: std.ArrayList(std.Build.ResolvedTarget) = .empty; | |
| 2421 | ||
| 2422 | const host = b.graph.host.result; | |
| 2423 | ||
| 2424 | targets.append(b.graph.arena, b.resolveTargetQuery(.{ | |
| 2425 | .cpu_arch = host.cpu.arch, | |
| 2426 | .os_tag = .macos, | |
| 2427 | })) catch @panic("OOM"); | |
| 2428 | ||
| 2429 | return targets.toOwnedSlice(b.graph.arena) catch @panic("OOM"); | |
| 2430 | } | |
| 2431 | ||
| 2432 | pub fn addStackTraceTests( | |
| 2433 | b: *std.Build, | |
| 2434 | test_filters: []const []const u8, | |
| 2435 | skip_non_native: bool, | |
| 2436 | ) *Step { | |
| 2382 | pub fn addStackTraceTests(b: *std.Build, test_filters: []const []const u8, skip_non_native: bool) *Step { | |
| 2437 | 2383 | const step = b.step("test-stack-traces", "Run the stack trace tests"); |
| 2438 | 2384 | |
| 2439 | 2385 | const convert_exe = b.addExecutable(.{ |
| ... | ... | @@ -2445,39 +2391,15 @@ pub fn addStackTraceTests( |
| 2445 | 2391 | }), |
| 2446 | 2392 | }); |
| 2447 | 2393 | |
| 2448 | const host_cases = b.allocator.create(StackTracesContext) catch @panic("OOM"); | |
| 2449 | host_cases.* = .{ | |
| 2394 | const stack_traces_context = b.allocator.create(StackTracesContext) catch @panic("OOM"); | |
| 2395 | stack_traces_context.* = .{ | |
| 2450 | 2396 | .b = b, |
| 2451 | 2397 | .step = step, |
| 2452 | 2398 | .test_filters = test_filters, |
| 2453 | .targets = nativeAndCompatible32bit(b, skip_non_native), | |
| 2399 | .skip_non_native = skip_non_native, | |
| 2454 | 2400 | .convert_exe = convert_exe, |
| 2455 | 2401 | }; |
| 2456 | stack_traces.addCases(host_cases, b.graph.host.result.os.tag); | |
| 2457 | ||
| 2458 | if (b.enable_wine) { | |
| 2459 | const wine_cases = b.allocator.create(StackTracesContext) catch @panic("OOM"); | |
| 2460 | wine_cases.* = .{ | |
| 2461 | .b = b, | |
| 2462 | .step = step, | |
| 2463 | .test_filters = test_filters, | |
| 2464 | .targets = wineAndCompatible32bit(b, skip_non_native), | |
| 2465 | .convert_exe = convert_exe, | |
| 2466 | }; | |
| 2467 | stack_traces.addCases(wine_cases, .windows); | |
| 2468 | } | |
| 2469 | ||
| 2470 | if (b.enable_darling) { | |
| 2471 | const darling_cases = b.allocator.create(StackTracesContext) catch @panic("OOM"); | |
| 2472 | darling_cases.* = .{ | |
| 2473 | .b = b, | |
| 2474 | .step = step, | |
| 2475 | .test_filters = test_filters, | |
| 2476 | .targets = darlingTargets(b), | |
| 2477 | .convert_exe = convert_exe, | |
| 2478 | }; | |
| 2479 | stack_traces.addCases(darling_cases, .macos); | |
| 2480 | } | |
| 2402 | stack_traces_context.addCases(); | |
| 2481 | 2403 | |
| 2482 | 2404 | return step; |
| 2483 | 2405 | } |
| ... | ... | @@ -2499,52 +2421,20 @@ pub fn addErrorTraceTests( |
| 2499 | 2421 | }), |
| 2500 | 2422 | }); |
| 2501 | 2423 | |
| 2502 | const host_cases = b.allocator.create(ErrorTracesContext) catch @panic("OOM"); | |
| 2503 | host_cases.* = .{ | |
| 2424 | const error_traces_context = b.allocator.create(ErrorTracesContext) catch @panic("OOM"); | |
| 2425 | error_traces_context.* = .{ | |
| 2504 | 2426 | .b = b, |
| 2505 | 2427 | .step = step, |
| 2506 | 2428 | .test_filters = test_filters, |
| 2507 | .targets = nativeAndCompatible32bit(b, skip_non_native), | |
| 2429 | .skip_non_native = skip_non_native, | |
| 2508 | 2430 | .optimize_modes = optimize_modes, |
| 2509 | 2431 | .convert_exe = convert_exe, |
| 2510 | 2432 | }; |
| 2511 | error_traces.addCases(host_cases, b.graph.host.result.os.tag); | |
| 2512 | ||
| 2513 | if (b.enable_wine) { | |
| 2514 | const wine_cases = b.allocator.create(ErrorTracesContext) catch @panic("OOM"); | |
| 2515 | wine_cases.* = .{ | |
| 2516 | .b = b, | |
| 2517 | .step = step, | |
| 2518 | .test_filters = test_filters, | |
| 2519 | .targets = wineAndCompatible32bit(b, skip_non_native), | |
| 2520 | .optimize_modes = optimize_modes, | |
| 2521 | .convert_exe = convert_exe, | |
| 2522 | }; | |
| 2523 | error_traces.addCases(wine_cases, .windows); | |
| 2524 | } | |
| 2525 | ||
| 2526 | if (b.enable_darling) { | |
| 2527 | const darling_cases = b.allocator.create(ErrorTracesContext) catch @panic("OOM"); | |
| 2528 | darling_cases.* = .{ | |
| 2529 | .b = b, | |
| 2530 | .step = step, | |
| 2531 | .test_filters = test_filters, | |
| 2532 | .targets = darlingTargets(b), | |
| 2533 | .optimize_modes = optimize_modes, | |
| 2534 | .convert_exe = convert_exe, | |
| 2535 | }; | |
| 2536 | error_traces.addCases(darling_cases, .macos); | |
| 2537 | } | |
| 2433 | error_traces_context.addCases(); | |
| 2538 | 2434 | |
| 2539 | 2435 | return step; |
| 2540 | 2436 | } |
| 2541 | 2437 | |
| 2542 | fn compilerHasPackageManager(b: *std.Build) bool { | |
| 2543 | // We can only use dependencies if the compiler was built with support for package management. | |
| 2544 | // (zig2 doesn't support it, but we still need to construct a build graph to build stage3.) | |
| 2545 | return b.available_deps.len != 0; | |
| 2546 | } | |
| 2547 | ||
| 2548 | 2438 | pub fn addStandaloneTests( |
| 2549 | 2439 | b: *std.Build, |
| 2550 | 2440 | optimize_modes: []const OptimizeMode, |
| ... | ... | @@ -2553,21 +2443,19 @@ pub fn addStandaloneTests( |
| 2553 | 2443 | enable_symlinks_windows: bool, |
| 2554 | 2444 | ) *Step { |
| 2555 | 2445 | const step = b.step("test-standalone", "Run the standalone tests"); |
| 2556 | if (compilerHasPackageManager(b)) { | |
| 2557 | const test_cases_dep_name = "standalone_test_cases"; | |
| 2558 | const test_cases_dep = b.dependency(test_cases_dep_name, .{ | |
| 2559 | .enable_ios_sdk = enable_ios_sdk, | |
| 2560 | .enable_macos_sdk = enable_macos_sdk, | |
| 2561 | .enable_symlinks_windows = enable_symlinks_windows, | |
| 2562 | .simple_skip_debug = mem.findScalar(OptimizeMode, optimize_modes, .debug) == null, | |
| 2563 | .simple_skip_release_safe = mem.findScalar(OptimizeMode, optimize_modes, .safe) == null, | |
| 2564 | .simple_skip_release_fast = mem.findScalar(OptimizeMode, optimize_modes, .fast) == null, | |
| 2565 | .simple_skip_release_small = mem.findScalar(OptimizeMode, optimize_modes, .small) == null, | |
| 2566 | }); | |
| 2567 | const test_cases_dep_step = test_cases_dep.builder.default_step; | |
| 2568 | test_cases_dep_step.name = b.graph.dupeString(test_cases_dep_name); | |
| 2569 | step.dependOn(test_cases_dep.builder.default_step); | |
| 2570 | } | |
| 2446 | const test_cases_dep_name = "standalone_test_cases"; | |
| 2447 | const test_cases_dep = b.dependency(test_cases_dep_name, .{ | |
| 2448 | .enable_ios_sdk = enable_ios_sdk, | |
| 2449 | .enable_macos_sdk = enable_macos_sdk, | |
| 2450 | .enable_symlinks_windows = enable_symlinks_windows, | |
| 2451 | .simple_skip_debug = mem.findScalar(OptimizeMode, optimize_modes, .debug) == null, | |
| 2452 | .simple_skip_release_safe = mem.findScalar(OptimizeMode, optimize_modes, .safe) == null, | |
| 2453 | .simple_skip_release_fast = mem.findScalar(OptimizeMode, optimize_modes, .fast) == null, | |
| 2454 | .simple_skip_release_small = mem.findScalar(OptimizeMode, optimize_modes, .small) == null, | |
| 2455 | }); | |
| 2456 | const test_cases_dep_step = test_cases_dep.builder.default_step; | |
| 2457 | test_cases_dep_step.name = b.graph.dupeString(test_cases_dep_name); | |
| 2458 | step.dependOn(test_cases_dep.builder.default_step); | |
| 2571 | 2459 | return step; |
| 2572 | 2460 | } |
| 2573 | 2461 | |
| ... | ... | @@ -3417,10 +3305,11 @@ pub fn addIncrementalTests(b: *std.Build, test_step: *Step, test_filters: []cons |
| 3417 | 3305 | |
| 3418 | 3306 | run.addArg("--quiet"); // don't fill stderr telling us about skipped tests etc |
| 3419 | 3307 | |
| 3420 | if (b.enable_qemu) run.addArg("-fqemu"); | |
| 3421 | if (b.enable_wine) run.addArg("-fwine"); | |
| 3422 | if (b.enable_wasmtime) run.addArg("-fwasmtime"); | |
| 3423 | if (b.enable_darling) run.addArg("-fdarling"); | |
| 3308 | run.addThirdPartyEnabledArgDarling(.{ .enabled = "-fdarling" }); | |
| 3309 | run.addThirdPartyEnabledArgQemu(.{ .enabled = "-fqemu" }); | |
| 3310 | run.addThirdPartyEnabledArgRosetta(.{ .enabled = "-frosetta" }); | |
| 3311 | run.addThirdPartyEnabledArgWasmtime(.{ .enabled = "-fwasmtime" }); | |
| 3312 | run.addThirdPartyEnabledArgWine(.{ .enabled = "-fwine" }); | |
| 3424 | 3313 | |
| 3425 | 3314 | run.addCheck(.{ .expect_term = .{ .exited = 0 } }); |
| 3426 | 3315 | test_step.dependOn(&run.step); |