Skip to main content

cargo_hyperlight/
lib.rs

1use anyhow::Result;
2
3mod cargo_cmd;
4mod cli;
5mod command;
6mod sysroot;
7mod toolchain;
8
9use cargo_cmd::CargoCmd;
10use cli::Args;
11pub use command::Command;
12
13/// Constructs a new `Command` for launching cargo targeting
14/// [hyperlight](https://github.com/hyperlight-dev/hyperlight) guest code.
15///
16/// The value of the `CARGO` environment variable is used if it is set; otherwise, the
17/// default `cargo` from the system PATH is used.
18/// If `RUSTUP_TOOLCHAIN` is set in the environment, it is also propagated to the
19/// child process to ensure correct functioning of the rustup wrappers.
20///
21/// The default configuration is:
22/// - No arguments to the program
23/// - Inherits the current process's environment
24/// - Inherits the current process's working directory
25///
26/// # Errors
27///
28/// This function will return an error if:
29/// - If the `CARGO` environment variable is set but it specifies an invalid path
30/// - If the `CARGO` environment variable is not set and the `cargo` program cannot be found in the system PATH
31///
32/// # Examples
33///
34/// Basic usage:
35///
36/// ```rust
37/// use cargo_hyperlight::cargo;
38///
39/// let command = cargo().unwrap();
40/// ```
41pub fn cargo() -> Result<Command> {
42    Command::new()
43}
44
45impl Args {
46    pub fn sysroot_dir(&self) -> std::path::PathBuf {
47        self.target_dir.join("sysroot")
48    }
49
50    pub fn triplet_dir(&self) -> std::path::PathBuf {
51        self.sysroot_dir()
52            .join("lib")
53            .join("rustlib")
54            .join(&self.target)
55    }
56
57    pub fn build_dir(&self) -> std::path::PathBuf {
58        self.sysroot_dir().join("target")
59    }
60
61    pub fn libs_dir(&self) -> std::path::PathBuf {
62        self.triplet_dir().join("lib")
63    }
64
65    pub fn includes_dir(&self) -> std::path::PathBuf {
66        self.triplet_dir().join("include")
67    }
68
69    pub fn crate_dir(&self) -> std::path::PathBuf {
70        self.sysroot_dir().join("crate")
71    }
72}
73
74trait CargoCommandExt {
75    fn populate_from_args(&mut self, args: &Args) -> &mut Self;
76}
77
78impl CargoCommandExt for std::process::Command {
79    fn populate_from_args(&mut self, args: &Args) -> &mut Self {
80        self.target(&args.target);
81        self.sysroot(args.sysroot_dir());
82        self.append_rustflags("--cfg=hyperlight");
83        self.append_rustflags("--check-cfg=cfg(hyperlight)");
84        self.entrypoint("entrypoint");
85        if let Some(clang) = &args.clang {
86            self.cc_env(&args.target, clang);
87        } else {
88            // If we couldn't find clang, use the default from the
89            // system path. This will then error if we try to build
90            // using cc-rs, but will succeed otherwise.
91            self.cc_env(&args.target, "clang");
92        }
93        if let Some(ar) = &args.ar {
94            self.ar_env(&args.target, ar);
95        } else {
96            // do nothing, let cc-rs find ar itself
97        }
98        self.append_cflags(&args.target, toolchain::cflags(args));
99
100        self
101    }
102}
103
104impl Args {
105    pub fn prepare_sysroot(&self) -> Result<()> {
106        // Build sysroot
107        sysroot::build(self)?;
108
109        // Build toolchain
110        toolchain::prepare(self)?;
111
112        Ok(())
113    }
114}