nexus_sdk/compile/mod.rs
1use crypto_common::generic_array::ArrayLength;
2use std::fs;
3use std::io::Write;
4use std::marker::PhantomData;
5use std::path::PathBuf;
6use std::str::FromStr;
7
8use crate::error::BuildError;
9
10/// Compilation and packaging for Rust guests via Cargo.
11pub mod cargo;
12
13/// A guest program packager.
14pub trait Packager {
15 type DigestSize: ArrayLength<u8>;
16
17 /// Return the digest length the packager uses.
18 fn digest_len() -> usize;
19}
20
21/// Dynamic compilation of guest programs.
22///
23/// By default, compilation occurs within `/tmp`. However, the implementation does respect the [`OUT_DIR`](https://doc.rust-lang.org/cargo/reference/environment-variables.html) environment variable.
24#[derive(Clone)]
25pub struct Compiler<P: Packager> {
26 /// The (in-workspace) package to build.
27 pub package: String,
28 /// The binary produced by the build that should be loaded into the zkVM after successful compilation.
29 pub binary: String,
30 debug: bool,
31 native: bool,
32 unique: bool,
33 _packager: PhantomData<P>,
34}
35
36/// An interface for dynamic compilation of guest programs.
37pub trait Compile {
38 /// Setup dynamic compilation.
39 fn new(package: &str) -> Self;
40
41 /// Setup dynamic compilation, using non-default binary name.
42 fn new_with_custom_binary(package: &str, binary: &str) -> Self;
43
44 /// Set dynamic compilation to build the guest program in a debug profile.
45 fn set_debug_build(&mut self, debug: bool);
46
47 /// Set dynamic compilation to build for the native (host machine) target, rather than for the zkVM.
48 fn set_native_build(&mut self, native: bool);
49
50 /// Set dynamic compilation to run a unique build that neither overwrites prior builds nor will be overwritten by future builds. May be used to concurrently build different versions of the same binary.
51 ///
52 /// Note: the SDK does not automatically clean or otherwise manage the resultant builds in the output directory.
53 fn set_unique_build(&mut self, unique: bool);
54
55 /// Set the linker script to use when building the guest binary.
56 fn set_linker() -> Result<PathBuf, BuildError> {
57 let linker_script = include_str!("./linker-scripts/default.x");
58
59 let linker_path = PathBuf::from_str("/tmp/nexus-guest-linkers/default.ld").unwrap();
60
61 if let Some(parent) = linker_path.parent() {
62 fs::create_dir_all(parent)?;
63 }
64
65 let mut file = fs::File::create(linker_path.clone())?;
66 file.write_all(linker_script.as_bytes())?;
67
68 Ok(linker_path)
69 }
70
71 /// Compile and build the guest binary.
72 fn build(&mut self) -> Result<PathBuf, BuildError>;
73}