sp1_build/
lib.rs

1mod build;
2mod command;
3mod utils;
4use build::build_program_internal;
5pub use build::{execute_build_program, generate_elf_paths};
6pub use command::TOOLCHAIN_NAME;
7
8use clap::Parser;
9
10const DEFAULT_DOCKER_TAG: &str = concat!("v", env!("CARGO_PKG_VERSION"));
11const BUILD_TARGET: &str = "riscv32im-succinct-zkvm-elf";
12const HELPER_TARGET_SUBDIR: &str = "elf-compilation";
13
14/// Compile an SP1 program.
15///
16/// Additional arguments are useful for configuring the build process, including options for using
17/// Docker, specifying binary and ELF names, ignoring Rust version checks, and enabling specific
18/// features.
19#[derive(Clone, Parser, Debug)]
20pub struct BuildArgs {
21    #[clap(
22        long,
23        action,
24        help = "Run compilation using a Docker container for reproducible builds."
25    )]
26    pub docker: bool,
27    #[clap(
28        long,
29        help = "The ghcr.io/succinctlabs/sp1 image tag to use when building with Docker.",
30        default_value = DEFAULT_DOCKER_TAG
31    )]
32    pub tag: String,
33    #[clap(
34        long,
35        action,
36        value_delimiter = ',',
37        help = "Space or comma separated list of features to activate"
38    )]
39    pub features: Vec<String>,
40    #[clap(
41        long,
42        action,
43        value_delimiter = ',',
44        help = "Space or comma separated list of extra flags to invokes `rustc` with"
45    )]
46    pub rustflags: Vec<String>,
47    #[clap(long, action, help = "Do not activate the `default` feature")]
48    pub no_default_features: bool,
49    #[clap(long, action, help = "Ignore `rust-version` specification in packages")]
50    pub ignore_rust_version: bool,
51    #[clap(long, action, help = "Assert that `Cargo.lock` will remain unchanged")]
52    pub locked: bool,
53    #[clap(
54        short,
55        long,
56        action,
57        help = "Build only the specified packages",
58        num_args = 1..
59    )]
60    pub packages: Vec<String>,
61    #[clap(
62        alias = "bin",
63        long,
64        action,
65        help = "Build only the specified binaries",
66        num_args = 1..
67    )]
68    pub binaries: Vec<String>,
69    #[clap(long, action, requires = "output_directory", help = "ELF binary name")]
70    pub elf_name: Option<String>,
71    #[clap(alias = "out-dir", long, action, help = "Copy the compiled ELF to this directory")]
72    pub output_directory: Option<String>,
73
74    #[clap(
75        alias = "workspace-dir",
76        long,
77        action,
78        help = "The top level directory to be used in the docker invocation."
79    )]
80    pub workspace_directory: Option<String>,
81}
82
83// Implement default args to match clap defaults.
84impl Default for BuildArgs {
85    fn default() -> Self {
86        Self {
87            docker: false,
88            tag: DEFAULT_DOCKER_TAG.to_string(),
89            features: vec![],
90            rustflags: vec![],
91            ignore_rust_version: false,
92            packages: vec![],
93            binaries: vec![],
94            elf_name: None,
95            output_directory: None,
96            locked: false,
97            no_default_features: false,
98            workspace_directory: None,
99        }
100    }
101}
102
103/// Builds the program if the program at the specified path, or one of its dependencies, changes.
104///
105/// This function monitors the program and its dependencies for changes. If any changes are
106/// detected, it triggers a rebuild of the program.
107///
108/// # Arguments
109///
110/// * `path` - A string slice that holds the path to the program directory.
111///
112/// This function is useful for automatically rebuilding the program during development
113/// when changes are made to the source code or its dependencies.
114///
115/// Set the `SP1_SKIP_PROGRAM_BUILD` environment variable to `true` to skip building the program.
116pub fn build_program(path: &str) {
117    build_program_internal(path, None)
118}
119
120/// Builds the program with the given arguments if the program at path, or one of its dependencies,
121/// changes.
122///
123/// # Arguments
124///
125/// * `path` - A string slice that holds the path to the program directory.
126/// * `args` - A [`BuildArgs`] struct that contains various build configuration options.
127///
128/// Set the `SP1_SKIP_PROGRAM_BUILD` environment variable to `true` to skip building the program.
129pub fn build_program_with_args(path: &str, args: BuildArgs) {
130    build_program_internal(path, Some(args))
131}
132
133/// Returns the raw ELF bytes by the zkVM program target name.
134///
135/// Note that this only works when using `sp1_build::build_program` or
136/// `sp1_build::build_program_with_args` in a build script.
137///
138/// By default, the program target name is the same as the program crate name. However, this might
139/// not be the case for non-standard project structures. For example, placing the entrypoint source
140/// file at `src/bin/my_entry.rs` would result in the program target being named `my_entry`, in
141/// which case the invocation should be `include_elf!("my_entry")` instead.
142#[macro_export]
143macro_rules! include_elf {
144    ($arg:tt) => {{
145        include_bytes!(env!(concat!("SP1_ELF_", $arg)))
146    }};
147}