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, GenerationResult, SolanaProgram},
14};
15
16/// Generate Rust bindings for Solana programs
17pub fn generate() -> Result<GenerationResult, Error> {
18    let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR")
19        .map(PathBuf::from)
20        .map_err(|e| Error::WorkspaceDiscovery(format!("CARGO_MANIFEST_DIR not set: {}", e)))?;
21
22    // Clean pipeline: load → discover → build → generate → save
23    let config = Config::load(&cargo_manifest_dir)?;
24    let workspaces = workspace::load_workspaces(&cargo_manifest_dir, &config)?;
25    let discovered_programs = workspaces
26        .iter()
27        .map(|w| w.discover_programs())
28        .collect::<Result<Vec<_>, _>>()?;
29
30    // Extract and deduplicate included programs
31    let included_programs: Vec<SolanaProgram> = discovered_programs
32        .iter()
33        .flat_map(|w| w.included.iter().cloned())
34        .collect();
35    let included_programs = deduplicate_programs(included_programs);
36
37    // Build, generate, and save
38    let build_result = builder::build_programs(&included_programs);
39    let code = codegen::generate(&build_result)?;
40    codegen::save(&cargo_manifest_dir, &code)?;
41
42    builder::enable_incremental_builds(&cargo_manifest_dir, &included_programs)?;
43
44    Ok(GenerationResult::new(
45        config.mode_name().to_string(),
46        discovered_programs,
47    ))
48}