openvm_benchmarks_utils/
lib.rs

1use std::{
2    fs::read,
3    path::{Path, PathBuf},
4};
5
6use cargo_metadata::Package;
7use eyre::Result;
8use openvm_build::{build_guest_package, get_package, guest_methods, GuestOptions};
9use openvm_transpiler::{elf::Elf, openvm_platform::memory::MEM_SIZE};
10use tempfile::tempdir;
11
12pub fn get_programs_dir() -> PathBuf {
13    PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../guest")
14}
15
16pub fn build_elf(manifest_dir: &PathBuf, profile: impl ToString) -> Result<Elf> {
17    let pkg = get_package(manifest_dir);
18    build_elf_with_path(&pkg, profile, None)
19}
20
21pub fn build_elf_with_path(
22    pkg: &Package,
23    profile: impl ToString,
24    elf_path: Option<&PathBuf>,
25) -> Result<Elf> {
26    // Use a temporary directory for the build
27    let temp_dir = tempdir()?;
28    let target_dir = temp_dir.path();
29
30    // Build guest with default features
31    let guest_opts = GuestOptions::default()
32        .with_target_dir(target_dir)
33        .with_profile(profile.to_string());
34
35    if let Err(Some(code)) = build_guest_package(pkg, &guest_opts, None, &None) {
36        std::process::exit(code);
37    }
38
39    // Assumes the package has a single target binary
40    let temp_elf_path = guest_methods(pkg, target_dir, &guest_opts.features, &guest_opts.profile)
41        .pop()
42        .unwrap();
43
44    // If an elf_path is provided, copy the built ELF to that location
45    if let Some(dest_path) = elf_path {
46        // Create parent directories if they don't exist
47        if let Some(parent) = dest_path.parent() {
48            if !parent.exists() {
49                std::fs::create_dir_all(parent)?;
50            }
51        }
52
53        // Copy the built ELF to the destination
54        std::fs::copy(&temp_elf_path, dest_path)?;
55    }
56
57    read_elf_file(&temp_elf_path)
58}
59
60pub fn get_elf_path(manifest_dir: &PathBuf) -> PathBuf {
61    let pkg = get_package(manifest_dir);
62    get_elf_path_with_pkg(manifest_dir, &pkg)
63}
64
65pub fn get_elf_path_with_pkg(manifest_dir: &Path, pkg: &Package) -> PathBuf {
66    let elf_file_name = format!("{}.elf", &pkg.name);
67    manifest_dir.join("elf").join(elf_file_name)
68}
69
70pub fn read_elf_file(elf_path: &PathBuf) -> Result<Elf> {
71    let data = read(elf_path)?;
72    Elf::decode(&data, MEM_SIZE as u32)
73}