@@ -6,6 +6,8 @@ |
| 6 | | 6 | |
| 7 | use std::collections::BTreeMap; | 7 | use std::collections::BTreeMap; |
| 8 | use std::io::{self, Write}; | 8 | use std::io::{self, Write}; |
| | 9 | +use std::process::Command; |
| | 10 | +use std::sync::OnceLock; |
| 9 | | 11 | |
| 10 | // ---- Mach-O Constants ---- | 12 | // ---- Mach-O Constants ---- |
| 11 | | 13 | |
@@ -83,12 +85,33 @@ impl Default for BuildVersion { |
| 83 | fn default() -> Self { | 85 | fn default() -> Self { |
| 84 | Self { | 86 | Self { |
| 85 | platform: PLATFORM_MACOS, | 87 | platform: PLATFORM_MACOS, |
| 86 | - minos: pack_version(15, 0, 0), | 88 | + minos: default_host_minos(), |
| 87 | sdk: 0, | 89 | sdk: 0, |
| 88 | } | 90 | } |
| 89 | } | 91 | } |
| 90 | } | 92 | } |
| 91 | | 93 | |
| | 94 | +fn default_host_minos() -> u32 { |
| | 95 | + static HOST_MINOS: OnceLock<u32> = OnceLock::new(); |
| | 96 | + *HOST_MINOS.get_or_init(|| { |
| | 97 | + Command::new("sw_vers") |
| | 98 | + .arg("-productVersion") |
| | 99 | + .output() |
| | 100 | + .ok() |
| | 101 | + .and_then(|out| out.status.success().then_some(out.stdout)) |
| | 102 | + .and_then(|stdout| { |
| | 103 | + let version = String::from_utf8(stdout).ok()?; |
| | 104 | + version |
| | 105 | + .trim() |
| | 106 | + .split('.') |
| | 107 | + .next() |
| | 108 | + .and_then(|major| major.parse::<u32>().ok()) |
| | 109 | + }) |
| | 110 | + .map(|major| pack_version(major, 0, 0)) |
| | 111 | + .unwrap_or_else(|| pack_version(15, 0, 0)) |
| | 112 | + }) |
| | 113 | +} |
| | 114 | + |
| 92 | /// A symbol in the object file. | 115 | /// A symbol in the object file. |
| 93 | #[derive(Debug, Clone)] | 116 | #[derive(Debug, Clone)] |
| 94 | pub struct Symbol { | 117 | pub struct Symbol { |