xtask\tasks/
build_igvm.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::Xtask;
5use clap::Parser;
6use clap::builder::PossibleValue;
7use std::fmt;
8use std::path::PathBuf;
9
10#[derive(clap::ValueEnum, Copy, Clone, PartialEq, Eq, Debug)]
11enum KernelPackageKind {
12    /// Last known good
13    Lkg,
14    /// Development
15    Dev,
16}
17
18#[derive(Copy, Clone, PartialEq, Eq, Debug)]
19/// The IGVM target architecture.
20pub enum BuildIgvmArch {
21    /// X64
22    X86_64,
23    /// ARM64
24    Aarch64,
25}
26
27impl BuildIgvmArch {
28    /// Host architecture, other places to have that didn't look better.
29    pub fn host() -> Self {
30        // xtask-fmt allow-target-arch oneoff-guest-arch-impl
31        if cfg!(target_arch = "x86_64") {
32            BuildIgvmArch::X86_64
33        }
34        // xtask-fmt allow-target-arch oneoff-guest-arch-impl
35        else if cfg!(target_arch = "aarch64") {
36            BuildIgvmArch::Aarch64
37        } else {
38            panic!("Unsupported host architecture")
39        }
40    }
41
42    /// String representation (what the compiler uses).
43    pub fn as_str(&self) -> &'static str {
44        match self {
45            BuildIgvmArch::X86_64 => "x86_64",
46            BuildIgvmArch::Aarch64 => "aarch64",
47        }
48    }
49}
50
51impl fmt::Display for BuildIgvmArch {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        f.pad(self.as_str())
54    }
55}
56
57impl clap::ValueEnum for BuildIgvmArch {
58    fn value_variants<'a>() -> &'a [Self] {
59        &[BuildIgvmArch::X86_64, BuildIgvmArch::Aarch64]
60    }
61
62    fn to_possible_value(&self) -> Option<PossibleValue> {
63        match self {
64            BuildIgvmArch::X86_64 => Some(PossibleValue::new("x86_64").aliases(["x86-64", "x64"])),
65            BuildIgvmArch::Aarch64 => Some(PossibleValue::new("aarch64").aliases(["arm64"])),
66        }
67    }
68}
69
70/// (DEPRECATED) use `cargo xflowey build-igvm` instead!
71#[derive(Debug, Parser)]
72pub struct BuildIgvm {
73    /// pass `--verbose` to cargo
74    #[clap(long)]
75    verbose: bool,
76
77    /// build underhill binary in release (--profile=underhill-ship) mode
78    #[clap(long)]
79    release: bool,
80
81    /// don't strip underhill binary, so that perf tooling works
82    #[clap(short = 'p', long, requires("release"))]
83    perf: bool,
84
85    /// Preserve debuginfo in the underhill binary in the IGVM file.
86    ///
87    /// This increases the VTL2 memory requirements significantly.
88    #[clap(long)]
89    debuginfo: bool,
90
91    /// path to the underhill binary, none means underhill will be built.
92    #[clap(long)]
93    underhill: Option<PathBuf>,
94
95    /// path to the boot loader, none means the boot loader will be built.
96    #[clap(long)]
97    boot_shim: Option<PathBuf>,
98
99    /// path to the underhill profiler, none means the profiler will be built.
100    #[clap(long)]
101    profiler: Option<PathBuf>,
102
103    /// path to uefi, none means the nuget package of uefi will be used.
104    #[clap(long)]
105    uefi: Option<PathBuf>,
106
107    /// include the AP kernel in the IGVM file
108    #[clap(long)]
109    sidecar: bool,
110
111    /// path to the AP kernel, none means the AP kernel will be built
112    #[clap(long, requires = "sidecar")]
113    sidecar_path: Option<PathBuf>,
114
115    /// json manifest passed to igvmfilegen
116    #[clap(short = 'm', long)]
117    manifest: Option<PathBuf>,
118
119    /// additional layers to be included in the initrd
120    #[clap(long)]
121    layer: Vec<String>,
122
123    /// additional directories to be included in the initrd
124    #[clap(long)]
125    directory: Vec<String>,
126
127    /// Relative path of the output file (IGVM firmware). Defaults to the name
128    /// of the manifest file if not specified.
129    #[clap(short = 'o', long)]
130    output_name: Option<PathBuf>,
131
132    /// Kernel package kind.
133    #[clap(short = 'k', long)]
134    #[clap(value_enum, default_value_t=KernelPackageKind::Lkg)]
135    kernel_kind: KernelPackageKind,
136
137    /// Path to the kernel. Defaults to the one specified in the JSON manifest.
138    #[clap(long)]
139    kernel: Option<PathBuf>,
140
141    /// Path to kernel modules. Defaults to the nuget package path.
142    #[clap(long)]
143    kernel_modules: Option<PathBuf>,
144
145    /// Target architecture.
146    #[clap(short = 'a', long)]
147    #[clap(default_value_t=BuildIgvmArch::host())]
148    arch: BuildIgvmArch,
149
150    /// Pass additional features when building `underhill`
151    #[clap(long)]
152    extra_features: Vec<String>,
153
154    /// Which Linux kernel to use for VTL0. If not specified, the packaged
155    /// openvmm test linux direct kernel is used.
156    #[clap(long)]
157    vtl0_kernel: Option<PathBuf>,
158}
159
160impl Xtask for BuildIgvm {
161    #[rustfmt::skip]
162    fn run(self, _ctx: crate::XtaskCtx) -> anyhow::Result<()> {
163        let _ = self;
164
165        log::warn!("NOTE: `cargo xtask build-igvm` has been deleted!");
166        log::warn!("");
167        log::warn!("Please switch over to using `cargo xflowey build-igvm` instead.");
168        log::warn!("");
169        log::warn!("  NOTE: The new `xflowey build-igvm` CLI is INCOMPATIBLE with `xtask build-igvm`!");
170        log::warn!("");
171        log::warn!("    This new CLI is designed to be more consistent, user-friendly, and better-documented than the legacy `xtask build-igvm` CLI.");
172        log::warn!("    Please read the docs at `cargo xflowey build-igvm --help` to learn more");
173        log::warn!("");
174        log::warn!("  NOTE: The new `xflowey build-igvm` command has DIFFERENT output filenames and directories!");
175        log::warn!("");
176        log::warn!("    Old: `target/x86_64-unknown-linux-musl/debug/underhill-cvm.bin`");
177        log::warn!("    New: `flowey-out/artifacts/build-igvm/x64-cvm/openhcl-cvm-x64.bin`");
178        log::warn!("");
179
180        anyhow::bail!("`cargo xtask build-igvm` has been deleted!");
181    }
182}