| ... | ... | @@ -7,10 +7,13 @@ const std = @import("std"); |
| 7 | 7 | const assert = std.debug.assert; |
| 8 | 8 | const mem = std.mem; |
| 9 | 9 | const testing = std.testing; |
| 10 | const os = std.os; |
| 11 | |
| 12 | const Target = std.Target; |
| 10 | 13 | |
| 11 | 14 | /// Detect macOS version. |
| 12 | | /// `os` is not modified in case of error. |
| 13 | | pub fn detect(os: *std.Target.Os) !void { |
| 15 | /// `target_os` is not modified in case of error. |
| 16 | pub fn detect(target_os: *Target.Os) !void { |
| 14 | 17 | // Drop use of osproductversion sysctl because: |
| 15 | 18 | // 1. only available 10.13.4 High Sierra and later |
| 16 | 19 | // 2. when used from a binary built against < SDK 11.0 it returns 10.16 and masks Big Sur 11.x version |
| ... | ... | @@ -60,8 +63,8 @@ pub fn detect(os: *std.Target.Os) !void { |
| 60 | 63 | if (parseSystemVersion(bytes)) |ver| { |
| 61 | 64 | // never return non-canonical `10.(16+)` |
| 62 | 65 | if (!(ver.major == 10 and ver.minor >= 16)) { |
| 63 | | os.version_range.semver.min = ver; |
| 64 | | os.version_range.semver.max = ver; |
| 66 | target_os.version_range.semver.min = ver; |
| 67 | target_os.version_range.semver.max = ver; |
| 65 | 68 | return; |
| 66 | 69 | } |
| 67 | 70 | continue; |
| ... | ... | @@ -410,7 +413,7 @@ fn testVersionEquality(expected: std.builtin.Version, got: std.builtin.Version) |
| 410 | 413 | /// `-syslibroot` param of the linker. |
| 411 | 414 | /// The caller needs to free the resulting path slice. |
| 412 | 415 | pub fn getSDKPath(allocator: *mem.Allocator) ![]u8 { |
| 413 | | assert(std.Target.current.isDarwin()); |
| 416 | assert(Target.current.isDarwin()); |
| 414 | 417 | const argv = &[_][]const u8{ "xcrun", "--show-sdk-path" }; |
| 415 | 418 | const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); |
| 416 | 419 | defer { |
| ... | ... | @@ -426,3 +429,41 @@ pub fn getSDKPath(allocator: *mem.Allocator) ![]u8 { |
| 426 | 429 | const syslibroot = mem.trimRight(u8, result.stdout, "\r\n"); |
| 427 | 430 | return mem.dupe(allocator, u8, syslibroot); |
| 428 | 431 | } |
| 432 | |
| 433 | pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 434 | var cpu_family: os.CPUFAMILY = undefined; |
| 435 | var len: usize = @sizeOf(os.CPUFAMILY); |
| 436 | os.sysctlbynameZ("hw.cpufamily", &cpu_family, &len, null, 0) catch |err| switch (err) { |
| 437 | error.NameTooLong => unreachable, // constant, known good value |
| 438 | error.PermissionDenied => unreachable, // only when setting values, |
| 439 | error.SystemResources => unreachable, // memory already on the stack |
| 440 | error.UnknownName => unreachable, // constant, known good value |
| 441 | error.Unexpected => unreachable, // EFAULT: stack should be safe, EISDIR/ENOTDIR: constant, known good value |
| 442 | }; |
| 443 | |
| 444 | const current_arch = Target.current.cpu.arch; |
| 445 | switch (current_arch) { |
| 446 | .aarch64, .aarch64_be, .aarch64_32 => { |
| 447 | const model = switch (cpu_family) { |
| 448 | .ARM_FIRESTORM_ICESTORM => &Target.aarch64.cpu.apple_a14, |
| 449 | .ARM_LIGHTNING_THUNDER => &Target.aarch64.cpu.apple_a13, |
| 450 | .ARM_VORTEX_TEMPEST => &Target.aarch64.cpu.apple_a12, |
| 451 | .ARM_MONSOON_MISTRAL => &Target.aarch64.cpu.apple_a11, |
| 452 | .ARM_HURRICANE => &Target.aarch64.cpu.apple_a10, |
| 453 | .ARM_TWISTER => &Target.aarch64.cpu.apple_a9, |
| 454 | .ARM_TYPHOON => &Target.aarch64.cpu.apple_a8, |
| 455 | .ARM_CYCLONE => &Target.aarch64.cpu.cyclone, |
| 456 | else => return null, |
| 457 | }; |
| 458 | |
| 459 | return Target.Cpu{ |
| 460 | .arch = current_arch, |
| 461 | .model = model, |
| 462 | .features = model.features, |
| 463 | }; |
| 464 | }, |
| 465 | else => {}, |
| 466 | } |
| 467 | |
| 468 | return null; |
| 469 | } |