| ... | @@ -7,10 +7,13 @@ const std = @import("std"); | ... | @@ -7,10 +7,13 @@ const std = @import("std"); |
| 7 | const assert = std.debug.assert; | 7 | const assert = std.debug.assert; |
| 8 | const mem = std.mem; | 8 | const mem = std.mem; |
| 9 | const testing = std.testing; | 9 | const testing = std.testing; |
| | 10 | const os = std.os; |
| | 11 | |
| | 12 | const Target = std.Target; |
| 10 | | 13 | |
| 11 | /// Detect macOS version. | 14 | /// Detect macOS version. |
| 12 | /// `os` is not modified in case of error. | 15 | /// `target_os` is not modified in case of error. |
| 13 | pub fn detect(os: *std.Target.Os) !void { | 16 | pub fn detect(target_os: *Target.Os) !void { |
| 14 | // Drop use of osproductversion sysctl because: | 17 | // Drop use of osproductversion sysctl because: |
| 15 | // 1. only available 10.13.4 High Sierra and later | 18 | // 1. only available 10.13.4 High Sierra and later |
| 16 | // 2. when used from a binary built against < SDK 11.0 it returns 10.16 and masks Big Sur 11.x version | 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,8 +63,8 @@ pub fn detect(os: *std.Target.Os) !void { |
| 60 | if (parseSystemVersion(bytes)) |ver| { | 63 | if (parseSystemVersion(bytes)) |ver| { |
| 61 | // never return non-canonical `10.(16+)` | 64 | // never return non-canonical `10.(16+)` |
| 62 | if (!(ver.major == 10 and ver.minor >= 16)) { | 65 | if (!(ver.major == 10 and ver.minor >= 16)) { |
| 63 | os.version_range.semver.min = ver; | 66 | target_os.version_range.semver.min = ver; |
| 64 | os.version_range.semver.max = ver; | 67 | target_os.version_range.semver.max = ver; |
| 65 | return; | 68 | return; |
| 66 | } | 69 | } |
| 67 | continue; | 70 | continue; |
| ... | @@ -410,7 +413,7 @@ fn testVersionEquality(expected: std.builtin.Version, got: std.builtin.Version) | ... | @@ -410,7 +413,7 @@ fn testVersionEquality(expected: std.builtin.Version, got: std.builtin.Version) |
| 410 | /// `-syslibroot` param of the linker. | 413 | /// `-syslibroot` param of the linker. |
| 411 | /// The caller needs to free the resulting path slice. | 414 | /// The caller needs to free the resulting path slice. |
| 412 | pub fn getSDKPath(allocator: *mem.Allocator) ![]u8 { | 415 | pub fn getSDKPath(allocator: *mem.Allocator) ![]u8 { |
| 413 | assert(std.Target.current.isDarwin()); | 416 | assert(Target.current.isDarwin()); |
| 414 | const argv = &[_][]const u8{ "xcrun", "--show-sdk-path" }; | 417 | const argv = &[_][]const u8{ "xcrun", "--show-sdk-path" }; |
| 415 | const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); | 418 | const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv }); |
| 416 | defer { | 419 | defer { |
| ... | @@ -426,3 +429,41 @@ pub fn getSDKPath(allocator: *mem.Allocator) ![]u8 { | ... | @@ -426,3 +429,41 @@ pub fn getSDKPath(allocator: *mem.Allocator) ![]u8 { |
| 426 | const syslibroot = mem.trimRight(u8, result.stdout, "\r\n"); | 429 | const syslibroot = mem.trimRight(u8, result.stdout, "\r\n"); |
| 427 | return mem.dupe(allocator, u8, syslibroot); | 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 | } |