Skip to content

Commit

Permalink
wip: procedural macro compilation
Browse files Browse the repository at this point in the history
commit-id:aebc6424
  • Loading branch information
maciektr committed Feb 5, 2024
1 parent bf9634d commit 19549c3
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 7 deletions.
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 lib::*;
pub use procedural_macro::*;
pub use starknet_contract::*;
pub use test::*;

mod lib;
mod procedural_macro;
mod starknet_contract;
mod test;
48 changes: 48 additions & 0 deletions scarb/src/compiler/compilers/procedural_macro.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use crate::compiler::{CompilationUnit, Compiler};
use crate::core::{TargetKind, Workspace};
use anyhow::{Context, Result};
use cairo_lang_compiler::db::RootDatabase;
use std::path::Path;
use std::process::Command;
use tracing::trace_span;

pub struct ProceduralMacroCompiler;

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

fn compile(
&self,
unit: CompilationUnit,
_db: &mut RootDatabase,
_ws: &Workspace<'_>,
) -> Result<()> {
let main_package = unit.components.first().unwrap().package.clone();
let mut cmd = Self::build_command(main_package.root());
{
let _ = trace_span!("compile_proc_macro").enter();
let status = cmd
.status()
.with_context(|| format!("Failed to execute {:?}", cmd))?;
if !status.success() {
return Err(anyhow::anyhow!(
"Failed to compile procedural macro plugin: {:?}",
cmd
));
}
}
Ok(())
}
}

impl ProceduralMacroCompiler {
fn build_command(cwd: impl AsRef<Path>) -> Command {
let mut cmd = Command::new("cargo");
cmd.current_dir(cwd);
cmd.arg("build");
cmd.arg("--release");
cmd
}
}
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::{
LibCompiler, ProceduralMacroCompiler, StarknetContractCompiler, TestCompiler,
};
use crate::compiler::{CompilationUnit, 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(ProceduralMacroCompiler)).unwrap();
repo
}

Expand Down
17 changes: 14 additions & 3 deletions scarb/src/ops/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use anyhow::{anyhow, Result};
use cairo_lang_compiler::db::RootDatabase;
use cairo_lang_compiler::diagnostics::DiagnosticsError;
use indoc::formatdoc;
use itertools::Itertools;

use scarb_ui::components::Status;
use scarb_ui::HumanDuration;
Expand Down Expand Up @@ -59,11 +60,21 @@ where

let compilation_units = ops::generate_compilation_units(&resolve, ws)?
.into_iter()
.filter(|cu| !opts.exclude_targets.contains(&cu.target().kind))
.filter(|cu| {
opts.include_targets.is_empty() || opts.include_targets.contains(&cu.target().kind)
let is_excluded = opts.exclude_targets.contains(&cu.target().kind);
let is_included =
opts.include_targets.is_empty() || opts.include_targets.contains(&cu.target().kind);
let is_selected = packages.contains(&cu.main_package_id);
let is_cairo_plugin = cu.components.first().unwrap().target.is_cairo_plugin();
is_cairo_plugin || (is_selected && is_included && !is_excluded)
})
.sorted_by_key(|cu| {
if cu.components.first().unwrap().target.is_cairo_plugin() {
0
} else {
1
}
})
.filter(|cu| packages.contains(&cu.main_package_id))
.collect::<Vec<_>>();

for unit in compilation_units {
Expand Down
35 changes: 32 additions & 3 deletions scarb/src/ops/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,24 @@ pub fn generate_compilation_units(
let mut units = Vec::with_capacity(ws.members().size_hint().0);
for member in ws.members() {
units.extend(if member.is_cairo_plugin() {
generate_cairo_plugin_compilation_units()?
generate_cairo_plugin_compilation_units(&member, ws)?
} else {
generate_cairo_compilation_units(&member, resolve, ws)?
});
}

let cairo_plugins = units
.iter()
.flat_map(|unit| unit.cairo_plugins.clone())
.filter(|plugin| !plugin.builtin)
.map(|plugin| plugin.package.clone())
.unique_by(|plugin| plugin.id)
.collect_vec();

for plugin in cairo_plugins {
units.extend(generate_cairo_plugin_compilation_units(&plugin, ws)?);
}

assert!(
units.iter().map(CompilationUnit::id).all_unique(),
"All generated compilation units must have unique IDs."
Expand Down Expand Up @@ -402,6 +414,23 @@ fn check_cairo_version_compatibility(packages: &[Package], ws: &Workspace<'_>) -
Ok(())
}

fn generate_cairo_plugin_compilation_units() -> Result<Vec<CompilationUnit>> {
bail!("compiling Cairo plugin packages is not possible yet")
fn generate_cairo_plugin_compilation_units(
member: &Package,
ws: &Workspace<'_>,
) -> Result<Vec<CompilationUnit>> {
Ok(vec![CompilationUnit {
main_package_id: member.id,
components: vec![CompilationUnitComponent {
package: member.clone(),
target: member
.fetch_target(&TargetKind::CAIRO_PLUGIN)
.cloned()
// Safe to unwrap, as member.is_cairo_plugin() has been ensured before.
.expect("main component of procedural macro must define `cairo-plugin` target"),
}],
cairo_plugins: Vec::new(),
profile: ws.current_profile()?,
compiler_config: member.manifest.compiler_config.clone(),
cfg_set: Default::default(),
}])
}
1 change: 1 addition & 0 deletions scarb/tests/build_cairo_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use scarb_test_support::command::Scarb;
use scarb_test_support::project_builder::ProjectBuilder;

#[test]
#[ignore = "TODO(maciektr): Remove when proc-macros are implemented."]
fn compile_cairo_plugin() {
let t = TempDir::new().unwrap();
ProjectBuilder::start()
Expand Down

0 comments on commit 19549c3

Please sign in to comment.