nexus_sdk/compile/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use crypto_common::generic_array::ArrayLength;
use std::fs;
use std::io::Write;
use std::marker::PhantomData;
use std::path::PathBuf;
use std::str::FromStr;

use crate::error::BuildError;

/// Compilation and packaging for Rust guests via Cargo.
pub mod cargo;

/// A guest program packager.
pub trait Packager {
    type DigestSize: ArrayLength<u8>;

    /// Return the digest length the packager uses.
    fn digest_len() -> usize;
}

/// Dynamic compilation of guest programs.
///
/// 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.
#[derive(Clone)]
pub struct Compiler<P: Packager> {
    /// The (in-workspace) package to build.
    pub package: String,
    /// The binary produced by the build that should be loaded into the zkVM after successful compilation.
    pub binary: String,
    debug: bool,
    native: bool,
    unique: bool,
    _packager: PhantomData<P>,
}

/// An interface for dynamic compilation of guest programs.
pub trait Compile {
    /// Setup dynamic compilation.
    fn new(package: &str) -> Self;

    /// Setup dynamic compilation, using non-default binary name.
    fn new_with_custom_binary(package: &str, binary: &str) -> Self;

    /// Set dynamic compilation to build the guest program in a debug profile.
    fn set_debug_build(&mut self, debug: bool);

    /// Set dynamic compilation to build for the native (host machine) target, rather than for the zkVM.
    fn set_native_build(&mut self, native: bool);

    /// 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.
    ///
    /// Note: the SDK does not automatically clean or otherwise manage the resultant builds in the output directory.
    fn set_unique_build(&mut self, unique: bool);

    /// Set the linker script to use when building the guest binary.
    fn set_linker() -> Result<PathBuf, BuildError> {
        let linker_script = include_str!("./linker-scripts/default.x");

        let linker_path = PathBuf::from_str("/tmp/nexus-guest-linkers/default.ld").unwrap();

        if let Some(parent) = linker_path.parent() {
            fs::create_dir_all(parent)?;
        }

        let mut file = fs::File::create(linker_path.clone())?;
        file.write_all(linker_script.as_bytes())?;

        Ok(linker_path)
    }

    /// Compile and build the guest binary.
    fn build(&mut self) -> Result<PathBuf, BuildError>;
}