nexus_sdk/compile/
cargo.rs1use crypto_common::generic_array::typenum::{ToInt, U32};
2use std::io;
3use std::io::Write;
4use std::marker::PhantomData;
5use std::path::PathBuf;
6use std::process::Command;
7use std::str::FromStr;
8use uuid::Uuid;
9
10pub use crate::error::BuildError;
11
12use super::{Compile, Compiler, Packager};
13
14pub enum CargoPackager {}
16impl Packager for CargoPackager {
17 type DigestSize = U32;
18
19 fn digest_len() -> usize {
20 let sz: u32 = Self::DigestSize::to_int();
21 sz as usize
22 }
23}
24
25impl Compile for Compiler<CargoPackager> {
26 fn new(package: &str) -> Self {
28 Self {
29 package: package.to_string(),
30 binary: package.to_string(),
31 debug: false,
32 native: false,
33 unique: false,
34 _packager: PhantomData,
35 }
36 }
37
38 fn new_with_custom_binary(package: &str, binary: &str) -> Self {
40 Self {
41 package: package.to_string(),
42 binary: binary.to_string(),
43 debug: false,
44 native: false,
45 unique: false,
46 _packager: PhantomData,
47 }
48 }
49
50 fn set_debug_build(&mut self, debug: bool) {
52 self.debug = debug;
53 }
54
55 fn set_native_build(&mut self, native: bool) {
57 self.native = native;
58 }
59
60 fn set_unique_build(&mut self, unique: bool) {
64 self.unique = unique;
65 }
66
67 fn build(&mut self) -> Result<PathBuf, BuildError> {
69 let linker_path = Compiler::set_linker()?;
70
71 let rust_flags = [
72 "-C",
73 "relocation-model=pic",
74 "-C",
75 &format!("link-arg=-T{}", linker_path.display()),
76 "-C",
77 "panic=abort",
78 ];
79
80 let target = if self.native {
81 "native"
82 } else {
83 "riscv32im-unknown-none-elf"
84 };
85
86 let profile = if self.debug { "debug" } else { "release" };
87
88 let cargo_encoded_rustflags = rust_flags.join("\x1f");
89 let prog = self.binary.as_str();
90
91 let mut dest = match std::env::var_os("OUT_DIR") {
92 Some(path) => path.into_string().unwrap(),
93 None => "/tmp/nexus-target".into(),
94 };
95
96 if self.unique {
97 let uuid = Uuid::new_v4();
98 dest = format!("{}-{}", dest, uuid);
99 }
100
101 let cargo_bin = std::env::var("CARGO").unwrap_or_else(|_err| "cargo".into());
102 let mut cmd = Command::new(cargo_bin);
103
104 cmd.env("CARGO_ENCODED_RUSTFLAGS", cargo_encoded_rustflags)
106 .args([
107 "build",
108 "--package",
109 self.package.as_str(),
110 "--bin",
111 prog,
112 "--target-dir",
113 &dest,
114 ]);
115
116 if !self.native {
118 cmd.args(["--target", target]);
119 }
120
121 cmd.args(["--profile", profile]);
123
124 let res = cmd.output()?;
125
126 if !res.status.success() {
127 io::stderr().write_all(&res.stderr)?;
128 return Err(BuildError::CompilerError);
129 }
130
131 let elf_path = if self.native {
133 PathBuf::from_str(&format!("{}/{}/{}", dest, profile, prog)).unwrap()
134 } else {
135 PathBuf::from_str(&format!("{}/{}/{}/{}", dest, target, profile, prog)).unwrap()
136 };
137
138 Ok(elf_path)
139 }
140}