Skip to main content

cargo_hyperlight/
lib.rs

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