authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-28 14:07:28+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-11-28 14:07:28+01:00
log8594f179f9d70fbc3bf39111c4e1f147d4a6dc3c
tree5221ffb639a15071af4c079d7dd75a8f2cf55497
parent6cf01a679f1950f1393d9245048a62500e3869c1
parent5beb5f20d282fd0db8715899ba6a5d6630d91bb4
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #22067 from alexrp/pie-tests

Add PIC/PIE tests and fix some bugs + some improvements to the test harness

28 files changed, 267 insertions(+), 57 deletions(-)

build.zig+7-2
...@@ -442,7 +442,7 @@ pub fn build(b: *std.Build) !void {...@@ -442,7 +442,7 @@ pub fn build(b: *std.Build) !void {
442 test_step.dependOn(check_fmt);442 test_step.dependOn(check_fmt);
443443
444 const test_cases_step = b.step("test-cases", "Run the main compiler test cases");444 const test_cases_step = b.step("test-cases", "Run the main compiler test cases");
445 try tests.addCases(b, test_cases_step, test_filters, target, .{445 try tests.addCases(b, test_cases_step, test_filters, test_target_filters, target, .{
446 .skip_translate_c = skip_translate_c,446 .skip_translate_c = skip_translate_c,
447 .skip_run_translated_c = skip_run_translated_c,447 .skip_run_translated_c = skip_run_translated_c,
448 }, .{448 }, .{
...@@ -541,13 +541,18 @@ pub fn build(b: *std.Build) !void {...@@ -541,13 +541,18 @@ pub fn build(b: *std.Build) !void {
541 enable_ios_sdk,541 enable_ios_sdk,
542 enable_symlinks_windows,542 enable_symlinks_windows,
543 ));543 ));
544 test_step.dependOn(tests.addCAbiTests(b, skip_non_native, skip_release));544 test_step.dependOn(tests.addCAbiTests(b, .{
545 .test_target_filters = test_target_filters,
546 .skip_non_native = skip_non_native,
547 .skip_release = skip_release,
548 }));
545 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));549 test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
546 test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));550 test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));
547 test_step.dependOn(tests.addCliTests(b));551 test_step.dependOn(tests.addCliTests(b));
548 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));552 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));
549 if (tests.addDebuggerTests(b, .{553 if (tests.addDebuggerTests(b, .{
550 .test_filters = test_filters,554 .test_filters = test_filters,
555 .test_target_filters = test_target_filters,
551 .gdb = b.option([]const u8, "gdb", "path to gdb binary"),556 .gdb = b.option([]const u8, "gdb", "path to gdb binary"),
552 .lldb = b.option([]const u8, "lldb", "path to lldb binary"),557 .lldb = b.option([]const u8, "lldb", "path to lldb binary"),
553 .optimize_modes = optimization_modes,558 .optimize_modes = optimization_modes,
lib/std/Build/Cache.zig+5
...@@ -217,6 +217,11 @@ pub const HashHelper = struct {...@@ -217,6 +217,11 @@ pub const HashHelper = struct {
217 },217 },
218 std.Target.Os.TaggedVersionRange => {218 std.Target.Os.TaggedVersionRange => {
219 switch (x) {219 switch (x) {
220 .hurd => |hurd| {
221 hh.add(hurd.range.min);
222 hh.add(hurd.range.max);
223 hh.add(hurd.glibc);
224 },
220 .linux => |linux| {225 .linux => |linux| {
221 hh.add(linux.range.min);226 hh.add(linux.range.min);
222 hh.add(linux.range.max);227 hh.add(linux.range.max);
lib/std/Target.zig+38-5
...@@ -187,7 +187,6 @@ pub const Os = struct {...@@ -187,7 +187,6 @@ pub const Os = struct {
187 .hermit,187 .hermit,
188188
189 .aix,189 .aix,
190 .hurd,
191 .rtems,190 .rtems,
192 .zos,191 .zos,
193192
...@@ -218,6 +217,7 @@ pub const Os = struct {...@@ -218,6 +217,7 @@ pub const Os = struct {
218 .vulkan,217 .vulkan,
219 => .semver,218 => .semver,
220219
220 .hurd => .hurd,
221 .linux => .linux,221 .linux => .linux,
222222
223 .windows => .windows,223 .windows => .windows,
...@@ -356,6 +356,21 @@ pub const Os = struct {...@@ -356,6 +356,21 @@ pub const Os = struct {
356 }356 }
357 };357 };
358358
359 pub const HurdVersionRange = struct {
360 range: std.SemanticVersion.Range,
361 glibc: std.SemanticVersion,
362
363 pub inline fn includesVersion(range: HurdVersionRange, ver: std.SemanticVersion) bool {
364 return range.range.includesVersion(ver);
365 }
366
367 /// Checks if system is guaranteed to be at least `version` or older than `version`.
368 /// Returns `null` if a runtime check is required.
369 pub inline fn isAtLeast(range: HurdVersionRange, ver: std.SemanticVersion) ?bool {
370 return range.range.isAtLeast(ver);
371 }
372 };
373
359 pub const LinuxVersionRange = struct {374 pub const LinuxVersionRange = struct {
360 range: std.SemanticVersion.Range,375 range: std.SemanticVersion.Range,
361 glibc: std.SemanticVersion,376 glibc: std.SemanticVersion,
...@@ -400,6 +415,7 @@ pub const Os = struct {...@@ -400,6 +415,7 @@ pub const Os = struct {
400 pub const VersionRange = union {415 pub const VersionRange = union {
401 none: void,416 none: void,
402 semver: std.SemanticVersion.Range,417 semver: std.SemanticVersion.Range,
418 hurd: HurdVersionRange,
403 linux: LinuxVersionRange,419 linux: LinuxVersionRange,
404 windows: WindowsVersion.Range,420 windows: WindowsVersion.Range,
405421
...@@ -456,9 +472,12 @@ pub const Os = struct {...@@ -456,9 +472,12 @@ pub const Os = struct {
456 },472 },
457 },473 },
458 .hurd => .{474 .hurd => .{
459 .semver = .{475 .hurd = .{
460 .min = .{ .major = 0, .minor = 9, .patch = 0 },476 .range = .{
461 .max = .{ .major = 0, .minor = 9, .patch = 0 },477 .min = .{ .major = 0, .minor = 9, .patch = 0 },
478 .max = .{ .major = 0, .minor = 9, .patch = 0 },
479 },
480 .glibc = .{ .major = 2, .minor = 28, .patch = 0 },
462 },481 },
463 },482 },
464 .linux => .{483 .linux => .{
...@@ -632,8 +651,17 @@ pub const Os = struct {...@@ -632,8 +651,17 @@ pub const Os = struct {
632 pub const TaggedVersionRange = union(enum) {651 pub const TaggedVersionRange = union(enum) {
633 none: void,652 none: void,
634 semver: std.SemanticVersion.Range,653 semver: std.SemanticVersion.Range,
654 hurd: HurdVersionRange,
635 linux: LinuxVersionRange,655 linux: LinuxVersionRange,
636 windows: WindowsVersion.Range,656 windows: WindowsVersion.Range,
657
658 pub fn gnuLibCVersion(range: TaggedVersionRange) ?std.SemanticVersion {
659 return switch (range) {
660 .none, .semver, .windows => null,
661 .hurd => |h| h.glibc,
662 .linux => |l| l.glibc,
663 };
664 }
637 };665 };
638666
639 /// Provides a tagged union. `Target` does not store the tag because it is667 /// Provides a tagged union. `Target` does not store the tag because it is
...@@ -642,6 +670,7 @@ pub const Os = struct {...@@ -642,6 +670,7 @@ pub const Os = struct {
642 return switch (os.tag.versionRangeTag()) {670 return switch (os.tag.versionRangeTag()) {
643 .none => .{ .none = {} },671 .none => .{ .none = {} },
644 .semver => .{ .semver = os.version_range.semver },672 .semver => .{ .semver = os.version_range.semver },
673 .hurd => .{ .hurd = os.version_range.hurd },
645 .linux => .{ .linux = os.version_range.linux },674 .linux => .{ .linux = os.version_range.linux },
646 .windows => .{ .windows = os.version_range.windows },675 .windows => .{ .windows = os.version_range.windows },
647 };676 };
...@@ -651,12 +680,13 @@ pub const Os = struct {...@@ -651,12 +680,13 @@ pub const Os = struct {
651 /// Returns `null` if a runtime check is required.680 /// Returns `null` if a runtime check is required.
652 pub inline fn isAtLeast(os: Os, comptime tag: Tag, ver: switch (tag.versionRangeTag()) {681 pub inline fn isAtLeast(os: Os, comptime tag: Tag, ver: switch (tag.versionRangeTag()) {
653 .none => void,682 .none => void,
654 .semver, .linux => std.SemanticVersion,683 .semver, .hurd, .linux => std.SemanticVersion,
655 .windows => WindowsVersion,684 .windows => WindowsVersion,
656 }) ?bool {685 }) ?bool {
657 return if (os.tag != tag) false else switch (tag.versionRangeTag()) {686 return if (os.tag != tag) false else switch (tag.versionRangeTag()) {
658 .none => true,687 .none => true,
659 inline .semver,688 inline .semver,
689 .hurd,
660 .linux,690 .linux,
661 .windows,691 .windows,
662 => |field| @field(os.version_range, @tagName(field)).isAtLeast(ver),692 => |field| @field(os.version_range, @tagName(field)).isAtLeast(ver),
...@@ -832,6 +862,9 @@ pub const Abi = enum {...@@ -832,6 +862,9 @@ pub const Abi = enum {
832 .mips,862 .mips,
833 .mipsel,863 .mipsel,
834 => .musleabi,864 => .musleabi,
865 .mips64,
866 .mips64el,
867 => .muslabi64,
835 else => .musl,868 else => .musl,
836 },869 },
837 .rtems => switch (arch) {870 .rtems => switch (arch) {
lib/std/Target/Query.zig+5-5
...@@ -102,7 +102,7 @@ pub fn fromTarget(target: Target) Query {...@@ -102,7 +102,7 @@ pub fn fromTarget(target: Target) Query {
102 .os_version_min = undefined,102 .os_version_min = undefined,
103 .os_version_max = undefined,103 .os_version_max = undefined,
104 .abi = target.abi,104 .abi = target.abi,
105 .glibc_version = if (target.isGnuLibC()) target.os.version_range.linux.glibc else null,105 .glibc_version = target.os.versionRange().gnuLibCVersion(),
106 .android_api_level = if (target.abi.isAndroid()) target.os.version_range.linux.android else null,106 .android_api_level = if (target.abi.isAndroid()) target.os.version_range.linux.android else null,
107 };107 };
108 result.updateOsVersionRange(target.os);108 result.updateOsVersionRange(target.os);
...@@ -132,9 +132,9 @@ fn updateOsVersionRange(self: *Query, os: Target.Os) void {...@@ -132,9 +132,9 @@ fn updateOsVersionRange(self: *Query, os: Target.Os) void {
132 .{ .semver = os.version_range.semver.min },132 .{ .semver = os.version_range.semver.min },
133 .{ .semver = os.version_range.semver.max },133 .{ .semver = os.version_range.semver.max },
134 },134 },
135 .linux => .{135 inline .hurd, .linux => |t| .{
136 .{ .semver = os.version_range.linux.range.min },136 .{ .semver = @field(os.version_range, @tagName(t)).range.min },
137 .{ .semver = os.version_range.linux.range.max },137 .{ .semver = @field(os.version_range, @tagName(t)).range.max },
138 },138 },
139 .windows => .{139 .windows => .{
140 .{ .windows = os.version_range.windows.min },140 .{ .windows = os.version_range.windows.min },
...@@ -544,7 +544,7 @@ fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !...@@ -544,7 +544,7 @@ fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !
544 const version_text = it.rest();544 const version_text = it.rest();
545 if (version_text.len > 0) switch (tag.versionRangeTag()) {545 if (version_text.len > 0) switch (tag.versionRangeTag()) {
546 .none => return error.InvalidOperatingSystemVersion,546 .none => return error.InvalidOperatingSystemVersion,
547 .semver, .linux => range: {547 .semver, .hurd, .linux => range: {
548 var range_it = mem.splitSequence(u8, version_text, "...");548 var range_it = mem.splitSequence(u8, version_text, "...");
549 result.os_version_min = .{549 result.os_version_min = .{
550 .semver = parseVersion(range_it.first()) catch |err| switch (err) {550 .semver = parseVersion(range_it.first()) catch |err| switch (err) {
lib/std/c.zig+2-3
...@@ -56,9 +56,8 @@ pub inline fn versionCheck(comptime version: std.SemanticVersion) bool {...@@ -56,9 +56,8 @@ pub inline fn versionCheck(comptime version: std.SemanticVersion) bool {
56 if (!builtin.link_libc) break :blk false;56 if (!builtin.link_libc) break :blk false;
57 if (native_abi.isMusl()) break :blk true;57 if (native_abi.isMusl()) break :blk true;
58 if (builtin.target.isGnuLibC()) {58 if (builtin.target.isGnuLibC()) {
59 const ver = builtin.os.version_range.linux.glibc;59 const ver = builtin.os.versionRange().gnuLibCVersion().?;
60 const order = ver.order(version);60 break :blk switch (ver.order(version)) {
61 break :blk switch (order) {
62 .gt, .eq => true,61 .gt, .eq => true,
63 .lt => false,62 .lt => false,
64 };63 };
lib/std/os/linux/pie.zig+1-1
...@@ -178,7 +178,7 @@ inline fn getDynamicSymbol() [*]elf.Dyn {...@@ -178,7 +178,7 @@ inline fn getDynamicSymbol() [*]elf.Dyn {
178 \\ .hidden _DYNAMIC178 \\ .hidden _DYNAMIC
179 \\ larl %[ret], 1f179 \\ larl %[ret], 1f
180 \\ ag %[ret], 0(%[ret])180 \\ ag %[ret], 0(%[ret])
181 \\ b 2f181 \\ jg 2f
182 \\ 1: .quad _DYNAMIC - .182 \\ 1: .quad _DYNAMIC - .
183 \\ 2:183 \\ 2:
184 : [ret] "=r" (-> [*]elf.Dyn),184 : [ret] "=r" (-> [*]elf.Dyn),
lib/std/zig/system.zig+8-5
...@@ -311,8 +311,8 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {...@@ -311,8 +311,8 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
311311
312 if (query.os_version_min) |min| switch (min) {312 if (query.os_version_min) |min| switch (min) {
313 .none => {},313 .none => {},
314 .semver => |semver| switch (os.tag) {314 .semver => |semver| switch (os.tag.versionRangeTag()) {
315 .linux => os.version_range.linux.range.min = semver,315 inline .hurd, .linux => |t| @field(os.version_range, @tagName(t)).range.min = semver,
316 else => os.version_range.semver.min = semver,316 else => os.version_range.semver.min = semver,
317 },317 },
318 .windows => |win_ver| os.version_range.windows.min = win_ver,318 .windows => |win_ver| os.version_range.windows.min = win_ver,
...@@ -320,15 +320,18 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {...@@ -320,15 +320,18 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
320320
321 if (query.os_version_max) |max| switch (max) {321 if (query.os_version_max) |max| switch (max) {
322 .none => {},322 .none => {},
323 .semver => |semver| switch (os.tag) {323 .semver => |semver| switch (os.tag.versionRangeTag()) {
324 .linux => os.version_range.linux.range.max = semver,324 inline .hurd, .linux => |t| @field(os.version_range, @tagName(t)).range.max = semver,
325 else => os.version_range.semver.max = semver,325 else => os.version_range.semver.max = semver,
326 },326 },
327 .windows => |win_ver| os.version_range.windows.max = win_ver,327 .windows => |win_ver| os.version_range.windows.max = win_ver,
328 };328 };
329329
330 if (query.glibc_version) |glibc| {330 if (query.glibc_version) |glibc| {
331 os.version_range.linux.glibc = glibc;331 switch (os.tag.versionRangeTag()) {
332 inline .hurd, .linux => |t| @field(os.version_range, @tagName(t)).glibc = glibc,
333 else => {},
334 }
332 }335 }
333336
334 if (query.android_api_level) |android| {337 if (query.android_api_level) |android| {
lib/std/zig/target.zig+2-2
...@@ -88,10 +88,10 @@ pub fn canBuildLibC(target: std.Target) bool {...@@ -88,10 +88,10 @@ pub fn canBuildLibC(target: std.Target) bool {
88 const ver = target.os.version_range.semver;88 const ver = target.os.version_range.semver;
89 return ver.min.order(libc.os_ver.?) != .lt;89 return ver.min.order(libc.os_ver.?) != .lt;
90 }90 }
91 // Ensure glibc (aka *-linux-gnu) version is supported91 // Ensure glibc (aka *-(linux,hurd)-gnu) version is supported
92 if (target.isGnuLibC()) {92 if (target.isGnuLibC()) {
93 const min_glibc_ver = libc.glibc_min orelse return true;93 const min_glibc_ver = libc.glibc_min orelse return true;
94 const target_glibc_ver = target.os.version_range.linux.glibc;94 const target_glibc_ver = target.os.versionRange().gnuLibCVersion().?;
95 return target_glibc_ver.order(min_glibc_ver) != .lt;95 return target_glibc_ver.order(min_glibc_ver) != .lt;
96 }96 }
97 return true;97 return true;
src/Builtin.zig+34
...@@ -142,6 +142,40 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {...@@ -142,6 +142,40 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
142142
143 linux.android,143 linux.android,
144 }),144 }),
145 .hurd => |hurd| try buffer.writer().print(
146 \\ .hurd = .{{
147 \\ .range = .{{
148 \\ .min = .{{
149 \\ .major = {},
150 \\ .minor = {},
151 \\ .patch = {},
152 \\ }},
153 \\ .max = .{{
154 \\ .major = {},
155 \\ .minor = {},
156 \\ .patch = {},
157 \\ }},
158 \\ }},
159 \\ .glibc = .{{
160 \\ .major = {},
161 \\ .minor = {},
162 \\ .patch = {},
163 \\ }},
164 \\ }}}},
165 \\
166 , .{
167 hurd.range.min.major,
168 hurd.range.min.minor,
169 hurd.range.min.patch,
170
171 hurd.range.max.major,
172 hurd.range.max.minor,
173 hurd.range.max.patch,
174
175 hurd.glibc.major,
176 hurd.glibc.minor,
177 hurd.glibc.patch,
178 }),
145 .windows => |windows| try buffer.writer().print(179 .windows => |windows| try buffer.writer().print(
146 \\ .windows = .{{180 \\ .windows = .{{
147 \\ .min = {c},181 \\ .min = {c},
src/Compilation.zig+1-1
...@@ -5315,7 +5315,7 @@ pub fn addCCArgs(...@@ -5315,7 +5315,7 @@ pub fn addCCArgs(
53155315
5316 if (comp.config.link_libc) {5316 if (comp.config.link_libc) {
5317 if (target.isGnuLibC()) {5317 if (target.isGnuLibC()) {
5318 const target_version = target.os.version_range.linux.glibc;5318 const target_version = target.os.versionRange().gnuLibCVersion().?;
5319 const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{5319 const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{
5320 target_version.minor,5320 target_version.minor,
5321 });5321 });
src/codegen/llvm.zig+10-6
...@@ -245,7 +245,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {...@@ -245,7 +245,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
245 ver.min.minor,245 ver.min.minor,
246 ver.min.patch,246 ver.min.patch,
247 }),247 }),
248 .linux => |ver| try llvm_triple.writer().print("{d}.{d}.{d}", .{248 inline .linux, .hurd => |ver| try llvm_triple.writer().print("{d}.{d}.{d}", .{
249 ver.range.min.major,249 ver.range.min.major,
250 ver.range.min.minor,250 ver.range.min.minor,
251 ver.range.min.patch,251 ver.range.min.patch,
...@@ -290,11 +290,15 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {...@@ -290,11 +290,15 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
290 .semver,290 .semver,
291 .windows,291 .windows,
292 => {},292 => {},
293 .linux => |ver| if (target.abi.isGnu()) try llvm_triple.writer().print("{d}.{d}.{d}", .{293 inline .hurd, .linux => |ver| if (target.abi.isGnu()) {
294 ver.glibc.major,294 try llvm_triple.writer().print("{d}.{d}.{d}", .{
295 ver.glibc.minor,295 ver.glibc.major,
296 ver.glibc.patch,296 ver.glibc.minor,
297 }) else if (target.abi.isAndroid()) try llvm_triple.writer().print("{d}", .{ver.android}),297 ver.glibc.patch,
298 });
299 } else if (@TypeOf(ver) == std.Target.Os.LinuxVersionRange and target.abi.isAndroid()) {
300 try llvm_triple.writer().print("{d}", .{ver.android});
301 },
298 }302 }
299303
300 return llvm_triple.toOwnedSlice();304 return llvm_triple.toOwnedSlice();
src/glibc.zig+3-3
...@@ -188,7 +188,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre...@@ -188,7 +188,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre
188 const arena = arena_allocator.allocator();188 const arena = arena_allocator.allocator();
189189
190 const target = comp.root_mod.resolved_target.result;190 const target = comp.root_mod.resolved_target.result;
191 const target_ver = target.os.version_range.linux.glibc;191 const target_ver = target.os.versionRange().gnuLibCVersion().?;
192 const nonshared_stat = target_ver.order(.{ .major = 2, .minor = 32, .patch = 0 }) != .gt;192 const nonshared_stat = target_ver.order(.{ .major = 2, .minor = 32, .patch = 0 }) != .gt;
193 const start_old_init_fini = target_ver.order(.{ .major = 2, .minor = 33, .patch = 0 }) != .gt;193 const start_old_init_fini = target_ver.order(.{ .major = 2, .minor = 33, .patch = 0 }) != .gt;
194194
...@@ -750,7 +750,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi...@@ -750,7 +750,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
750 const arena = arena_allocator.allocator();750 const arena = arena_allocator.allocator();
751751
752 const target = comp.getTarget();752 const target = comp.getTarget();
753 const target_version = target.os.version_range.linux.glibc;753 const target_version = target.os.versionRange().gnuLibCVersion().?;
754754
755 // Use the global cache directory.755 // Use the global cache directory.
756 var cache: Cache = .{756 var cache: Cache = .{
...@@ -1218,7 +1218,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi...@@ -1218,7 +1218,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) !voi
1218}1218}
12191219
1220fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {1220fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void {
1221 const target_version = comp.getTarget().os.version_range.linux.glibc;1221 const target_version = comp.getTarget().os.versionRange().gnuLibCVersion().?;
12221222
1223 assert(comp.glibc_so_files == null);1223 assert(comp.glibc_so_files == null);
1224 comp.glibc_so_files = so_files;1224 comp.glibc_so_files = so_files;
src/libcxx.zig+3-3
...@@ -262,7 +262,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!...@@ -262,7 +262,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: std.Progress.Node) BuildError!
262262
263 if (target.isGnuLibC()) {263 if (target.isGnuLibC()) {
264 // glibc 2.16 introduced aligned_alloc264 // glibc 2.16 introduced aligned_alloc
265 if (target.os.version_range.linux.glibc.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {265 if (target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {
266 try cflags.append("-D_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION");266 try cflags.append("-D_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION");
267 }267 }
268 }268 }
...@@ -477,7 +477,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -477,7 +477,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
477 }477 }
478 try cflags.append("-D_LIBCXXABI_HAS_NO_THREADS");478 try cflags.append("-D_LIBCXXABI_HAS_NO_THREADS");
479 } else if (target.abi.isGnu()) {479 } else if (target.abi.isGnu()) {
480 if (target.os.tag != .linux or !(target.os.version_range.linux.glibc.order(.{ .major = 2, .minor = 18, .patch = 0 }) == .lt))480 if (target.os.tag != .linux or !(target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 18, .patch = 0 }) == .lt))
481 try cflags.append("-DHAVE___CXA_THREAD_ATEXIT_IMPL");481 try cflags.append("-DHAVE___CXA_THREAD_ATEXIT_IMPL");
482 }482 }
483483
...@@ -500,7 +500,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr...@@ -500,7 +500,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: std.Progress.Node) BuildErr
500500
501 if (target.isGnuLibC()) {501 if (target.isGnuLibC()) {
502 // glibc 2.16 introduced aligned_alloc502 // glibc 2.16 introduced aligned_alloc
503 if (target.os.version_range.linux.glibc.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {503 if (target.os.versionRange().gnuLibCVersion().?.order(.{ .major = 2, .minor = 16, .patch = 0 }) == .lt) {
504 try cflags.append("-D_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION");504 try cflags.append("-D_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION");
505 }505 }
506 }506 }
src/link/Elf.zig+1-1
...@@ -2013,7 +2013,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s...@@ -2013,7 +2013,7 @@ fn linkWithLLD(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: s
2013 } else if (target.isGnuLibC()) {2013 } else if (target.isGnuLibC()) {
2014 for (glibc.libs) |lib| {2014 for (glibc.libs) |lib| {
2015 if (lib.removed_in) |rem_in| {2015 if (lib.removed_in) |rem_in| {
2016 if (target.os.version_range.linux.glibc.order(rem_in) != .lt) continue;2016 if (target.os.versionRange().gnuLibCVersion().?.order(rem_in) != .lt) continue;
2017 }2017 }
20182018
2019 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{2019 const lib_path = try std.fmt.allocPrint(arena, "{}{c}lib{s}.so.{d}", .{
test/cases/inherit_want_safety.zig+1
...@@ -35,3 +35,4 @@ pub export fn entry() usize {...@@ -35,3 +35,4 @@ pub export fn entry() usize {
3535
36// compile36// compile
37// output_mode=Obj37// output_mode=Obj
38// emit_bin=false
test/cases/no_compile_panic_for_unchecked_arith.zig+1-1
...@@ -13,4 +13,4 @@ export fn entry() usize {...@@ -13,4 +13,4 @@ export fn entry() usize {
1313
14// compile14// compile
15// output_mode=Obj15// output_mode=Obj
16// backend=stage2,llvm16// emit_bin=false
test/cases/pic_freestanding.zig created+14
...@@ -0,0 +1,14 @@
1const builtin = @import("builtin");
2const std = @import("std");
3
4fn _start() callconv(.naked) void {}
5
6comptime {
7 @export(&_start, .{ .name = if (builtin.cpu.arch.isMIPS()) "__start" else "_start" });
8}
9
10// compile
11// backend=stage2,llvm
12// target=arm-freestanding,armeb-freestanding,thumb-freestanding,thumbeb-freestanding,aarch64-freestanding,aarch64_be-freestanding,loongarch64-freestanding,mips-freestanding,mipsel-freestanding,mips64-freestanding,mips64el-freestanding,powerpc-freestanding,powerpcle-freestanding,powerpc64-freestanding,powerpc64le-freestanding,riscv32-freestanding,riscv64-freestanding,s390x-freestanding,x86-freestanding,x86_64-freestanding
13// pic=true
14// output_mode=Exe
test/cases/pic_linux.zig created+14
...@@ -0,0 +1,14 @@
1const std = @import("std");
2
3// Eventually, this test should be made to work without libc by providing our
4// own `__tls_get_addr` implementation. powerpcle-linux should be added to the
5// target list here when that happens.
6//
7// https://github.com/ziglang/zig/issues/20625
8pub fn main() void {}
9
10// run
11// backend=stage2,llvm
12// target=arm-linux,armeb-linux,thumb-linux,thumbeb-linux,aarch64-linux,aarch64_be-linux,loongarch64-linux,mips-linux,mipsel-linux,mips64-linux,mips64el-linux,powerpc-linux,powerpc64-linux,powerpc64le-linux,riscv32-linux,riscv64-linux,s390x-linux,x86-linux,x86_64-linux
13// pic=true
14// link_libc=true
test/cases/pie_freestanding.zig created+16
...@@ -0,0 +1,16 @@
1const builtin = @import("builtin");
2const std = @import("std");
3
4// The self-hosted backends currently output a bunch of bad relocations for PIE,
5// so this test is LLVM only for now.
6fn _start() callconv(.naked) void {}
7
8comptime {
9 @export(&_start, .{ .name = if (builtin.cpu.arch.isMIPS()) "__start" else "_start" });
10}
11
12// compile
13// backend=llvm
14// target=arm-freestanding,armeb-freestanding,thumb-freestanding,thumbeb-freestanding,aarch64-freestanding,aarch64_be-freestanding,loongarch64-freestanding,mips-freestanding,mipsel-freestanding,mips64-freestanding,mips64el-freestanding,powerpc-freestanding,powerpcle-freestanding,powerpc64-freestanding,powerpc64le-freestanding,riscv32-freestanding,riscv64-freestanding,s390x-freestanding,x86-freestanding,x86_64-freestanding
15// pie=true
16// output_mode=Exe
test/cases/pie_linux.zig created+10
...@@ -0,0 +1,10 @@
1const std = @import("std");
2
3// The self-hosted backends can't handle `.hidden _DYNAMIC` and `.weak _DYNAMIC`
4// directives in inline assembly yet, so this test is LLVM only for now.
5pub fn main() void {}
6
7// run
8// backend=llvm
9// target=arm-linux,armeb-linux,thumb-linux,thumbeb-linux,aarch64-linux,aarch64_be-linux,loongarch64-linux,mips-linux,mipsel-linux,mips64-linux,mips64el-linux,powerpc-linux,powerpcle-linux,powerpc64-linux,powerpc64le-linux,riscv32-linux,riscv64-linux,s390x-linux,x86-linux,x86_64-linux
10// pie=true
test/cases/spirv_mergable_pointers.zig+1
...@@ -14,3 +14,4 @@ export fn a() void {...@@ -14,3 +14,4 @@ export fn a() void {
14// output_mode=Obj14// output_mode=Obj
15// backend=stage215// backend=stage2
16// target=spirv64-vulkan16// target=spirv64-vulkan
17// emit_bin=false
test/link/glibc_compat/build.zig+1-4
...@@ -5,10 +5,7 @@ const builtin = @import("builtin");...@@ -5,10 +5,7 @@ const builtin = @import("builtin");
5// run-time glibc version needs to be new enough. Check the host's glibc5// run-time glibc version needs to be new enough. Check the host's glibc
6// version. Note that this does not allow for translation/vm/emulation6// version. Note that this does not allow for translation/vm/emulation
7// services to run these tests.7// services to run these tests.
8const running_glibc_ver: ?std.SemanticVersion = switch (builtin.os.tag) {8const running_glibc_ver = builtin.os.versionRange().gnuLibCVersion();
9 .linux => builtin.os.version_range.linux.glibc,
10 else => null,
11};
129
13pub fn build(b: *std.Build) void {10pub fn build(b: *std.Build) void {
14 const test_step = b.step("test", "Test");11 const test_step = b.step("test", "Test");
test/link/glibc_compat/glibc_runtime_check.zig+1-1
...@@ -21,7 +21,7 @@ const c_string = @cImport(...@@ -21,7 +21,7 @@ const c_string = @cImport(
21);21);
2222
23// Version of glibc this test is being built to run against23// Version of glibc this test is being built to run against
24const glibc_ver = builtin.target.os.version_range.linux.glibc;24const glibc_ver = builtin.os.versionRange().gnuLibCVersion().?;
2525
26// PR #17034 - fstat moved between libc_nonshared and libc26// PR #17034 - fstat moved between libc_nonshared and libc
27fn checkStat() !void {27fn checkStat() !void {
test/nvptx.zig+1
...@@ -95,6 +95,7 @@ fn addPtx(ctx: *Cases, target: std.Build.ResolvedTarget, name: []const u8) *Case...@@ -95,6 +95,7 @@ fn addPtx(ctx: *Cases, target: std.Build.ResolvedTarget, name: []const u8) *Case
95 .output_mode = .Obj,95 .output_mode = .Obj,
96 .deps = std.ArrayList(Cases.DepModule).init(ctx.cases.allocator),96 .deps = std.ArrayList(Cases.DepModule).init(ctx.cases.allocator),
97 .link_libc = false,97 .link_libc = false,
98 .emit_bin = false,
98 .backend = .llvm,99 .backend = .llvm,
99 // Bug in Debug mode100 // Bug in Debug mode
100 .optimize_mode = .ReleaseSafe,101 .optimize_mode = .ReleaseSafe,
test/src/Cases.zig+41-3
...@@ -88,6 +88,8 @@ pub const Case = struct {...@@ -88,6 +88,8 @@ pub const Case = struct {
88 expect_exact: bool = false,88 expect_exact: bool = false,
89 backend: Backend = .stage2,89 backend: Backend = .stage2,
90 link_libc: bool = false,90 link_libc: bool = false,
91 pic: ?bool = null,
92 pie: ?bool = null,
9193
92 deps: std.ArrayList(DepModule),94 deps: std.ArrayList(DepModule),
9395
...@@ -425,6 +427,9 @@ fn addFromDirInner(...@@ -425,6 +427,9 @@ fn addFromDirInner(
425 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);427 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
426 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);428 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);
427 const output_mode = try manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode);429 const output_mode = try manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode);
430 const pic = try manifest.getConfigForKeyAssertSingle("pic", ?bool);
431 const pie = try manifest.getConfigForKeyAssertSingle("pie", ?bool);
432 const emit_bin = try manifest.getConfigForKeyAssertSingle("emit_bin", bool);
428433
429 if (manifest.type == .translate_c) {434 if (manifest.type == .translate_c) {
430 for (c_frontends) |c_frontend| {435 for (c_frontends) |c_frontend| {
...@@ -485,9 +490,12 @@ fn addFromDirInner(...@@ -485,9 +490,12 @@ fn addFromDirInner(
485 .target = resolved_target,490 .target = resolved_target,
486 .backend = backend,491 .backend = backend,
487 .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator),492 .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator),
493 .emit_bin = emit_bin,
488 .is_test = is_test,494 .is_test = is_test,
489 .output_mode = output_mode,495 .output_mode = output_mode,
490 .link_libc = link_libc,496 .link_libc = link_libc,
497 .pic = pic,
498 .pie = pie,
491 .deps = std.ArrayList(DepModule).init(ctx.cases.allocator),499 .deps = std.ArrayList(DepModule).init(ctx.cases.allocator),
492 });500 });
493 try cases.append(next);501 try cases.append(next);
...@@ -539,13 +547,14 @@ pub fn lowerToTranslateCSteps(...@@ -539,13 +547,14 @@ pub fn lowerToTranslateCSteps(
539 b: *std.Build,547 b: *std.Build,
540 parent_step: *std.Build.Step,548 parent_step: *std.Build.Step,
541 test_filters: []const []const u8,549 test_filters: []const []const u8,
550 test_target_filters: []const []const u8,
542 target: std.Build.ResolvedTarget,551 target: std.Build.ResolvedTarget,
543 translate_c_options: TranslateCOptions,552 translate_c_options: TranslateCOptions,
544) void {553) void {
545 const tests = @import("../tests.zig");554 const tests = @import("../tests.zig");
546 const test_translate_c_step = b.step("test-translate-c", "Run the C translation tests");555 const test_translate_c_step = b.step("test-translate-c", "Run the C translation tests");
547 if (!translate_c_options.skip_translate_c) {556 if (!translate_c_options.skip_translate_c) {
548 tests.addTranslateCTests(b, test_translate_c_step, test_filters);557 tests.addTranslateCTests(b, test_translate_c_step, test_filters, test_target_filters);
549 parent_step.dependOn(test_translate_c_step);558 parent_step.dependOn(test_translate_c_step);
550 }559 }
551560
...@@ -620,6 +629,7 @@ pub fn lowerToBuildSteps(...@@ -620,6 +629,7 @@ pub fn lowerToBuildSteps(
620 b: *std.Build,629 b: *std.Build,
621 parent_step: *std.Build.Step,630 parent_step: *std.Build.Step,
622 test_filters: []const []const u8,631 test_filters: []const []const u8,
632 test_target_filters: []const []const u8,
623) void {633) void {
624 const host = std.zig.system.resolveTargetQuery(.{}) catch |err|634 const host = std.zig.system.resolveTargetQuery(.{}) catch |err|
625 std.debug.panic("unable to detect native host: {s}\n", .{@errorName(err)});635 std.debug.panic("unable to detect native host: {s}\n", .{@errorName(err)});
...@@ -648,6 +658,14 @@ pub fn lowerToBuildSteps(...@@ -648,6 +658,14 @@ pub fn lowerToBuildSteps(
648 if (std.mem.indexOf(u8, case.name, test_filter)) |_| break;658 if (std.mem.indexOf(u8, case.name, test_filter)) |_| break;
649 } else if (test_filters.len > 0) continue;659 } else if (test_filters.len > 0) continue;
650660
661 const triple_txt = case.target.result.zigTriple(b.allocator) catch @panic("OOM");
662
663 if (test_target_filters.len > 0) {
664 for (test_target_filters) |filter| {
665 if (std.mem.indexOf(u8, triple_txt, filter) != null) break;
666 } else continue;
667 }
668
651 const writefiles = b.addWriteFiles();669 const writefiles = b.addWriteFiles();
652 var file_sources = std.StringHashMap(std.Build.LazyPath).init(b.allocator);670 var file_sources = std.StringHashMap(std.Build.LazyPath).init(b.allocator);
653 defer file_sources.deinit();671 defer file_sources.deinit();
...@@ -685,6 +703,8 @@ pub fn lowerToBuildSteps(...@@ -685,6 +703,8 @@ pub fn lowerToBuildSteps(
685 };703 };
686704
687 if (case.link_libc) artifact.linkLibC();705 if (case.link_libc) artifact.linkLibC();
706 if (case.pic) |pic| artifact.root_module.pic = pic;
707 if (case.pie) |pie| artifact.pie = pie;
688708
689 switch (case.backend) {709 switch (case.backend) {
690 .stage1 => continue,710 .stage1 => continue,
...@@ -705,6 +725,10 @@ pub fn lowerToBuildSteps(...@@ -705,6 +725,10 @@ pub fn lowerToBuildSteps(
705725
706 switch (update.case) {726 switch (update.case) {
707 .Compile => {727 .Compile => {
728 // Force the binary to be emitted if requested.
729 if (case.emit_bin) {
730 _ = artifact.getEmittedBin();
731 }
708 parent_step.dependOn(&artifact.step);732 parent_step.dependOn(&artifact.step);
709 },733 },
710 .CompareObjectFile => |expected_output| {734 .CompareObjectFile => |expected_output| {
...@@ -740,7 +764,7 @@ pub fn lowerToBuildSteps(...@@ -740,7 +764,7 @@ pub fn lowerToBuildSteps(
740 "--",764 "--",
741 "-lc",765 "-lc",
742 "-target",766 "-target",
743 case.target.result.zigTriple(b.allocator) catch @panic("OOM"),767 triple_txt,
744 });768 });
745 run_c.addArtifactArg(artifact);769 run_c.addArtifactArg(artifact);
746 break :run_step run_c;770 break :run_step run_c;
...@@ -942,12 +966,18 @@ const TestManifestConfigDefaults = struct {...@@ -942,12 +966,18 @@ const TestManifestConfigDefaults = struct {
942 .run_translated_c => "Obj",966 .run_translated_c => "Obj",
943 .cli => @panic("TODO test harness for CLI tests"),967 .cli => @panic("TODO test harness for CLI tests"),
944 };968 };
969 } else if (std.mem.eql(u8, key, "emit_bin")) {
970 return "true";
945 } else if (std.mem.eql(u8, key, "is_test")) {971 } else if (std.mem.eql(u8, key, "is_test")) {
946 return "false";972 return "false";
947 } else if (std.mem.eql(u8, key, "link_libc")) {973 } else if (std.mem.eql(u8, key, "link_libc")) {
948 return "false";974 return "false";
949 } else if (std.mem.eql(u8, key, "c_frontend")) {975 } else if (std.mem.eql(u8, key, "c_frontend")) {
950 return "clang";976 return "clang";
977 } else if (std.mem.eql(u8, key, "pic")) {
978 return "null";
979 } else if (std.mem.eql(u8, key, "pie")) {
980 return "null";
951 } else unreachable;981 } else unreachable;
952 }982 }
953};983};
...@@ -975,12 +1005,15 @@ const TestManifest = struct {...@@ -975,12 +1005,15 @@ const TestManifest = struct {
975 trailing_bytes: []const u8 = "",1005 trailing_bytes: []const u8 = "",
9761006
977 const valid_keys = std.StaticStringMap(void).initComptime(.{1007 const valid_keys = std.StaticStringMap(void).initComptime(.{
1008 .{ "emit_bin", {} },
978 .{ "is_test", {} },1009 .{ "is_test", {} },
979 .{ "output_mode", {} },1010 .{ "output_mode", {} },
980 .{ "target", {} },1011 .{ "target", {} },
981 .{ "c_frontend", {} },1012 .{ "c_frontend", {} },
982 .{ "link_libc", {} },1013 .{ "link_libc", {} },
983 .{ "backend", {} },1014 .{ "backend", {} },
1015 .{ "pic", {} },
1016 .{ "pie", {} },
984 });1017 });
9851018
986 const Type = enum {1019 const Type = enum {
...@@ -1209,7 +1242,12 @@ const TestManifest = struct {...@@ -1209,7 +1242,12 @@ const TestManifest = struct {
1209 };1242 };
1210 }1243 }
1211 }.parse,1244 }.parse,
1212 .@"struct" => @compileError("no default parser for " ++ @typeName(T)),1245 .optional => |o| return struct {
1246 fn parse(str: []const u8) anyerror!T {
1247 if (std.mem.eql(u8, str, "null")) return null;
1248 return try getDefaultParser(o.child)(str);
1249 }
1250 }.parse,
1213 else => @compileError("no default parser for " ++ @typeName(T)),1251 else => @compileError("no default parser for " ++ @typeName(T)),
1214 }1252 }
1215 }1253 }
test/src/Debugger.zig+7
...@@ -4,6 +4,7 @@ root_step: *std.Build.Step,...@@ -4,6 +4,7 @@ root_step: *std.Build.Step,
44
5pub const Options = struct {5pub const Options = struct {
6 test_filters: []const []const u8,6 test_filters: []const []const u8,
7 test_target_filters: []const []const u8,
7 gdb: ?[]const u8,8 gdb: ?[]const u8,
8 lldb: ?[]const u8,9 lldb: ?[]const u8,
9 optimize_modes: []const std.builtin.OptimizeMode,10 optimize_modes: []const std.builtin.OptimizeMode,
...@@ -2406,6 +2407,12 @@ fn addTest(...@@ -2406,6 +2407,12 @@ fn addTest(
2406 for (db.options.test_filters) |test_filter| {2407 for (db.options.test_filters) |test_filter| {
2407 if (std.mem.indexOf(u8, name, test_filter)) |_| return;2408 if (std.mem.indexOf(u8, name, test_filter)) |_| return;
2408 }2409 }
2410 if (db.options.test_target_filters.len > 0) {
2411 const triple_txt = target.resolved.result.zigTriple(db.b.allocator) catch @panic("OOM");
2412 for (db.options.test_target_filters) |filter| {
2413 if (std.mem.indexOf(u8, triple_txt, filter) != null) break;
2414 } else return;
2415 }
2409 const files_wf = db.b.addWriteFiles();2416 const files_wf = db.b.addWriteFiles();
2410 const exe = db.b.addExecutable(.{2417 const exe = db.b.addExecutable(.{
2411 .name = name,2418 .name = name,
test/src/TranslateC.zig+12-1
...@@ -2,6 +2,7 @@ b: *std.Build,...@@ -2,6 +2,7 @@ b: *std.Build,
2step: *std.Build.Step,2step: *std.Build.Step,
3test_index: usize,3test_index: usize,
4test_filters: []const []const u8,4test_filters: []const []const u8,
5test_target_filters: []const []const u8,
56
6const TestCase = struct {7const TestCase = struct {
7 name: []const u8,8 name: []const u8,
...@@ -92,6 +93,16 @@ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {...@@ -92,6 +93,16 @@ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
92 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;93 if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break;
93 } else if (self.test_filters.len > 0) return;94 } else if (self.test_filters.len > 0) return;
9495
96 const target = b.resolveTargetQuery(case.target);
97
98 if (self.test_target_filters.len > 0) {
99 const triple_txt = target.result.zigTriple(b.allocator) catch @panic("OOM");
100
101 for (self.test_target_filters) |filter| {
102 if (std.mem.indexOf(u8, triple_txt, filter) != null) break;
103 } else return;
104 }
105
95 const write_src = b.addWriteFiles();106 const write_src = b.addWriteFiles();
96 const first_src = case.sources.items[0];107 const first_src = case.sources.items[0];
97 const root_source_file = write_src.add(first_src.filename, first_src.source);108 const root_source_file = write_src.add(first_src.filename, first_src.source);
...@@ -101,7 +112,7 @@ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {...@@ -101,7 +112,7 @@ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
101112
102 const translate_c = b.addTranslateC(.{113 const translate_c = b.addTranslateC(.{
103 .root_source_file = root_source_file,114 .root_source_file = root_source_file,
104 .target = b.resolveTargetQuery(case.target),115 .target = target,
105 .optimize = .Debug,116 .optimize = .Debug,
106 });117 });
107118
test/tests.zig+27-10
...@@ -1237,18 +1237,22 @@ pub fn addAssembleAndLinkTests(b: *std.Build, test_filters: []const []const u8,...@@ -1237,18 +1237,22 @@ pub fn addAssembleAndLinkTests(b: *std.Build, test_filters: []const []const u8,
1237 return cases.step;1237 return cases.step;
1238}1238}
12391239
1240pub fn addTranslateCTests(b: *std.Build, parent_step: *std.Build.Step, test_filters: []const []const u8) void {1240pub fn addTranslateCTests(
1241 b: *std.Build,
1242 parent_step: *std.Build.Step,
1243 test_filters: []const []const u8,
1244 test_target_filters: []const []const u8,
1245) void {
1241 const cases = b.allocator.create(TranslateCContext) catch @panic("OOM");1246 const cases = b.allocator.create(TranslateCContext) catch @panic("OOM");
1242 cases.* = TranslateCContext{1247 cases.* = TranslateCContext{
1243 .b = b,1248 .b = b,
1244 .step = parent_step,1249 .step = parent_step,
1245 .test_index = 0,1250 .test_index = 0,
1246 .test_filters = test_filters,1251 .test_filters = test_filters,
1252 .test_target_filters = test_target_filters,
1247 };1253 };
12481254
1249 translate_c.addCases(cases);1255 translate_c.addCases(cases);
1250
1251 return;
1252}1256}
12531257
1254pub fn addRunTranslatedCTests(1258pub fn addRunTranslatedCTests(
...@@ -1267,8 +1271,6 @@ pub fn addRunTranslatedCTests(...@@ -1267,8 +1271,6 @@ pub fn addRunTranslatedCTests(
1267 };1271 };
12681272
1269 run_translated_c.addCases(cases);1273 run_translated_c.addCases(cases);
1270
1271 return;
1272}1274}
12731275
1274const ModuleTestOptions = struct {1276const ModuleTestOptions = struct {
...@@ -1486,19 +1488,32 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {...@@ -1486,19 +1488,32 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
1486 return step;1488 return step;
1487}1489}
14881490
1489pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *Step {1491const CAbiTestOptions = struct {
1492 test_target_filters: []const []const u8,
1493 skip_non_native: bool,
1494 skip_release: bool,
1495};
1496
1497pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step {
1490 const step = b.step("test-c-abi", "Run the C ABI tests");1498 const step = b.step("test-c-abi", "Run the C ABI tests");
14911499
1492 const optimize_modes: [3]OptimizeMode = .{ .Debug, .ReleaseSafe, .ReleaseFast };1500 const optimize_modes: [3]OptimizeMode = .{ .Debug, .ReleaseSafe, .ReleaseFast };
14931501
1494 for (optimize_modes) |optimize_mode| {1502 for (optimize_modes) |optimize_mode| {
1495 if (optimize_mode != .Debug and skip_release) continue;1503 if (optimize_mode != .Debug and options.skip_release) continue;
14961504
1497 for (c_abi_targets) |c_abi_target| {1505 for (c_abi_targets) |c_abi_target| {
1498 if (skip_non_native and !c_abi_target.target.isNative()) continue;1506 if (options.skip_non_native and !c_abi_target.target.isNative()) continue;
14991507
1500 const resolved_target = b.resolveTargetQuery(c_abi_target.target);1508 const resolved_target = b.resolveTargetQuery(c_abi_target.target);
1501 const target = resolved_target.result;1509 const target = resolved_target.result;
1510 const triple_txt = target.zigTriple(b.allocator) catch @panic("OOM");
1511
1512 if (options.test_target_filters.len > 0) {
1513 for (options.test_target_filters) |filter| {
1514 if (std.mem.indexOf(u8, triple_txt, filter) != null) break;
1515 } else continue;
1516 }
15021517
1503 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {1518 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
1504 // https://github.com/ziglang/zig/issues/149081519 // https://github.com/ziglang/zig/issues/14908
...@@ -1507,7 +1522,7 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S...@@ -1507,7 +1522,7 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S
15071522
1508 const test_step = b.addTest(.{1523 const test_step = b.addTest(.{
1509 .name = b.fmt("test-c-abi-{s}-{s}-{s}{s}{s}{s}", .{1524 .name = b.fmt("test-c-abi-{s}-{s}-{s}{s}{s}{s}", .{
1510 target.zigTriple(b.allocator) catch @panic("OOM"),1525 triple_txt,
1511 target.cpu.model.name,1526 target.cpu.model.name,
1512 @tagName(optimize_mode),1527 @tagName(optimize_mode),
1513 if (c_abi_target.use_llvm == true)1528 if (c_abi_target.use_llvm == true)
...@@ -1552,6 +1567,7 @@ pub fn addCases(...@@ -1552,6 +1567,7 @@ pub fn addCases(
1552 b: *std.Build,1567 b: *std.Build,
1553 parent_step: *Step,1568 parent_step: *Step,
1554 test_filters: []const []const u8,1569 test_filters: []const []const u8,
1570 test_target_filters: []const []const u8,
1555 target: std.Build.ResolvedTarget,1571 target: std.Build.ResolvedTarget,
1556 translate_c_options: @import("src/Cases.zig").TranslateCOptions,1572 translate_c_options: @import("src/Cases.zig").TranslateCOptions,
1557 build_options: @import("cases.zig").BuildOptions,1573 build_options: @import("cases.zig").BuildOptions,
...@@ -1567,12 +1583,13 @@ pub fn addCases(...@@ -1567,12 +1583,13 @@ pub fn addCases(
1567 cases.addFromDir(dir, b);1583 cases.addFromDir(dir, b);
1568 try @import("cases.zig").addCases(&cases, build_options, b);1584 try @import("cases.zig").addCases(&cases, build_options, b);
15691585
1570 cases.lowerToTranslateCSteps(b, parent_step, test_filters, target, translate_c_options);1586 cases.lowerToTranslateCSteps(b, parent_step, test_filters, test_target_filters, target, translate_c_options);
15711587
1572 cases.lowerToBuildSteps(1588 cases.lowerToBuildSteps(
1573 b,1589 b,
1574 parent_step,1590 parent_step,
1575 test_filters,1591 test_filters,
1592 test_target_filters,
1576 );1593 );
1577}1594}
15781595