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.target_dir(&args.target_dir);
96        self.sysroot(args.sysroot_dir());
97        self.append_rustflags("--cfg=hyperlight");
98        self.append_rustflags("--check-cfg=cfg(hyperlight)");
99        if args.unstable_target_spec {
100            self.append_rustflags(sysroot::UNSTABLE_TARGET_SPEC_FLAG);
101        }
102        self.entrypoint("entrypoint");
103        if let Some(clang) = &args.clang {
104            self.cc_env(&args.target, clang);
105        } else {
106            // If we couldn't find clang, use the default from the
107            // system path. This will then error if we try to build
108            // using cc-rs, but will succeed otherwise.
109            self.cc_env(&args.target, "clang");
110        }
111        if let Some(ar) = &args.ar {
112            self.ar_env(&args.target, ar);
113        } else {
114            // do nothing, let cc-rs find ar itself
115        }
116        self.append_cflags(&args.target, toolchain::cflags(args, bootstrap).joined());
117
118        self
119    }
120}
121
122impl Args {
123    pub fn prepare_sysroot(&mut self) -> Result<()> {
124        // Build sysroot
125        sysroot::build(self)?;
126
127        // Build toolchain
128        toolchain::prepare(self)?;
129
130        Ok(())
131    }
132}