From e06ec35420da29d8859bb6b98eb9fc4b2eb39e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 19 Apr 2024 12:26:10 -0300 Subject: [PATCH 1/4] Add path to build command --- crates/concrete_driver/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/concrete_driver/src/lib.rs b/crates/concrete_driver/src/lib.rs index 8db5401..87e3b9f 100644 --- a/crates/concrete_driver/src/lib.rs +++ b/crates/concrete_driver/src/lib.rs @@ -52,6 +52,9 @@ enum Commands { }, /// Build a project Build { + #[arg(required = false)] + path: Option, + /// Build for release with all optimizations. #[arg(short, long, default_value_t = false)] release: bool, @@ -247,7 +250,11 @@ mod {} {{ println!(" {} library `{}` package", "Created".green(), name); } } - Commands::Build { release, profile } => { + Commands::Build { + path, + release, + profile, + } => { build_command(profile, release)?; } Commands::Run { From 670722115408524412991c65f9693db71ba22027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 19 Apr 2024 14:40:00 -0300 Subject: [PATCH 2/4] Include single file mode to build command and reuse --- crates/concrete_driver/src/lib.rs | 309 +++++++++++++++--------------- 1 file changed, 154 insertions(+), 155 deletions(-) diff --git a/crates/concrete_driver/src/lib.rs b/crates/concrete_driver/src/lib.rs index 87e3b9f..4feeafb 100644 --- a/crates/concrete_driver/src/lib.rs +++ b/crates/concrete_driver/src/lib.rs @@ -255,67 +255,14 @@ mod {} {{ release, profile, } => { - build_command(profile, release)?; + handle_build(path, release, profile)?; } Commands::Run { path, release, profile, } => { - let output = match path { - Some(input) => { - let input_stem = input - .file_stem() - .context("could not get file stem")? - .to_str() - .context("could not convert file stem to string")?; - - let build_dir = std::env::current_dir()?.join("build"); - if !build_dir.exists() { - std::fs::create_dir_all(&build_dir)?; - } - let output = build_dir.join(input_stem); - - let compile_args = CompilerArgs { - input: input.clone(), - output: output.clone(), - release, - optlevel: None, - debug_info: None, - library: false, - ast: false, - ir: false, - llvm: true, - asm: false, - object: true, - mlir: true, - }; - - println!( - " {} {} ({})", - "Compiling".green().bold(), - input_stem, - input.display() - ); - - let start = Instant::now(); - let object = compile(&compile_args)?; - link_binary(&[object], &output)?; - let elapsed = start.elapsed(); - - println!( - " {} {} in {elapsed:?}", - "Finished".green().bold(), - if release { "release" } else { "dev" }, - ); - - output - } - None => build_command(profile, release)?, - }; - - println!(" {} {}", "Running".green().bold(), &output.display()); - + let output = handle_build(path, release, profile)?; Err(std::process::Command::new(output).exec())?; } } @@ -323,110 +270,162 @@ mod {} {{ Ok(()) } -fn build_command(profile: Option, release: bool) -> Result { - let mut current_dir = std::env::current_dir()?; - let mut config_path = None; - for _ in 0..3 { - if !current_dir.join("Concrete.toml").exists() { - current_dir = if let Some(parent) = current_dir.parent() { - parent.to_path_buf() +fn handle_build(path: Option, release: bool, profile: Option) -> Result { + match path { + Some(input) => { + let input_stem = input + .file_stem() + .context("could not get file stem")? + .to_str() + .context("could not convert file stem to string")?; + + let build_dir = std::env::current_dir()?.join("build"); + if !build_dir.exists() { + std::fs::create_dir_all(&build_dir)?; + } + let output = build_dir.join(input_stem); + + let compile_args = CompilerArgs { + input: input.clone(), + output: output.clone(), + release, + optlevel: None, + debug_info: None, + library: false, + ast: false, + ir: false, + llvm: true, + asm: false, + object: true, + mlir: true, + }; + + println!( + " {} {} ({})", + "Compiling".green().bold(), + input_stem, + input.display() + ); + + let start = Instant::now(); + let object = compile(&compile_args)?; + link_binary(&[object], &output)?; + let elapsed = start.elapsed(); + + println!( + " {} {} in {elapsed:?}", + "Finished".green().bold(), + if release { "release" } else { "dev" }, + ); + + Ok(output) + } + None => { + let mut current_dir = std::env::current_dir()?; + let mut config_path = None; + for _ in 0..3 { + if !current_dir.join("Concrete.toml").exists() { + current_dir = if let Some(parent) = current_dir.parent() { + parent.to_path_buf() + } else { + bail!("couldn't find Concrete.toml"); + }; + } else { + config_path = Some(current_dir.join("Concrete.toml")); + break; + } + } + let config_path = match config_path { + Some(x) => x, + None => bail!("couldn't find Concrete.toml"), + }; + let base_dir = config_path + .parent() + .context("couldn't get config parent dir")?; + let mut config = File::open(&config_path).context("failed to open Concrete.toml")?; + let mut buf = String::new(); + config.read_to_string(&mut buf)?; + let config: Config = toml::from_str(&buf).context("failed to parse Concrete.toml")?; + println!( + " {} {} v{} ({})", + "Compiling".green().bold(), + config.package.name, + config.package.version, + base_dir.display() + ); + let src_dir = base_dir.join("src"); + let target_dir = base_dir.join("build"); + if !target_dir.exists() { + std::fs::create_dir_all(&target_dir)?; + } + let has_main = src_dir.join("main.con").exists(); + let output = target_dir.join(config.package.name); + let (profile, profile_name) = if let Some(profile) = profile { + ( + config + .profile + .get(&profile) + .context("couldn't get requested profile")?, + profile, + ) + } else if release { + ( + config + .profile + .get("release") + .context("couldn't get profile: release")?, + "release".to_string(), + ) } else { - bail!("couldn't find Concrete.toml"); + ( + config + .profile + .get("dev") + .context("couldn't get profile: dev")?, + "dev".to_string(), + ) }; - } else { - config_path = Some(current_dir.join("Concrete.toml")); - break; + let compile_args = CompilerArgs { + input: src_dir, + output: output.clone(), + release, + optlevel: Some(profile.opt_level), + debug_info: Some(profile.debug_info), + library: !has_main, + ast: false, + ir: false, + llvm: true, + asm: false, + object: true, + mlir: true, + }; + let start = Instant::now(); + let object = compile(&compile_args)?; + if !has_main { + link_shared_lib(&[object], &output)?; + } else { + link_binary(&[object], &output)?; + } + let elapsed = start.elapsed(); + println!( + " {} {} [{}{}] in {elapsed:?}", + "Finished".green().bold(), + profile_name, + if profile.opt_level > 0 { + "optimized" + } else { + "unoptimized" + }, + if profile.debug_info { + " + debuginfo" + } else { + "" + } + ); + + Ok(output) } } - let config_path = match config_path { - Some(x) => x, - None => bail!("couldn't find Concrete.toml"), - }; - let base_dir = config_path - .parent() - .context("couldn't get config parent dir")?; - let mut config = File::open(&config_path).context("failed to open Concrete.toml")?; - let mut buf = String::new(); - config.read_to_string(&mut buf)?; - let config: Config = toml::from_str(&buf).context("failed to parse Concrete.toml")?; - println!( - " {} {} v{} ({})", - "Compiling".green().bold(), - config.package.name, - config.package.version, - base_dir.display() - ); - let src_dir = base_dir.join("src"); - let target_dir = base_dir.join("build"); - if !target_dir.exists() { - std::fs::create_dir_all(&target_dir)?; - } - let has_main = src_dir.join("main.con").exists(); - let output = target_dir.join(config.package.name); - let (profile, profile_name) = if let Some(profile) = profile { - ( - config - .profile - .get(&profile) - .context("couldn't get requested profile")?, - profile, - ) - } else if release { - ( - config - .profile - .get("release") - .context("couldn't get profile: release")?, - "release".to_string(), - ) - } else { - ( - config - .profile - .get("dev") - .context("couldn't get profile: dev")?, - "dev".to_string(), - ) - }; - let compile_args = CompilerArgs { - input: src_dir, - output: output.clone(), - release, - optlevel: Some(profile.opt_level), - debug_info: Some(profile.debug_info), - library: !has_main, - ast: false, - ir: false, - llvm: true, - asm: false, - object: true, - mlir: true, - }; - let start = Instant::now(); - let object = compile(&compile_args)?; - if !has_main { - link_shared_lib(&[object], &output)?; - } else { - link_binary(&[object], &output)?; - } - let elapsed = start.elapsed(); - println!( - " {} {} [{}{}] in {elapsed:?}", - "Finished".green().bold(), - profile_name, - if profile.opt_level > 0 { - "optimized" - } else { - "unoptimized" - }, - if profile.debug_info { - " + debuginfo" - } else { - "" - } - ); - - Ok(output) } pub fn compile(args: &CompilerArgs) -> Result { From 2f0e48febf9ee1b8b72321d7226710c71a543e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 19 Apr 2024 15:00:16 -0300 Subject: [PATCH 3/4] Abstract args to another struct and add flags --- crates/concrete_driver/src/lib.rs | 123 +++++++++++++++++------------- 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/crates/concrete_driver/src/lib.rs b/crates/concrete_driver/src/lib.rs index 4feeafb..2b27d41 100644 --- a/crates/concrete_driver/src/lib.rs +++ b/crates/concrete_driver/src/lib.rs @@ -50,32 +50,49 @@ enum Commands { #[arg(long, group = "binary")] lib: bool, }, - /// Build a project - Build { - #[arg(required = false)] - path: Option, - - /// Build for release with all optimizations. - #[arg(short, long, default_value_t = false)] - release: bool, - - /// Override the profile to use. - #[arg(short, long)] - profile: Option, - }, - /// Run a concrete file - Run { - #[arg(required = false)] - path: Option, - - /// Build for release with all optimizations. - #[arg(short, long, default_value_t = false)] - release: bool, - - /// Override the profile to use. - #[arg(short, long)] - profile: Option, - }, + /// Build a project or file + Build(BuildArgs), + /// Run a project or file + Run(BuildArgs), +} + +#[derive(Args)] +pub struct BuildArgs { + /// Build specific file + #[arg(required = false)] + path: Option, + + /// Build for release with all optimizations. + #[arg(short, long, default_value_t = false)] + release: bool, + + /// Override the profile to use. + #[arg(short, long)] + profile: Option, + + /// Also output the ast. + #[arg(long, default_value_t = false)] + ast: bool, + + /// Also output the ir. + #[arg(long, default_value_t = false)] + ir: bool, + + /// Also output the llvm ir file. + #[arg(long, default_value_t = false)] + llvm: bool, + + /// Also output the mlir file + #[arg(long, default_value_t = false)] + mlir: bool, + + /// Also output the asm file. + #[arg(long, default_value_t = false)] + asm: bool, + + /// Also output the object file. + #[arg(long, default_value_t = false)] + object: bool, } #[derive(Parser, Debug)] @@ -250,19 +267,11 @@ mod {} {{ println!(" {} library `{}` package", "Created".green(), name); } } - Commands::Build { - path, - release, - profile, - } => { - handle_build(path, release, profile)?; + Commands::Build(args) => { + handle_build(args)?; } - Commands::Run { - path, - release, - profile, - } => { - let output = handle_build(path, release, profile)?; + Commands::Run(args) => { + let output = handle_build(args)?; Err(std::process::Command::new(output).exec())?; } } @@ -270,7 +279,19 @@ mod {} {{ Ok(()) } -fn handle_build(path: Option, release: bool, profile: Option) -> Result { +fn handle_build( + BuildArgs { + path, + release, + profile, + ast, + ir, + llvm, + mlir, + asm, + object, + }: BuildArgs, +) -> Result { match path { Some(input) => { let input_stem = input @@ -292,12 +313,12 @@ fn handle_build(path: Option, release: bool, profile: Option) - optlevel: None, debug_info: None, library: false, - ast: false, - ir: false, - llvm: true, - asm: false, - object: true, - mlir: true, + ast, + ir, + llvm, + asm, + object, + mlir, }; println!( @@ -392,12 +413,12 @@ fn handle_build(path: Option, release: bool, profile: Option) - optlevel: Some(profile.opt_level), debug_info: Some(profile.debug_info), library: !has_main, - ast: false, - ir: false, - llvm: true, - asm: false, - object: true, - mlir: true, + ast, + ir, + llvm, + asm, + object, + mlir, }; let start = Instant::now(); let object = compile(&compile_args)?; From 882ab24c1a013bfe535a51249e0bc32bc6926821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 19 Apr 2024 15:15:23 -0300 Subject: [PATCH 4/4] Fix typo --- crates/concrete_driver/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/concrete_driver/src/lib.rs b/crates/concrete_driver/src/lib.rs index 2b27d41..21a9237 100644 --- a/crates/concrete_driver/src/lib.rs +++ b/crates/concrete_driver/src/lib.rs @@ -1,6 +1,7 @@ use anyhow::bail; use anyhow::Context; use anyhow::Result; +use clap::Args; use clap::{Parser, Subcommand}; use concrete_ir::lowering::lower_programs; use concrete_parser::{error::Diagnostics, ProgramSource}; @@ -56,7 +57,7 @@ enum Commands { Run(BuildArgs), } -#[derive(Args)] +#[derive(Args, Debug)] pub struct BuildArgs { /// Build specific file #[arg(required = false)]