Skip to main content

flowey_lib_hvlite/
common.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Vocabulary types for the most-common build profiles, architectures,
5//! platforms, and target triples used in the OpenVMM/OpenHCL tree.
6//!
7//! Outside of a few binaries / libraries that are intimately tied to one
8//! particular architecture / platform, most things in the hvlite tree run on a
9//! common subset of supported target triples + build profiles.
10
11use flowey::node::prelude::*;
12
13/// Vocabulary type for artifacts that only get built using the two most
14/// common cargo build profiles (i.e: `release` vs. `debug`).
15///
16/// More specialized artifacts should use the
17/// [`BuildProfile`](crate::run_cargo_build::BuildProfile) type, which
18/// enumerates _all_ build profiles defined in HvLite's `Cargo.toml` file.
19#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
20pub enum CommonProfile {
21    Release,
22    Debug,
23}
24
25impl CommonProfile {
26    pub fn from_release(release: bool) -> Self {
27        match release {
28            true => Self::Release,
29            false => Self::Debug,
30        }
31    }
32
33    pub fn to_release(self) -> bool {
34        match self {
35            Self::Release => true,
36            Self::Debug => false,
37        }
38    }
39}
40
41impl From<CommonProfile> for crate::run_cargo_build::BuildProfile {
42    fn from(value: CommonProfile) -> Self {
43        match value {
44            CommonProfile::Release => crate::run_cargo_build::BuildProfile::Release,
45            CommonProfile::Debug => crate::run_cargo_build::BuildProfile::Debug,
46        }
47    }
48}
49
50/// Vocabulary type for artifacts that only get built for the most common
51/// actively-supported architectures in the hvlite tree.
52#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
53pub enum CommonArch {
54    X86_64,
55    Aarch64,
56}
57
58impl CommonArch {
59    /// Convert to a [`target_lexicon::Architecture`].
60    pub fn as_arch(&self) -> target_lexicon::Architecture {
61        match self {
62            CommonArch::X86_64 => target_lexicon::Architecture::X86_64,
63            CommonArch::Aarch64 => {
64                target_lexicon::Architecture::Aarch64(target_lexicon::Aarch64Architecture::Aarch64)
65            }
66        }
67    }
68
69    /// Convert from a [`target_lexicon::Triple`], failing if the triple's
70    /// architecture is not one of the common architectures.
71    pub fn from_triple(triple: &target_lexicon::Triple) -> anyhow::Result<Self> {
72        Self::from_architecture(triple.architecture)
73    }
74
75    /// Convert from a [`target_lexicon::Architecture`], failing if it is not
76    /// one of the common architectures.
77    pub fn from_architecture(arch: target_lexicon::Architecture) -> anyhow::Result<Self> {
78        Ok(match arch {
79            target_lexicon::Architecture::Aarch64(target_lexicon::Aarch64Architecture::Aarch64) => {
80                Self::Aarch64
81            }
82            target_lexicon::Architecture::X86_64 => Self::X86_64,
83            _ => anyhow::bail!("unsupported arch {arch}"),
84        })
85    }
86}
87
88impl TryFrom<FlowArch> for CommonArch {
89    type Error = anyhow::Error;
90
91    fn try_from(arch: FlowArch) -> anyhow::Result<Self> {
92        Ok(match arch {
93            FlowArch::X86_64 => Self::X86_64,
94            FlowArch::Aarch64 => Self::Aarch64,
95            arch => anyhow::bail!("unsupported arch {arch}"),
96        })
97    }
98}
99
100/// Vocabulary type for artifacts that only get built for the most common
101/// actively-supported platforms in the hvlite tree.
102#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
103pub enum CommonPlatform {
104    WindowsMsvc,
105    LinuxGnu,
106    LinuxMusl,
107    MacOs,
108}
109
110impl TryFrom<FlowPlatform> for CommonPlatform {
111    type Error = anyhow::Error;
112
113    fn try_from(platform: FlowPlatform) -> anyhow::Result<Self> {
114        Ok(match platform {
115            FlowPlatform::Windows => Self::WindowsMsvc,
116            FlowPlatform::Linux(_) => Self::LinuxGnu,
117            FlowPlatform::MacOs => Self::MacOs,
118            platform => anyhow::bail!("unsupported platform {platform}"),
119        })
120    }
121}
122
123#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
124pub enum CommonTriple {
125    Common {
126        arch: CommonArch,
127        platform: CommonPlatform,
128    },
129    Custom(target_lexicon::Triple),
130}
131
132impl CommonTriple {
133    pub const X86_64_WINDOWS_MSVC: Self = Self::Common {
134        arch: CommonArch::X86_64,
135        platform: CommonPlatform::WindowsMsvc,
136    };
137    pub const X86_64_LINUX_GNU: Self = Self::Common {
138        arch: CommonArch::X86_64,
139        platform: CommonPlatform::LinuxGnu,
140    };
141    pub const X86_64_LINUX_MUSL: Self = Self::Common {
142        arch: CommonArch::X86_64,
143        platform: CommonPlatform::LinuxMusl,
144    };
145    pub const AARCH64_WINDOWS_MSVC: Self = Self::Common {
146        arch: CommonArch::Aarch64,
147        platform: CommonPlatform::WindowsMsvc,
148    };
149    pub const AARCH64_LINUX_GNU: Self = Self::Common {
150        arch: CommonArch::Aarch64,
151        platform: CommonPlatform::LinuxGnu,
152    };
153    pub const AARCH64_LINUX_MUSL: Self = Self::Common {
154        arch: CommonArch::Aarch64,
155        platform: CommonPlatform::LinuxMusl,
156    };
157}
158
159impl std::fmt::Debug for CommonTriple {
160    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161        std::fmt::Debug::fmt(&self.as_triple(), f)
162    }
163}
164
165impl std::fmt::Display for CommonTriple {
166    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167        std::fmt::Display::fmt(&self.as_triple(), f)
168    }
169}
170
171impl PartialOrd for CommonTriple {
172    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
173        Some(self.cmp(other))
174    }
175}
176
177impl Ord for CommonTriple {
178    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
179        self.as_triple()
180            .to_string()
181            .cmp(&other.as_triple().to_string())
182    }
183}
184
185impl CommonTriple {
186    pub fn as_triple(&self) -> target_lexicon::Triple {
187        match self {
188            CommonTriple::Common { arch, platform } => match platform {
189                CommonPlatform::WindowsMsvc => target_lexicon::Triple {
190                    architecture: arch.as_arch(),
191                    vendor: target_lexicon::Vendor::Pc,
192                    operating_system: target_lexicon::OperatingSystem::Windows,
193                    environment: target_lexicon::Environment::Msvc,
194                    binary_format: target_lexicon::BinaryFormat::Coff,
195                },
196                CommonPlatform::LinuxGnu => target_lexicon::Triple {
197                    architecture: arch.as_arch(),
198                    vendor: target_lexicon::Vendor::Unknown,
199                    operating_system: target_lexicon::OperatingSystem::Linux,
200                    environment: target_lexicon::Environment::Gnu,
201                    binary_format: target_lexicon::BinaryFormat::Elf,
202                },
203                CommonPlatform::LinuxMusl => target_lexicon::Triple {
204                    architecture: arch.as_arch(),
205                    vendor: target_lexicon::Vendor::Unknown,
206                    operating_system: target_lexicon::OperatingSystem::Linux,
207                    environment: target_lexicon::Environment::Musl,
208                    binary_format: target_lexicon::BinaryFormat::Elf,
209                },
210                CommonPlatform::MacOs => target_lexicon::Triple {
211                    architecture: arch.as_arch(),
212                    vendor: target_lexicon::Vendor::Apple,
213                    operating_system: target_lexicon::OperatingSystem::Darwin(None),
214                    environment: target_lexicon::Environment::Unknown,
215                    binary_format: target_lexicon::BinaryFormat::Macho,
216                },
217            },
218            CommonTriple::Custom(t) => t.clone(),
219        }
220    }
221
222    /// Get the common architecture of this triple, failing if the triple's
223    /// architecture is not one of the common architectures.
224    pub fn common_arch(&self) -> anyhow::Result<CommonArch> {
225        match self {
226            CommonTriple::Common { arch, .. } => Ok(*arch),
227            CommonTriple::Custom(target) => CommonArch::from_triple(target),
228        }
229    }
230}