mirror of
https://github.com/eth-act/ere.git
synced 2026-02-19 11:54:42 -05:00
feat: update riscv32 to riscv64 for sp1
This commit is contained in:
@@ -3,5 +3,8 @@ mod rust;
|
||||
|
||||
pub use {
|
||||
error::CommonError,
|
||||
rust::{CargoBuildCmd, cargo_metadata, rustc_path, rustup_add_components, rustup_add_rust_src},
|
||||
rust::{
|
||||
CargoBuildCmd, RustTarget, cargo_metadata, rustc_path, rustup_add_components,
|
||||
rustup_add_rust_src,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -10,6 +10,36 @@ use tempfile::tempdir;
|
||||
|
||||
const CARGO_ENCODED_RUSTFLAGS_SEPARATOR: &str = "\x1f";
|
||||
|
||||
/// Target specification for cargo build.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum RustTarget {
|
||||
/// Built-in target name (e.g., "riscv64im-unknown-none-elf").
|
||||
Name(&'static str),
|
||||
/// Custom target specification JSON content.
|
||||
SpecJson {
|
||||
/// Target name (e.g., "riscv64ima-unknown-none-elf").
|
||||
name: &'static str,
|
||||
/// Raw JSON content of the target specification.
|
||||
json: &'static str,
|
||||
},
|
||||
}
|
||||
|
||||
impl RustTarget {
|
||||
/// Returns the target name.
|
||||
pub const fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Name(name) => name,
|
||||
Self::SpecJson { name, .. } => name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'static str> for RustTarget {
|
||||
fn from(name: &'static str) -> Self {
|
||||
Self::Name(name)
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder for configuring `cargo build` invocation.
|
||||
#[derive(Clone)]
|
||||
pub struct CargoBuildCmd {
|
||||
@@ -73,12 +103,12 @@ impl CargoBuildCmd {
|
||||
self
|
||||
}
|
||||
|
||||
/// Takes the path to the manifest directory and the target triple, then
|
||||
/// Takes the path to the manifest directory and the target, then
|
||||
/// runs configured `cargo build` and returns built ELF.
|
||||
pub fn exec(
|
||||
&self,
|
||||
manifest_dir: impl AsRef<Path>,
|
||||
target: impl AsRef<str>,
|
||||
target: impl Into<RustTarget>,
|
||||
) -> Result<Vec<u8>, CommonError> {
|
||||
let metadata = cargo_metadata(manifest_dir.as_ref())?;
|
||||
let package = metadata.root_package().unwrap();
|
||||
@@ -103,6 +133,18 @@ impl CargoBuildCmd {
|
||||
})?;
|
||||
}
|
||||
|
||||
let target = target.into();
|
||||
let target_arg = match target {
|
||||
RustTarget::Name(name) => name.to_string(),
|
||||
RustTarget::SpecJson { name, json } => {
|
||||
let json_name = format!("{name}.json");
|
||||
let json_path = tempdir.path().join(&json_name);
|
||||
fs::write(&json_path, json.as_bytes())
|
||||
.map_err(|err| CommonError::write_file(json_name, &json_path, err))?;
|
||||
json_path.to_string_lossy().to_string()
|
||||
}
|
||||
};
|
||||
|
||||
let encoded_rustflags = iter::empty()
|
||||
.chain(self.rustflags.iter().cloned())
|
||||
.chain(
|
||||
@@ -120,7 +162,7 @@ impl CargoBuildCmd {
|
||||
.chain(["build".into()])
|
||||
.chain(self.build_options.iter().cloned())
|
||||
.chain(["--profile".into(), self.profile.clone()])
|
||||
.chain(["--target".into(), target.as_ref().into()])
|
||||
.chain(["--target".into(), target_arg])
|
||||
.chain(["--manifest-path".into(), package.manifest_path.to_string()]);
|
||||
|
||||
let mut cmd = Command::new("cargo");
|
||||
@@ -136,7 +178,7 @@ impl CargoBuildCmd {
|
||||
|
||||
let elf_path = metadata
|
||||
.target_directory
|
||||
.join(target.as_ref())
|
||||
.join(target.name())
|
||||
.join(&self.profile)
|
||||
.join(&package.name);
|
||||
let elf =
|
||||
|
||||
@@ -228,11 +228,11 @@ fn compile(guest_dir: PathBuf, compiler_kind: CompilerKind) -> CompilationResult
|
||||
use ere_sp1::compiler::*;
|
||||
match compiler_kind {
|
||||
CompilerKind::Rust => {
|
||||
let program = RustRv32ima.compile(&guest_dir)?;
|
||||
let program = RustRv64ima.compile(&guest_dir)?;
|
||||
(Some(program.elf().to_vec()), None, program)
|
||||
}
|
||||
CompilerKind::RustCustomized => {
|
||||
let program = RustRv32imaCustomized.compile(&guest_dir)?;
|
||||
let program = RustRv64imaCustomized.compile(&guest_dir)?;
|
||||
(Some(program.elf().to_vec()), None, program)
|
||||
}
|
||||
_ => bail!(unsupported_compiler_kind_err(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mod error;
|
||||
mod rust_rv32ima;
|
||||
mod rust_rv32ima_customized;
|
||||
mod rust_rv64ima;
|
||||
mod rust_rv64ima_customized;
|
||||
|
||||
pub use error::Error;
|
||||
pub use rust_rv32ima::RustRv32ima;
|
||||
pub use rust_rv32ima_customized::RustRv32imaCustomized;
|
||||
pub use rust_rv64ima::RustRv64ima;
|
||||
pub use rust_rv64ima_customized::RustRv64imaCustomized;
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
use crate::{compiler::Error, program::SP1Program};
|
||||
use ere_compile_utils::CargoBuildCmd;
|
||||
use ere_compile_utils::{CargoBuildCmd, RustTarget};
|
||||
use ere_zkvm_interface::compiler::Compiler;
|
||||
use std::{env, path::Path};
|
||||
|
||||
const TARGET_TRIPLE: &str = "riscv32ima-unknown-none-elf";
|
||||
/// Target spec modified from `riscv64im-unknown-none-elf` with patch `atomic-cas = true`.
|
||||
///
|
||||
/// To reproduce:
|
||||
///
|
||||
/// ```bash
|
||||
/// rustc +nightly -Z unstable-options --print target-spec-json --target riscv64im-unknown-none-elf \
|
||||
/// | jq '.["atomic-cas"] = true' \
|
||||
/// > ./crates/zkvm/sp1/src/compiler/rust_rv64ima/riscv64ima-unknown-none-elf.json
|
||||
/// ```
|
||||
const TARGET: RustTarget = RustTarget::SpecJson {
|
||||
name: "riscv64ima-unknown-none-elf",
|
||||
json: include_str!("./rust_rv64ima/riscv64ima-unknown-none-elf.json"),
|
||||
};
|
||||
|
||||
/// According to https://github.com/succinctlabs/sp1/blob/v6.0.0/crates/build/src/command/utils.rs#L49.
|
||||
const RUSTFLAGS: &[&str] = &[
|
||||
"-C",
|
||||
@@ -24,12 +37,14 @@ const RUSTFLAGS: &[&str] = &[
|
||||
const CARGO_BUILD_OPTIONS: &[&str] = &[
|
||||
// For bare metal we have to build core and alloc
|
||||
"-Zbuild-std=core,alloc",
|
||||
// For using json target spec
|
||||
"-Zjson-target-spec",
|
||||
];
|
||||
|
||||
/// Compiler for Rust guest program to RV32IMA architecture.
|
||||
pub struct RustRv32ima;
|
||||
/// Compiler for Rust guest program to RV64IMA architecture.
|
||||
pub struct RustRv64ima;
|
||||
|
||||
impl Compiler for RustRv32ima {
|
||||
impl Compiler for RustRv64ima {
|
||||
type Error = Error;
|
||||
|
||||
type Program = SP1Program;
|
||||
@@ -40,14 +55,14 @@ impl Compiler for RustRv32ima {
|
||||
.toolchain(toolchain)
|
||||
.build_options(CARGO_BUILD_OPTIONS)
|
||||
.rustflags(RUSTFLAGS)
|
||||
.exec(guest_directory, TARGET_TRIPLE)?;
|
||||
.exec(guest_directory, TARGET)?;
|
||||
Ok(SP1Program { elf })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{compiler::RustRv32ima, zkvm::EreSP1};
|
||||
use crate::{compiler::RustRv64ima, zkvm::EreSP1};
|
||||
use ere_test_utils::host::testing_guest_directory;
|
||||
use ere_zkvm_interface::{
|
||||
Input,
|
||||
@@ -58,14 +73,14 @@ mod tests {
|
||||
#[test]
|
||||
fn test_compile() {
|
||||
let guest_directory = testing_guest_directory("sp1", "stock_nightly_no_std");
|
||||
let program = RustRv32ima.compile(&guest_directory).unwrap();
|
||||
let program = RustRv64ima.compile(&guest_directory).unwrap();
|
||||
assert!(!program.elf().is_empty(), "ELF bytes should not be empty.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_execute() {
|
||||
let guest_directory = testing_guest_directory("sp1", "stock_nightly_no_std");
|
||||
let program = RustRv32ima.compile(&guest_directory).unwrap();
|
||||
let program = RustRv64ima.compile(&guest_directory).unwrap();
|
||||
let zkvm = EreSP1::new(program, ProverResource::Cpu).unwrap();
|
||||
|
||||
zkvm.execute(&Input::new()).unwrap();
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"arch": "riscv64",
|
||||
"atomic-cas": true,
|
||||
"code-model": "medium",
|
||||
"cpu": "generic-rv64",
|
||||
"crt-objects-fallback": "false",
|
||||
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||
"eh-frame-header": false,
|
||||
"emit-debug-gdb-scripts": false,
|
||||
"features": "+m,+forced-atomics",
|
||||
"linker": "rust-lld",
|
||||
"linker-flavor": "gnu-lld",
|
||||
"llvm-abiname": "lp64",
|
||||
"llvm-target": "riscv64",
|
||||
"max-atomic-width": 64,
|
||||
"metadata": {
|
||||
"description": "Bare RISC-V (RV64IM ISA)",
|
||||
"host_tools": false,
|
||||
"std": false,
|
||||
"tier": 3
|
||||
},
|
||||
"panic-strategy": "abort",
|
||||
"relocation-model": "static",
|
||||
"target-pointer-width": 64
|
||||
}
|
||||
@@ -5,11 +5,11 @@ use std::{fs, path::Path, process::Command};
|
||||
use tempfile::tempdir;
|
||||
use tracing::info;
|
||||
|
||||
/// Compiler for Rust guest program to RV32IMA architecture, using customized
|
||||
/// Compiler for Rust guest program to RV64IMA architecture, using customized
|
||||
/// Rust toolchain of Succinct.
|
||||
pub struct RustRv32imaCustomized;
|
||||
pub struct RustRv64imaCustomized;
|
||||
|
||||
impl Compiler for RustRv32imaCustomized {
|
||||
impl Compiler for RustRv64imaCustomized {
|
||||
type Error = Error;
|
||||
|
||||
type Program = SP1Program;
|
||||
@@ -56,14 +56,14 @@ impl Compiler for RustRv32imaCustomized {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::compiler::RustRv32imaCustomized;
|
||||
use crate::compiler::RustRv64imaCustomized;
|
||||
use ere_test_utils::host::testing_guest_directory;
|
||||
use ere_zkvm_interface::compiler::Compiler;
|
||||
|
||||
#[test]
|
||||
fn test_compile() {
|
||||
let guest_directory = testing_guest_directory("sp1", "basic");
|
||||
let program = RustRv32imaCustomized.compile(&guest_directory).unwrap();
|
||||
let program = RustRv64imaCustomized.compile(&guest_directory).unwrap();
|
||||
assert!(!program.elf().is_empty(), "ELF bytes should not be empty.");
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ fn input_to_stdin(input: &Input) -> Result<SP1Stdin, Error> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{compiler::RustRv32imaCustomized, program::SP1Program, zkvm::EreSP1};
|
||||
use crate::{compiler::RustRv64imaCustomized, program::SP1Program, zkvm::EreSP1};
|
||||
use ere_test_utils::{
|
||||
host::{TestCase, run_zkvm_execute, run_zkvm_prove, testing_guest_directory},
|
||||
io::serde::bincode::BincodeLegacy,
|
||||
@@ -148,7 +148,7 @@ mod tests {
|
||||
static PROGRAM: OnceLock<SP1Program> = OnceLock::new();
|
||||
PROGRAM
|
||||
.get_or_init(|| {
|
||||
RustRv32imaCustomized
|
||||
RustRv64imaCustomized
|
||||
.compile(&testing_guest_directory("sp1", "basic"))
|
||||
.unwrap()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user