authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-12-13 08:02:15+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-12-17 05:04:16+01:00
log0ef01c552100a8559bec5d17e6778f1cb652d403
treea4540fdee4b1fd8d046f85ead98cbb13273f362b
parent424f9ba53289ab720c76ae06685168b1bf3f5a59
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.Target: Incorporate the Abi tag in VersionRange.default().

This is necessary to pick out the correct minimum OS version from the std.zig.target.available_libcs list.

3 files changed, 68 insertions(+), 25 deletions(-)

lib/compiler/aro/aro/target.zig+4-4
......@@ -719,7 +719,7 @@ pub fn toLLVMTriple(target: std.Target, buf: []u8) []const u8 {
719719test "alignment functions - smoke test" {
720720 var target: std.Target = undefined;
721721 const x86 = std.Target.Cpu.Arch.x86_64;
722 target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
722 target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86, .none);
723723 target.cpu = std.Target.Cpu.baseline(x86, target.os);
724724 target.abi = std.Target.Abi.default(x86, target.os);
725725
......@@ -732,7 +732,7 @@ test "alignment functions - smoke test" {
732732 try std.testing.expect(systemCompiler(target) == .gcc);
733733
734734 const arm = std.Target.Cpu.Arch.arm;
735 target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
735 target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm, .none);
736736 target.cpu = std.Target.Cpu.baseline(arm, target.os);
737737 target.abi = std.Target.Abi.default(arm, target.os);
738738
......@@ -751,7 +751,7 @@ test "target size/align tests" {
751751 const x86 = std.Target.Cpu.Arch.x86;
752752 comp.target.cpu.arch = x86;
753753 comp.target.cpu.model = &std.Target.x86.cpu.i586;
754 comp.target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86);
754 comp.target.os = std.Target.Os.Tag.defaultVersionRange(.linux, x86, .none);
755755 comp.target.abi = std.Target.Abi.gnu;
756756
757757 const tt: Type = .{
......@@ -763,7 +763,7 @@ test "target size/align tests" {
763763
764764 const arm = std.Target.Cpu.Arch.arm;
765765 comp.target.cpu = std.Target.Cpu.Model.toCpu(&std.Target.arm.cpu.cortex_r4, arm);
766 comp.target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm);
766 comp.target.os = std.Target.Os.Tag.defaultVersionRange(.ios, arm, .none);
767767 comp.target.abi = std.Target.Abi.none;
768768
769769 const ct: Type = .{
lib/std/Target.zig+17-7
......@@ -148,10 +148,10 @@ pub const Os = struct {
148148 return (tag == .hurd or tag == .linux) and abi.isGnu();
149149 }
150150
151 pub fn defaultVersionRange(tag: Tag, arch: Cpu.Arch) Os {
151 pub fn defaultVersionRange(tag: Tag, arch: Cpu.Arch, abi: Abi) Os {
152152 return .{
153153 .tag = tag,
154 .version_range = VersionRange.default(tag, arch),
154 .version_range = .default(arch, tag, abi),
155155 };
156156 }
157157
......@@ -416,7 +416,7 @@ pub const Os = struct {
416416
417417 /// The default `VersionRange` represents the range that the Zig Standard Library
418418 /// bases its abstractions on.
419 pub fn default(tag: Tag, arch: Cpu.Arch) VersionRange {
419 pub fn default(arch: Cpu.Arch, tag: Tag, abi: Abi) VersionRange {
420420 return switch (tag) {
421421 .freestanding,
422422 .other,
......@@ -475,16 +475,26 @@ pub const Os = struct {
475475 .linux => .{
476476 .linux = .{
477477 .range = .{
478 .min = .{ .major = 4, .minor = 19, .patch = 0 },
478 .min = blk: {
479 const default_min: std.SemanticVersion = .{ .major = 4, .minor = 19, .patch = 0 };
480
481 for (std.zig.target.available_libcs) |libc| {
482 if (libc.arch != arch or libc.os != tag or libc.abi != abi) continue;
483
484 if (libc.os_ver) |min| {
485 if (min.order(default_min) == .gt) break :blk min;
486 }
487 }
488
489 break :blk default_min;
490 },
479491 .max = .{ .major = 6, .minor = 11, .patch = 5 },
480492 },
481493 .glibc = blk: {
482494 const default_min: std.SemanticVersion = .{ .major = 2, .minor = 28, .patch = 0 };
483495
484496 for (std.zig.target.available_libcs) |libc| {
485 // We don't know the ABI here. We can get away with not checking it
486 // for now, but that may not always remain true.
487 if (libc.os != tag or libc.arch != arch) continue;
497 if (libc.os != tag or libc.arch != arch or libc.abi != abi) continue;
488498
489499 if (libc.glibc_min) |min| {
490500 if (min.order(default_min) == .gt) break :blk min;
lib/std/zig/system.zig+47-14
......@@ -181,8 +181,12 @@ pub const DetectError = error{
181181/// components by detecting the native system, and then resolves
182182/// standard/default parts relative to that.
183183pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
184 // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the
185 // native CPU architecture as being different than the current target), we use this:
186 const query_cpu_arch = query.cpu_arch orelse builtin.cpu.arch;
184187 const query_os_tag = query.os_tag orelse builtin.os.tag;
185 var os = query_os_tag.defaultVersionRange(query.cpu_arch orelse builtin.cpu.arch);
188 const query_abi = query.abi orelse builtin.abi;
189 var os = query_os_tag.defaultVersionRange(query_cpu_arch, query_abi);
186190 if (query.os_tag == null) {
187191 switch (builtin.target.os.tag) {
188192 .linux => {
......@@ -338,29 +342,58 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
338342 os.version_range.linux.android = android;
339343 }
340344
341 // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the
342 // native CPU architecture as being different than the current target), we use this:
343 const cpu_arch = query.cpu_arch orelse builtin.cpu.arch;
344
345345 const cpu = switch (query.cpu_model) {
346 .native => detectNativeCpuAndFeatures(cpu_arch, os, query),
347 .baseline => Target.Cpu.baseline(cpu_arch, os),
346 .native => detectNativeCpuAndFeatures(query_cpu_arch, os, query),
347 .baseline => Target.Cpu.baseline(query_cpu_arch, os),
348348 .determined_by_arch_os => if (query.cpu_arch == null)
349 detectNativeCpuAndFeatures(cpu_arch, os, query)
349 detectNativeCpuAndFeatures(query_cpu_arch, os, query)
350350 else
351 Target.Cpu.baseline(cpu_arch, os),
352 .explicit => |model| model.toCpu(cpu_arch),
351 Target.Cpu.baseline(query_cpu_arch, os),
352 .explicit => |model| model.toCpu(query_cpu_arch),
353353 } orelse backup_cpu_detection: {
354 break :backup_cpu_detection Target.Cpu.baseline(cpu_arch, os);
354 break :backup_cpu_detection Target.Cpu.baseline(query_cpu_arch, os);
355355 };
356
356357 var result = try detectAbiAndDynamicLinker(cpu, os, query);
358
359 // It's possible that we detect the native ABI, but fail to detect the OS version or were told
360 // to use the default OS version range. In that case, while we can't determine the exact native
361 // OS version, we do at least know that some ABIs require a particular OS version (by way of
362 // `std.zig.target.available_libcs`). So in this case, adjust the OS version to the minimum that
363 // we know is required.
364 if (result.abi != query_abi and query.os_version_min == null) {
365 const result_ver_range = &result.os.version_range;
366 const abi_ver_range = result.os.tag.defaultVersionRange(result.cpu.arch, result.abi).version_range;
367
368 switch (result.os.tag.versionRangeTag()) {
369 .none => {},
370 .semver => if (result_ver_range.semver.min.order(abi_ver_range.semver.min) == .lt) {
371 result_ver_range.semver.min = abi_ver_range.semver.min;
372 },
373 inline .hurd, .linux => |t| {
374 if (@field(result_ver_range, @tagName(t)).range.min.order(@field(abi_ver_range, @tagName(t)).range.min) == .lt) {
375 @field(result_ver_range, @tagName(t)).range.min = @field(abi_ver_range, @tagName(t)).range.min;
376 }
377
378 if (@field(result_ver_range, @tagName(t)).glibc.order(@field(abi_ver_range, @tagName(t)).glibc) == .lt and
379 query.glibc_version == null)
380 {
381 @field(result_ver_range, @tagName(t)).glibc = @field(abi_ver_range, @tagName(t)).glibc;
382 }
383 },
384 .windows => if (!result_ver_range.windows.min.isAtLeast(abi_ver_range.windows.min)) {
385 result_ver_range.windows.min = abi_ver_range.windows.min;
386 },
387 }
388 }
389
357390 // For x86, we need to populate some CPU feature flags depending on architecture
358391 // and mode:
359392 // * 16bit_mode => if the abi is code16
360393 // * 32bit_mode => if the arch is x86
361394 // However, the "mode" flags can be used as overrides, so if the user explicitly
362395 // sets one of them, that takes precedence.
363 switch (cpu_arch) {
396 switch (result.cpu.arch) {
364397 .x86 => {
365398 if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{
366399 .@"16bit_mode", .@"32bit_mode",
......@@ -388,12 +421,12 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
388421 }
389422 updateCpuFeatures(
390423 &result.cpu.features,
391 cpu_arch.allFeaturesList(),
424 result.cpu.arch.allFeaturesList(),
392425 query.cpu_features_add,
393426 query.cpu_features_sub,
394427 );
395428
396 if (cpu_arch == .hexagon) {
429 if (result.cpu.arch == .hexagon) {
397430 // Both LLVM and LLD have broken support for the small data area. Yet LLVM has the feature
398431 // on by default for all Hexagon CPUs. Clang sort of solves this by defaulting the `-gpsize`
399432 // command line parameter for the Hexagon backend to 0, so that no constants get placed in