-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Support cairo project * Update README.md
- Loading branch information
Showing
10 changed files
with
223 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
use anyhow::{anyhow, bail, Context, Result}; | ||
use std::env; | ||
use std::process; | ||
use std::sync::Arc; | ||
|
||
use super::ProgramCompiled; | ||
use crate::compilation::utils::felt252_serde::sierra_from_felt252s; | ||
use crate::compilation::utils::replacer::SierraProgramDebugReplacer; | ||
use crate::core::core_unit::CoreOpts; | ||
use cairo_lang_compiler::db::RootDatabase; | ||
use cairo_lang_compiler::project::{setup_project, ProjectConfig, ProjectConfigContent}; | ||
use cairo_lang_compiler::CompilerConfig; | ||
use cairo_lang_filesystem::ids::Directory; | ||
use cairo_lang_sierra_generator::db::SierraGenGroup; | ||
use cairo_lang_sierra_generator::replace_ids::{replace_sierra_ids_in_program, SierraIdReplacer}; | ||
use cairo_lang_starknet::abi::{AbiBuilder, Contract}; | ||
use cairo_lang_starknet::compiler_version::current_compiler_version_id; | ||
use cairo_lang_starknet::contract::find_contracts; | ||
use cairo_lang_starknet::contract_class::ContractClass; | ||
use cairo_lang_starknet::inline_macros::selector::SelectorMacro; | ||
use cairo_lang_starknet::plugin::StarkNetPlugin; | ||
use cairo_lang_utils::ordered_hash_map::OrderedHashMap; | ||
|
||
pub fn compile(opts: CoreOpts) -> Result<Vec<ProgramCompiled>> { | ||
let output = process::Command::new("starknet-compile") | ||
.arg("--version") | ||
.output(); | ||
|
||
if let Ok(result) = output { | ||
if result.status.success() { | ||
println!( | ||
"Found local cairo installation {}", | ||
String::from_utf8(result.stdout)? | ||
); | ||
|
||
return local_compiler(opts); | ||
} | ||
} | ||
|
||
println!( | ||
"Local cairo installation not found. Compiling with starknet-compile {}", | ||
current_compiler_version_id() | ||
); | ||
|
||
// corelib cli option has priority over the environment variable | ||
let corelib = match opts.corelib { | ||
Some(ref p) => p.clone(), | ||
None => { | ||
match env::var("CORELIB_PATH") { | ||
Ok(p) => p.into(), | ||
Err(e) => bail!("{e}. The Corelib path must be specified either with the CORELIB_PATH environment variable or the --corelib cli option"), | ||
} | ||
} | ||
}; | ||
|
||
// Needed to pass the correct corelib path | ||
let project_config = ProjectConfig { | ||
corelib: Some(Directory::Real(corelib)), | ||
base_path: "".into(), | ||
content: ProjectConfigContent { | ||
crate_roots: OrderedHashMap::default(), | ||
}, | ||
}; | ||
|
||
let mut db = RootDatabase::builder() | ||
.with_project_config(project_config) | ||
.with_macro_plugin(Arc::new(StarkNetPlugin::default())) | ||
.with_inline_macro_plugin(SelectorMacro::NAME, Arc::new(SelectorMacro)) | ||
.build()?; | ||
|
||
let mut compiler_config = CompilerConfig::default(); | ||
|
||
let main_crate_ids = setup_project(&mut db, &opts.target)?; | ||
compiler_config.diagnostics_reporter.ensure(&db)?; | ||
|
||
let contracts = find_contracts(&db, &main_crate_ids); | ||
if contracts.is_empty() { | ||
bail!("Contract not found."); | ||
} | ||
|
||
let mut abi: Contract = Default::default(); | ||
contracts.iter().for_each(|c| { | ||
abi.items.extend( | ||
AbiBuilder::submodule_as_contract_abi(&db, c.submodule_id) | ||
.expect("Error when getting the ABI.") | ||
.items, | ||
) | ||
}); | ||
|
||
let sierra = db | ||
.get_sierra_program(main_crate_ids) | ||
.ok() | ||
.context("Compilation failed without any diagnostics.")?; | ||
let sierra = replace_sierra_ids_in_program(&db, &sierra); | ||
|
||
Ok(vec![ProgramCompiled { sierra, abi }]) | ||
} | ||
|
||
fn local_compiler(opts: CoreOpts) -> Result<Vec<ProgramCompiled>> { | ||
let output = if let Some(contract_path) = opts.contract_path { | ||
process::Command::new("starknet-compile") | ||
.arg(opts.target) | ||
.arg("--contract-path") | ||
.arg(contract_path) | ||
.arg("--replace-ids") | ||
.output()? | ||
} else { | ||
process::Command::new("starknet-compile") | ||
.arg(opts.target) | ||
.arg("--replace-ids") | ||
.output()? | ||
}; | ||
|
||
if !output.status.success() { | ||
bail!(anyhow!( | ||
"starknet-compile failed to compile.\n Status {}\n {}", | ||
output.status, | ||
String::from_utf8(output.stderr)? | ||
)); | ||
} | ||
|
||
let contract_class: ContractClass = | ||
serde_json::from_str(&String::from_utf8(output.stdout)?).unwrap(); | ||
|
||
// We don't have to check the existence because we ran the compiler with --replace-ids | ||
let debug_info = contract_class.sierra_program_debug_info.unwrap(); | ||
|
||
let sierra = sierra_from_felt252s(&contract_class.sierra_program) | ||
.unwrap() | ||
.2; | ||
let sierra = SierraProgramDebugReplacer { debug_info }.apply(&sierra); | ||
|
||
Ok(vec![ProgramCompiled { | ||
sierra, | ||
abi: contract_class.abi.unwrap(), | ||
}]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
pub mod felt252_serde; | ||
mod felt252_vec_compression; | ||
pub mod replacer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use cairo_lang_sierra::debug_info::DebugInfo; | ||
use cairo_lang_sierra_generator::replace_ids::SierraIdReplacer; | ||
|
||
pub struct SierraProgramDebugReplacer { | ||
pub debug_info: DebugInfo, | ||
} | ||
|
||
impl SierraIdReplacer for SierraProgramDebugReplacer { | ||
fn replace_libfunc_id( | ||
&self, | ||
id: &cairo_lang_sierra::ids::ConcreteLibfuncId, | ||
) -> cairo_lang_sierra::ids::ConcreteLibfuncId { | ||
let func_name = self | ||
.debug_info | ||
.libfunc_names | ||
.get(id) | ||
.expect("No libfunc in debug info"); | ||
cairo_lang_sierra::ids::ConcreteLibfuncId { | ||
id: id.id, | ||
debug_name: Some(func_name.clone()), | ||
} | ||
} | ||
|
||
fn replace_type_id( | ||
&self, | ||
id: &cairo_lang_sierra::ids::ConcreteTypeId, | ||
) -> cairo_lang_sierra::ids::ConcreteTypeId { | ||
let type_name = self | ||
.debug_info | ||
.type_names | ||
.get(id) | ||
.expect("No typeid in debug info"); | ||
cairo_lang_sierra::ids::ConcreteTypeId { | ||
id: id.id, | ||
debug_name: Some(type_name.clone()), | ||
} | ||
} | ||
|
||
fn replace_function_id( | ||
&self, | ||
sierra_id: &cairo_lang_sierra::ids::FunctionId, | ||
) -> cairo_lang_sierra::ids::FunctionId { | ||
let function_name = self | ||
.debug_info | ||
.user_func_names | ||
.get(sierra_id) | ||
.expect("No funcid in debug info"); | ||
cairo_lang_sierra::ids::FunctionId { | ||
id: sierra_id.id, | ||
debug_name: Some(function_name.clone()), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters