Skip to main content

elf_magic/
lib.rs

1mod builder;
2mod codegen;
3pub mod config;
4mod error;
5mod programs;
6mod workspace;
7
8use std::{env, path::PathBuf};
9
10use crate::{
11    config::Config,
12    error::Error,
13    programs::{deduplicate_programs, BuildResults, SolanaProgram},
14};
15
16#[deprecated(note = "use build() instead")]
17pub fn generate() -> Result<BuildResults, Error> {
18    build()
19}
20
21/// Generate Rust bindings for Solana programs
22pub fn build() -> Result<BuildResults, Error> {
23    let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR")
24        .map(PathBuf::from)
25        .map_err(|e| Error::WorkspaceDiscovery(format!("CARGO_MANIFEST_DIR not set: {}", e)))?;
26
27    // Clean pipeline: load → discover → build → generate → save
28    let config = Config::load(&cargo_manifest_dir)?;
29    let workspaces = workspace::load_workspaces(&cargo_manifest_dir, &config)?;
30    let discovered_programs = workspaces
31        .iter()
32        .map(|w| w.discover_programs())
33        .collect::<Result<Vec<_>, _>>()?;
34
35    // Extract and deduplicate included programs
36    let included_programs: Vec<SolanaProgram> = discovered_programs
37        .iter()
38        .flat_map(|w| w.included.iter().cloned())
39        .collect();
40    let included_programs = deduplicate_programs(included_programs);
41
42    // Build, generate, and save
43    let build_result = builder::build_programs(&included_programs);
44    let code = codegen::generate(&build_result)?;
45    codegen::save(&cargo_manifest_dir, &code)?;
46
47    builder::enable_incremental_builds(&cargo_manifest_dir, &included_programs)?;
48
49    Ok(BuildResults::new(
50        config.mode_name().to_string(),
51        discovered_programs,
52    ))
53}