Skip to content

Commit

Permalink
feat: compile executable (#1840)
Browse files Browse the repository at this point in the history
commit-id:4510e5a4
  • Loading branch information
FroyaTheHen authored Dec 17, 2024
1 parent e88244b commit f23fe58
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 12 deletions.
47 changes: 47 additions & 0 deletions scarb/src/compiler/compilers/executable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::compiler::helpers::write_json;
use crate::compiler::helpers::{build_compiler_config, collect_main_crate_ids};
use crate::compiler::{CairoCompilationUnit, CompilationUnitAttributes, Compiler};
use crate::core::{TargetKind, Workspace};
use anyhow::Result;
use cairo_lang_compiler::db::RootDatabase;
use cairo_lang_executable::executable::Executable;
use tracing::trace_span;

pub struct ExecutableCompiler;

impl Compiler for ExecutableCompiler {
fn target_kind(&self) -> TargetKind {
TargetKind::EXECUTABLE.clone()
}

fn compile(
&self,
unit: CairoCompilationUnit,
db: &mut RootDatabase,
ws: &Workspace<'_>,
) -> Result<()> {
let target_dir = unit.target_dir(ws);
let main_crate_ids = collect_main_crate_ids(&unit, db);
let compiler_config = build_compiler_config(db, &unit, &main_crate_ids, ws);
let span = trace_span!("compile_executable");
let executable = {
let _guard = span.enter();
Executable::new(
cairo_lang_executable::compile::compile_executable_in_prepared_db(
db,
None,
main_crate_ids,
compiler_config.diagnostics_reporter,
)?,
)
};

write_json(
format!("{}.executable.json", unit.main_component().target_name()).as_str(),
"output file",
&target_dir,
ws,
&executable,
)
}
}
9 changes: 6 additions & 3 deletions scarb/src/compiler/compilers/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ impl Compiler for LibCompiler {

validate_compiler_config(db, &compiler_config, &unit, ws);

let span = trace_span!("compile_sierra");
let sierra_program: VersionedProgram = {
let _ = trace_span!("compile_sierra").enter();
let _guard = span.enter();
let program_artifact = cairo_lang_compiler::compile_prepared_db_program_artifact(
db,
main_crate_ids,
Expand Down Expand Up @@ -101,8 +102,9 @@ impl Compiler for LibCompiler {
if props.casm {
let program = sierra_program.into_v1().unwrap().program;

let span = trace_span!("casm_calc_metadata");
let metadata = {
let _ = trace_span!("casm_calc_metadata").enter();
let _guard = span.enter();

if unit.compiler_config.enable_gas {
debug!("calculating Sierra variables");
Expand All @@ -114,8 +116,9 @@ impl Compiler for LibCompiler {
.context("failed calculating Sierra variables")?
};

let span = trace_span!("compile_casm");
let cairo_program = {
let _ = trace_span!("compile_casm").enter();
let _guard = span.enter();
let sierra_to_casm = SierraToCasmConfig {
gas_usage_check: unit.compiler_config.enable_gas,
max_bytecode_size: usize::MAX,
Expand Down
2 changes: 2 additions & 0 deletions scarb/src/compiler/compilers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
pub use executable::*;
pub use lib::*;
pub use starknet_contract::*;
pub use test::*;

mod executable;
mod lib;
mod starknet_contract;
mod test;
13 changes: 9 additions & 4 deletions scarb/src/compiler/compilers/starknet_contract/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ impl Compiler for StarknetContractCompiler {
check_allowed_libfuncs(&props, &contracts, &classes, db, &unit, ws)?;

let casm_classes: Vec<Option<CasmContractClass>> = if props.casm {
let _ = trace_span!("compile_sierra").enter();
let span = trace_span!("compile_sierra");
let _guard = span.enter();

zip(&contracts, &classes)
.map(|(decl, class)| -> Result<_> {
let contract_name = decl.submodule_id.name(db.upcast_mut());
Expand Down Expand Up @@ -159,8 +161,9 @@ pub fn get_compiled_contracts(
.collect::<Vec<_>>();
trace!(contracts = ?contract_paths);

let span = trace_span!("compile_starknet");
let classes = {
let _ = trace_span!("compile_starknet").enter();
let _guard = span.enter();
compile_prepared_db(db, &contracts.iter().collect::<Vec<_>>(), compiler_config)?
};
Ok(CompiledContracts {
Expand All @@ -177,14 +180,16 @@ pub fn find_project_contracts(
main_crate_ids: Vec<CrateId>,
external_contracts: Option<Vec<ContractSelector>>,
) -> Result<Vec<ContractDeclaration>> {
let span = trace_span!("find_internal_contracts");
let internal_contracts = {
let _ = trace_span!("find_internal_contracts").enter();
let _guard = span.enter();
find_contracts(db, &main_crate_ids)
};

let span = trace_span!("find_external_contracts");
let external_contracts: Vec<ContractDeclaration> =
if let Some(external_contracts) = external_contracts {
let _ = trace_span!("find_external_contracts").enter();
let _guard = span.enter();
debug!("external contracts selectors: {:?}", external_contracts);

let crate_ids = external_contracts
Expand Down
7 changes: 4 additions & 3 deletions scarb/src/compiler/compilers/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ impl Compiler for TestCompiler {
let diagnostics_reporter =
build_compiler_config(db, &unit, &test_crate_ids, ws).diagnostics_reporter;

let span = trace_span!("compile_test");
let test_compilation = {
let _ = trace_span!("compile_test").enter();
let _guard = span.enter();
let config = TestsCompilationConfig {
starknet,
add_statements_functions: unit
Expand All @@ -79,9 +80,9 @@ impl Compiler for TestCompiler {
compile_test_prepared_db(db, config, test_crate_ids.clone(), diagnostics_reporter)?
};

let span = trace_span!("serialize_test");
{
let _ = trace_span!("serialize_test").enter();

let _guard = span.enter();
let sierra_program: VersionedProgram = test_compilation.sierra_program.clone().into();
let file_name = format!("{}.test.sierra.json", unit.main_component().target_name());
write_json(&file_name, "output file", &target_dir, ws, &sierra_program)?;
Expand Down
3 changes: 2 additions & 1 deletion scarb/src/compiler/plugin/proc_macro/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,9 @@ fn run_cargo(action: CargoAction, package: &Package, ws: &Workspace<'_>) -> Resu
.to_path_buf(),
config: ws.config(),
};
let span = trace_span!("proc_macro");
{
let _ = trace_span!("proc_macro").enter();
let _guard = span.enter();
exec(&mut cmd.into(), ws.config())?;
}
Ok(())
Expand Down
5 changes: 4 additions & 1 deletion scarb/src/compiler/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use cairo_lang_compiler::db::RootDatabase;
use itertools::Itertools;
use smol_str::SmolStr;

use crate::compiler::compilers::{LibCompiler, StarknetContractCompiler, TestCompiler};
use crate::compiler::compilers::{
ExecutableCompiler, LibCompiler, StarknetContractCompiler, TestCompiler,
};
use crate::compiler::{CairoCompilationUnit, CompilationUnitAttributes, Compiler};
use crate::core::Workspace;

Expand All @@ -27,6 +29,7 @@ impl CompilerRepository {
repo.add(Box::new(LibCompiler)).unwrap();
repo.add(Box::new(StarknetContractCompiler)).unwrap();
repo.add(Box::new(TestCompiler)).unwrap();
repo.add(Box::new(ExecutableCompiler)).unwrap();
repo
}

Expand Down
1 change: 1 addition & 0 deletions scarb/src/core/manifest/target_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ impl TargetKind {
pub const LIB: Self = TargetKind(SmolStr::new_inline("lib"));
pub const TEST: Self = TargetKind(SmolStr::new_inline("test"));
pub const STARKNET_CONTRACT: Self = TargetKind(SmolStr::new_inline("starknet-contract"));
pub const EXECUTABLE: Self = TargetKind(SmolStr::new_inline("executable"));

/// Constructs and validates new [`TargetKind`].
///
Expand Down
29 changes: 29 additions & 0 deletions scarb/tests/build_targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1090,3 +1090,32 @@ fn transitive_dev_deps_not_available() {
error: could not check `hello` due to previous error
"#});
}

#[test]
fn test_executable_compiler_creates_output_files() {
let t = TempDir::new().unwrap();
ProjectBuilder::start()
.name("executable_test")
.dep_cairo_test()
.dep_starknet()
.dep_cairo_execute()
.manifest_extra(indoc! {r#"
[[target.executable]]
"#})
.lib_cairo(indoc! {r#"
#[executable]
fn main() -> felt252 {
42
}
"#})
.build(&t);

Scarb::quick_snapbox()
.arg("build")
.current_dir(&t)
.assert()
.success();

t.child("target/dev/executable_test.executable.json")
.assert(predicates::path::exists());
}

0 comments on commit f23fe58

Please sign in to comment.