authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-11-02 02:00:25+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-11-02 02:00:25+01:00
logab89af3d397291f0126ad17d3787a51284457884
tree4f418bfe9a67189e4b67c3365a1e746d5bf0bde5
parentaaf54ce6a7e5c69c92fe30e9ca0e8ffb7765f824
parent3c1ccbdf3990b6d802cdc8a0db7c11eaac0960e8
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21860 from alexrp/llvm-triple-stuff

More support for OS/libc version ranges in `std.Target` and improvements to LLVM target triple construction

7 files changed, 328 insertions(+), 139 deletions(-)

lib/std/Build/Cache.zig+1
......@@ -221,6 +221,7 @@ pub const HashHelper = struct {
221221 hh.add(linux.range.min);
222222 hh.add(linux.range.max);
223223 hh.add(linux.glibc);
224 hh.add(linux.android);
224225 },
225226 .windows => |windows| {
226227 hh.add(windows.min);
lib/std/Target.zig+205-112
......@@ -160,49 +160,62 @@ pub const Os = struct {
160160 pub inline fn versionRangeTag(tag: Tag) @typeInfo(TaggedVersionRange).@"union".tag_type.? {
161161 return switch (tag) {
162162 .freestanding,
163 .fuchsia,
164 .ps3,
165 .zos,
163 .other,
164
165 .elfiamcu,
166
166167 .haiku,
167 .rtems,
168 .aix,
169 .cuda,
170 .nvcl,
171 .amdhsa,
168 .plan9,
169 .serenity,
170
171 // This should use semver once we determine the version history.
172 .bridgeos,
173
174 .illumos,
175
176 .ps3,
172177 .ps4,
173178 .ps5,
174 .elfiamcu,
179
180 .emscripten,
181
175182 .mesa3d,
183 => .none,
184
176185 .contiki,
177 .amdpal,
186 .fuchsia,
178187 .hermit,
188
189 .aix,
179190 .hurd,
180 .emscripten,
181 .uefi,
182 .opencl, // TODO: OpenCL versions
183 .opengl, // TODO: GLSL versions
184 .vulkan,
185 .plan9,
186 .illumos,
187 .serenity,
188 .other,
189 => .none,
191 .rtems,
192 .zos,
190193
191 // This should use semver once we determine the version history.
192 .bridgeos => .none,
194 .dragonfly,
195 .freebsd,
196 .netbsd,
197 .openbsd,
193198
194199 .driverkit,
195 .freebsd,
196200 .macos,
197201 .ios,
198202 .tvos,
199 .watchos,
200203 .visionos,
201 .netbsd,
202 .openbsd,
203 .dragonfly,
204 .watchos,
205
204206 .solaris,
207
208 .uefi,
209
205210 .wasi,
211
212 .amdhsa,
213 .amdpal,
214 .cuda,
215 .nvcl,
216 .opencl,
217 .opengl,
218 .vulkan,
206219 => .semver,
207220
208221 .linux => .linux,
......@@ -257,10 +270,11 @@ pub const Os = struct {
257270 win11_zn = 0x0A00000E, //aka win11_21h2
258271 win11_ga = 0x0A00000F, //aka win11_22h2
259272 win11_ge = 0x0A000010, //aka win11_23h2
273 win11_dt = 0x0A000011, //aka win11_24h2
260274 _,
261275
262276 /// Latest Windows version that the Zig Standard Library is aware of
263 pub const latest = WindowsVersion.win11_ge;
277 pub const latest = WindowsVersion.win11_dt;
264278
265279 /// Compared against build numbers reported by the runtime to distinguish win10 versions,
266280 /// where 0x0A000000 + index corresponds to the WindowsVersion u32 value.
......@@ -282,6 +296,7 @@ pub const Os = struct {
282296 22000, //win11_zn aka win11_21h2
283297 22621, //win11_ga aka win11_22h2
284298 22631, //win11_ge aka win11_23h2
299 26100, //win11_dt aka win11_24h2
285300 };
286301
287302 /// Returns whether the first version `ver` is newer (greater) than or equal to the second version `ver`.
......@@ -344,6 +359,8 @@ pub const Os = struct {
344359 pub const LinuxVersionRange = struct {
345360 range: std.SemanticVersion.Range,
346361 glibc: std.SemanticVersion,
362 /// Android API level.
363 android: u32 = 14, // This default value is to be deleted after zig1.wasm is updated.
347364
348365 pub inline fn includesVersion(range: LinuxVersionRange, ver: std.SemanticVersion) bool {
349366 return range.range.includesVersion(ver);
......@@ -391,84 +408,106 @@ pub const Os = struct {
391408 pub fn default(tag: Tag, arch: Cpu.Arch) VersionRange {
392409 return switch (tag) {
393410 .freestanding,
394 .fuchsia,
395 .ps3,
396 .zos,
397 .haiku,
398 .rtems,
399 .aix,
400 .cuda,
401 .nvcl,
402 .amdhsa,
403 .ps4,
404 .ps5,
411 .other,
412
405413 .elfiamcu,
406 .mesa3d,
407 .contiki,
408 .amdpal,
409 .hermit,
410 .hurd,
411 .emscripten,
412 .uefi,
413 .opencl, // TODO: OpenCL versions
414 .opengl, // TODO: GLSL versions
415 .vulkan,
414
415 .haiku,
416416 .plan9,
417 .illumos,
418417 .serenity,
418
419 // This should use semver once we determine the version history.
419420 .bridgeos,
420 .other,
421
422 .illumos,
423
424 .ps3,
425 .ps4,
426 .ps5,
427
428 .emscripten,
429
430 .mesa3d,
421431 => .{ .none = {} },
422432
423 .freebsd => .{
424 .semver = std.SemanticVersion.Range{
425 .min = .{ .major = 12, .minor = 0, .patch = 0 },
426 .max = .{ .major = 14, .minor = 0, .patch = 0 },
433 .contiki => .{
434 .semver = .{
435 .min = .{ .major = 4, .minor = 0, .patch = 0 },
436 .max = .{ .major = 4, .minor = 9, .patch = 0 },
427437 },
428438 },
429 .driverkit => .{
439 .fuchsia => .{
430440 .semver = .{
431 .min = .{ .major = 19, .minor = 0, .patch = 0 },
432 .max = .{ .major = 24, .minor = 0, .patch = 0 },
441 .min = .{ .major = 1, .minor = 1, .patch = 0 },
442 .max = .{ .major = 20, .minor = 1, .patch = 0 },
433443 },
434444 },
435 .macos => switch (arch) {
436 .aarch64 => VersionRange{
437 .semver = .{
438 .min = .{ .major = 11, .minor = 7, .patch = 1 },
439 .max = .{ .major = 14, .minor = 6, .patch = 1 },
440 },
445 .hermit => .{
446 .semver = .{
447 .min = .{ .major = 0, .minor = 4, .patch = 0 },
448 .max = .{ .major = 0, .minor = 8, .patch = 0 },
449 },
450 },
451
452 .aix => .{
453 .semver = .{
454 .min = .{ .major = 7, .minor = 2, .patch = 5 },
455 .max = .{ .major = 7, .minor = 3, .patch = 2 },
441456 },
442 .x86_64 => VersionRange{
443 .semver = .{
444 .min = .{ .major = 11, .minor = 7, .patch = 1 },
445 .max = .{ .major = 14, .minor = 6, .patch = 1 },
457 },
458 .hurd => .{
459 .semver = .{
460 .min = .{ .major = 0, .minor = 9, .patch = 0 },
461 .max = .{ .major = 0, .minor = 9, .patch = 0 },
462 },
463 },
464 .linux => .{
465 .linux = .{
466 .range = .{
467 .min = .{ .major = 4, .minor = 19, .patch = 0 },
468 .max = .{ .major = 6, .minor = 11, .patch = 5 },
446469 },
470 .glibc = blk: {
471 const default_min: std.SemanticVersion = .{ .major = 2, .minor = 28, .patch = 0 };
472
473 for (std.zig.target.available_libcs) |libc| {
474 // We don't know the ABI here. We can get away with not checking it
475 // for now, but that may not always remain true.
476 if (libc.os != tag or libc.arch != arch) continue;
477
478 if (libc.glibc_min) |min| {
479 if (min.order(default_min) == .gt) break :blk min;
480 }
481 }
482
483 break :blk default_min;
484 },
485 .android = 14,
447486 },
448 else => unreachable,
449487 },
450 .ios => .{
488 .rtems => .{
451489 .semver = .{
452 .min = .{ .major = 12, .minor = 0, .patch = 0 },
453 .max = .{ .major = 17, .minor = 6, .patch = 1 },
490 .min = .{ .major = 5, .minor = 1, .patch = 0 },
491 .max = .{ .major = 5, .minor = 3, .patch = 0 },
454492 },
455493 },
456 .watchos => .{
494 .zos => .{
457495 .semver = .{
458 .min = .{ .major = 6, .minor = 0, .patch = 0 },
459 .max = .{ .major = 10, .minor = 6, .patch = 0 },
496 .min = .{ .major = 2, .minor = 5, .patch = 0 },
497 .max = .{ .major = 3, .minor = 1, .patch = 0 },
460498 },
461499 },
462 .tvos => .{
500
501 .dragonfly => .{
463502 .semver = .{
464 .min = .{ .major = 13, .minor = 0, .patch = 0 },
465 .max = .{ .major = 17, .minor = 6, .patch = 0 },
503 .min = .{ .major = 5, .minor = 8, .patch = 0 },
504 .max = .{ .major = 6, .minor = 4, .patch = 0 },
466505 },
467506 },
468 .visionos => .{
507 .freebsd => .{
469508 .semver = .{
470 .min = .{ .major = 1, .minor = 0, .patch = 0 },
471 .max = .{ .major = 1, .minor = 3, .patch = 0 },
509 .min = .{ .major = 12, .minor = 0, .patch = 0 },
510 .max = .{ .major = 14, .minor = 1, .patch = 0 },
472511 },
473512 },
474513 .netbsd => .{
......@@ -480,49 +519,51 @@ pub const Os = struct {
480519 .openbsd => .{
481520 .semver = .{
482521 .min = .{ .major = 7, .minor = 3, .patch = 0 },
483 .max = .{ .major = 7, .minor = 5, .patch = 0 },
522 .max = .{ .major = 7, .minor = 6, .patch = 0 },
484523 },
485524 },
486 .dragonfly => .{
525
526 .driverkit => .{
487527 .semver = .{
488 .min = .{ .major = 5, .minor = 8, .patch = 0 },
489 .max = .{ .major = 6, .minor = 4, .patch = 0 },
528 .min = .{ .major = 19, .minor = 0, .patch = 0 },
529 .max = .{ .major = 24, .minor = 2, .patch = 0 },
490530 },
491531 },
492 .solaris => .{
532 .macos => .{
493533 .semver = .{
494 .min = .{ .major = 11, .minor = 0, .patch = 0 },
495 .max = .{ .major = 11, .minor = 4, .patch = 0 },
534 .min = .{ .major = 11, .minor = 7, .patch = 1 },
535 .max = .{ .major = 15, .minor = 2, .patch = 0 },
496536 },
497537 },
498 .wasi => .{
538 .ios => .{
499539 .semver = .{
500 .min = .{ .major = 0, .minor = 1, .patch = 0 },
501 .max = .{ .major = 0, .minor = 1, .patch = 0 },
540 .min = .{ .major = 12, .minor = 0, .patch = 0 },
541 .max = .{ .major = 18, .minor = 1, .patch = 0 },
542 },
543 },
544 .tvos => .{
545 .semver = .{
546 .min = .{ .major = 13, .minor = 0, .patch = 0 },
547 .max = .{ .major = 18, .minor = 1, .patch = 0 },
548 },
549 },
550 .visionos => .{
551 .semver = .{
552 .min = .{ .major = 1, .minor = 0, .patch = 0 },
553 .max = .{ .major = 2, .minor = 1, .patch = 0 },
554 },
555 },
556 .watchos => .{
557 .semver = .{
558 .min = .{ .major = 6, .minor = 0, .patch = 0 },
559 .max = .{ .major = 11, .minor = 1, .patch = 0 },
502560 },
503561 },
504562
505 .linux => .{
506 .linux = .{
507 .range = .{
508 .min = .{ .major = 4, .minor = 19, .patch = 0 },
509 .max = .{ .major = 6, .minor = 10, .patch = 3 },
510 },
511 .glibc = blk: {
512 const default_min: std.SemanticVersion = .{ .major = 2, .minor = 28, .patch = 0 };
513
514 for (std.zig.target.available_libcs) |libc| {
515 // We don't know the ABI here. We can get away with not checking it
516 // for now, but that may not always remain true.
517 if (libc.os != tag or libc.arch != arch) continue;
518
519 if (libc.glibc_min) |min| {
520 if (min.order(default_min) == .gt) break :blk min;
521 }
522 }
523
524 break :blk default_min;
525 },
563 .solaris => .{
564 .semver = .{
565 .min = .{ .major = 11, .minor = 0, .patch = 0 },
566 .max = .{ .major = 11, .minor = 4, .patch = 0 },
526567 },
527568 },
528569
......@@ -532,6 +573,58 @@ pub const Os = struct {
532573 .max = WindowsVersion.latest,
533574 },
534575 },
576 .uefi => .{
577 .semver = .{
578 .min = .{ .major = 2, .minor = 0, .patch = 0 },
579 .max = .{ .major = 2, .minor = 9, .patch = 0 },
580 },
581 },
582
583 .wasi => .{
584 .semver = .{
585 .min = .{ .major = 0, .minor = 1, .patch = 0 },
586 .max = .{ .major = 0, .minor = 2, .patch = 2 },
587 },
588 },
589
590 .amdhsa => .{
591 .semver = .{
592 .min = .{ .major = 5, .minor = 0, .patch = 2 },
593 .max = .{ .major = 6, .minor = 2, .patch = 2 },
594 },
595 },
596 .amdpal => .{
597 .semver = .{
598 .min = .{ .major = 1, .minor = 1, .patch = 0 },
599 .max = .{ .major = 3, .minor = 5, .patch = 0 },
600 },
601 },
602 .cuda => .{
603 .semver = .{
604 .min = .{ .major = 11, .minor = 0, .patch = 1 },
605 .max = .{ .major = 12, .minor = 6, .patch = 1 },
606 },
607 },
608 .nvcl,
609 .opencl,
610 => .{
611 .semver = .{
612 .min = .{ .major = 2, .minor = 2, .patch = 0 },
613 .max = .{ .major = 3, .minor = 0, .patch = 0 },
614 },
615 },
616 .opengl => .{
617 .semver = .{
618 .min = .{ .major = 4, .minor = 5, .patch = 0 },
619 .max = .{ .major = 4, .minor = 6, .patch = 0 },
620 },
621 },
622 .vulkan => .{
623 .semver = .{
624 .min = .{ .major = 1, .minor = 2, .patch = 0 },
625 .max = .{ .major = 1, .minor = 3, .patch = 0 },
626 },
627 },
535628 };
536629 }
537630 };
lib/std/Target/Query.zig+52-7
......@@ -25,10 +25,14 @@ os_version_min: ?OsVersion = null,
2525/// When `os_tag` is native, `null` means equal to the native OS version.
2626os_version_max: ?OsVersion = null,
2727
28/// `null` means default when cross compiling, or native when os_tag is native.
28/// `null` means default when cross compiling, or native when `os_tag` is native.
2929/// If `isGnuLibC()` is `false`, this must be `null` and is ignored.
3030glibc_version: ?SemanticVersion = null,
3131
32/// `null` means default when cross compiling, or native when `os_tag` is native.
33/// If `isAndroid()` is `false`, this must be `null` and is ignored.
34android_api_level: ?u32 = null,
35
3236/// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI.
3337abi: ?Target.Abi = null,
3438
......@@ -98,10 +102,8 @@ pub fn fromTarget(target: Target) Query {
98102 .os_version_min = undefined,
99103 .os_version_max = undefined,
100104 .abi = target.abi,
101 .glibc_version = if (target.isGnuLibC())
102 target.os.version_range.linux.glibc
103 else
104 null,
105 .glibc_version = if (target.isGnuLibC()) target.os.version_range.linux.glibc else null,
106 .android_api_level = if (target.abi.isAndroid()) target.os.version_range.linux.android else null,
105107 };
106108 result.updateOsVersionRange(target.os);
107109
......@@ -147,7 +149,7 @@ pub const ParseOptions = struct {
147149 /// The fields are, respectively:
148150 /// * CPU Architecture
149151 /// * Operating System (and optional version range)
150 /// * C ABI (optional, with optional glibc version)
152 /// * C ABI (optional, with optional glibc version or Android API level)
151153 /// The string "native" can be used for CPU architecture as well as Operating System.
152154 /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted.
153155 arch_os_abi: []const u8 = "native",
......@@ -234,6 +236,11 @@ pub fn parse(args: ParseOptions) !Query {
234236 error.Overflow => return error.InvalidAbiVersion,
235237 error.InvalidVersion => return error.InvalidAbiVersion,
236238 };
239 } else if (abi.isAndroid()) {
240 result.android_api_level = std.fmt.parseUnsigned(u32, abi_ver_text, 10) catch |err| switch (err) {
241 error.InvalidCharacter => return error.InvalidVersion,
242 error.Overflow => return error.Overflow,
243 };
237244 } else {
238245 return error.InvalidAbiVersion;
239246 }
......@@ -355,7 +362,7 @@ pub fn isNativeCpu(self: Query) bool {
355362
356363pub fn isNativeOs(self: Query) bool {
357364 return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
358 self.dynamic_linker.get() == null and self.glibc_version == null;
365 self.dynamic_linker.get() == null and self.glibc_version == null and self.android_api_level == null;
359366}
360367
361368pub fn isNativeAbi(self: Query) bool {
......@@ -439,6 +446,13 @@ pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 {
439446 result.appendSliceAssumeCapacity(name);
440447 result.appendAssumeCapacity('.');
441448 try formatVersion(v, result.writer());
449 } else if (self.android_api_level) |lvl| {
450 const name = if (self.abi) |abi| @tagName(abi) else "android";
451 try result.ensureUnusedCapacity(name.len + 2);
452 result.appendAssumeCapacity('-');
453 result.appendSliceAssumeCapacity(name);
454 result.appendAssumeCapacity('.');
455 try result.writer().print("{d}", .{lvl});
442456 } else if (self.abi) |abi| {
443457 const name = @tagName(abi);
444458 try result.ensureUnusedCapacity(name.len + 1);
......@@ -561,6 +575,7 @@ pub fn eql(a: Query, b: Query) bool {
561575 if (!OsVersion.eqlOpt(a.os_version_min, b.os_version_min)) return false;
562576 if (!OsVersion.eqlOpt(a.os_version_max, b.os_version_max)) return false;
563577 if (!versionEqualOpt(a.glibc_version, b.glibc_version)) return false;
578 if (a.android_api_level != b.android_api_level) return false;
564579 if (a.abi != b.abi) return false;
565580 if (!a.dynamic_linker.eql(b.dynamic_linker)) return false;
566581 if (a.ofmt != b.ofmt) return false;
......@@ -592,6 +607,15 @@ test parse {
592607
593608 try std.testing.expectEqualSlices(u8, "native-native-gnu.2.1.1", text);
594609 }
610 if (builtin.target.abi.isAndroid()) {
611 var query = try Query.parse(.{});
612 query.android_api_level = 30;
613
614 const text = try query.zigTriple(std.testing.allocator);
615 defer std.testing.allocator.free(text);
616
617 try std.testing.expectEqualSlices(u8, "native-native-android.30", text);
618 }
595619 {
596620 const query = try Query.parse(.{
597621 .arch_os_abi = "aarch64-linux",
......@@ -677,4 +701,25 @@ test parse {
677701 defer std.testing.allocator.free(text);
678702 try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text);
679703 }
704 {
705 const query = try Query.parse(.{
706 .arch_os_abi = "aarch64-linux.3.10...4.4.1-android.30",
707 });
708 const target = try std.zig.system.resolveTargetQuery(query);
709
710 try std.testing.expect(target.cpu.arch == .aarch64);
711 try std.testing.expect(target.os.tag == .linux);
712 try std.testing.expect(target.os.version_range.linux.range.min.major == 3);
713 try std.testing.expect(target.os.version_range.linux.range.min.minor == 10);
714 try std.testing.expect(target.os.version_range.linux.range.min.patch == 0);
715 try std.testing.expect(target.os.version_range.linux.range.max.major == 4);
716 try std.testing.expect(target.os.version_range.linux.range.max.minor == 4);
717 try std.testing.expect(target.os.version_range.linux.range.max.patch == 1);
718 try std.testing.expect(target.os.version_range.linux.android == 30);
719 try std.testing.expect(target.abi == .android);
720
721 const text = try query.zigTriple(std.testing.allocator);
722 defer std.testing.allocator.free(text);
723 try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-android.30", text);
724 }
680725}
lib/std/c.zig+11-7
......@@ -44,22 +44,26 @@ comptime {
4444 }
4545}
4646
47/// If not linking libc, returns false.
48/// If linking musl libc, returns true.
49/// If linking gnu libc (glibc), returns true if the target version is greater
50/// than or equal to `glibc_version`.
51/// If linking a libc other than these, returns `false`.
52pub inline fn versionCheck(comptime glibc_version: std.SemanticVersion) bool {
47/// * If not linking libc, returns `false`.
48/// * If linking musl libc, returns `true`.
49/// * If linking GNU libc (glibc), returns `true` if the target version is greater than or equal to
50/// `version`.
51/// * If linking Android libc (bionic), returns `true` if the target API level is greater than or
52/// equal to `version.major`, ignoring other components.
53/// * If linking a libc other than these, returns `false`.
54pub inline fn versionCheck(comptime version: std.SemanticVersion) bool {
5355 return comptime blk: {
5456 if (!builtin.link_libc) break :blk false;
5557 if (native_abi.isMusl()) break :blk true;
5658 if (builtin.target.isGnuLibC()) {
5759 const ver = builtin.os.version_range.linux.glibc;
58 const order = ver.order(glibc_version);
60 const order = ver.order(version);
5961 break :blk switch (order) {
6062 .gt, .eq => true,
6163 .lt => false,
6264 };
65 } else if (builtin.abi.isAndroid()) {
66 break :blk builtin.os.version_range.linux.android >= version.major;
6367 } else {
6468 break :blk false;
6569 }
lib/std/zig/system.zig+4
......@@ -331,6 +331,10 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
331331 os.version_range.linux.glibc = glibc;
332332 }
333333
334 if (query.android_api_level) |android| {
335 os.version_range.linux.android = android;
336 }
337
334338 // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the
335339 // native CPU architecture as being different than the current target), we use this:
336340 const cpu_arch = query.cpu_arch orelse builtin.cpu.arch;
src/Builtin.zig+3
......@@ -124,6 +124,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
124124 \\ .minor = {},
125125 \\ .patch = {},
126126 \\ }},
127 \\ .android = {},
127128 \\ }}}},
128129 \\
129130 , .{
......@@ -138,6 +139,8 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
138139 linux.glibc.major,
139140 linux.glibc.minor,
140141 linux.glibc.patch,
142
143 linux.android,
141144 }),
142145 .windows => |windows| try buffer.writer().print(
143146 \\ .windows = .{{
src/codegen/llvm.zig+52-13
......@@ -164,14 +164,34 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
164164 };
165165
166166 if (llvm_sub_arch) |sub| try llvm_triple.appendSlice(sub);
167 try llvm_triple.append('-');
167168
168 // Unlike CPU backends, GPU backends actually care about the vendor tag.
169 try llvm_triple.appendSlice(switch (target.cpu.arch) {
170 .amdgcn => if (target.os.tag == .mesa3d) "-mesa-" else "-amd-",
171 .nvptx, .nvptx64 => "-nvidia-",
172 .spirv64 => if (target.os.tag == .amdhsa) "-amd-" else "-unknown-",
173 else => "-unknown-",
169 try llvm_triple.appendSlice(switch (target.os.tag) {
170 .aix,
171 .zos,
172 => "ibm",
173 .bridgeos,
174 .driverkit,
175 .ios,
176 .macos,
177 .tvos,
178 .visionos,
179 .watchos,
180 => "apple",
181 .ps4,
182 .ps5,
183 => "scei",
184 .amdhsa,
185 .amdpal,
186 => "amd",
187 .cuda,
188 .nvcl,
189 => "nvidia",
190 .mesa3d,
191 => "mesa",
192 else => "unknown",
174193 });
194 try llvm_triple.append('-');
175195
176196 const llvm_os = switch (target.os.tag) {
177197 .freestanding => "unknown",
......@@ -219,13 +239,20 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
219239 };
220240 try llvm_triple.appendSlice(llvm_os);
221241
222 if (target.os.tag.isDarwin()) {
223 const min_version = target.os.version_range.semver.min;
224 try llvm_triple.writer().print("{d}.{d}.{d}", .{
225 min_version.major,
226 min_version.minor,
227 min_version.patch,
228 });
242 switch (target.os.versionRange()) {
243 .none,
244 .windows,
245 => {},
246 .semver => |ver| try llvm_triple.writer().print("{d}.{d}.{d}", .{
247 ver.min.major,
248 ver.min.minor,
249 ver.min.patch,
250 }),
251 .linux => |ver| try llvm_triple.writer().print("{d}.{d}.{d}", .{
252 ver.range.min.major,
253 ver.range.min.minor,
254 ver.range.min.patch,
255 }),
229256 }
230257 try llvm_triple.append('-');
231258
......@@ -259,6 +286,18 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 {
259286 };
260287 try llvm_triple.appendSlice(llvm_abi);
261288
289 switch (target.os.versionRange()) {
290 .none,
291 .semver,
292 .windows,
293 => {},
294 .linux => |ver| if (target.abi.isGnu()) try llvm_triple.writer().print("{d}.{d}.{d}", .{
295 ver.glibc.major,
296 ver.glibc.minor,
297 ver.glibc.patch,
298 }) else if (target.abi.isAndroid()) try llvm_triple.writer().print("{d}", .{ver.android}),
299 }
300
262301 return llvm_triple.toOwnedSlice();
263302}
264303