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 "riscv32i-unknown-none-elf"
84 };
85
86 let profile = if self.debug { "debug" } else { "release" };
87
88 let envs = vec![("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.envs(envs).args([
105 "build",
106 "--package",
107 self.package.as_str(),
108 "--bin",
109 prog,
110 "--target-dir",
111 &dest,
112 "--target",
113 target,
114 "--profile",
115 profile,
116 ]);
117
118 let res = cmd.output()?;
119
120 if !res.status.success() {
121 io::stderr().write_all(&res.stderr)?;
122 return Err(BuildError::CompilerError);
123 }
124
125 let elf_path =
126 PathBuf::from_str(&format!("{}/{}/{}/{}", dest, target, profile, prog)).unwrap();
127
128 Ok(elf_path)
129 }
130}