Skip to content

Commit

Permalink
chore: simplify compilation flow to write to file immediately (#5265)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves <!-- Link to GitHub Issue -->

## Summary\*

This PR pulls across the changes from
AztecProtocol/aztec-packages#6488 to avoid
making changes in aztec-packages unnecessarily and get around the CI
issues over there.

## Additional Context



## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
TomAFrench authored Jun 18, 2024
1 parent c91186a commit f8608e6
Showing 1 changed file with 78 additions and 51 deletions.
129 changes: 78 additions & 51 deletions tooling/nargo_cli/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ use std::path::Path;
use std::time::Duration;

use fm::FileManager;
use nargo::artifacts::program::ProgramArtifact;
use nargo::ops::{collect_errors, compile_contract, compile_program, report_errors};
use nargo::package::Package;
use nargo::workspace::Workspace;
use nargo::{insert_all_files_for_workspace_into_file_manager, parse_all};
use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection};
use noirc_driver::file_manager_with_stdlib;
use noirc_driver::NOIR_ARTIFACT_VERSION_STRING;
use noirc_driver::{CompilationResult, CompileOptions, CompiledContract, CompiledProgram};
use noirc_driver::{CompilationResult, CompileOptions, CompiledContract};

use noirc_frontend::graph::CrateName;

Expand Down Expand Up @@ -121,72 +120,43 @@ pub(super) fn compile_workspace_full(
let compiled_workspace =
compile_workspace(&workspace_file_manager, &parsed_files, workspace, compile_options);

let (compiled_programs, compiled_contracts) = report_errors(
report_errors(
compiled_workspace,
&workspace_file_manager,
compile_options.deny_warnings,
compile_options.silence_warnings,
)?;

let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace
.into_iter()
.filter(|package| !package.is_library())
.cloned()
.partition(|package| package.is_binary());

// Save build artifacts to disk.
for (package, program) in binary_packages.into_iter().zip(compiled_programs) {
let program = nargo::ops::transform_program(program, compile_options.expression_width);
save_program(program.clone(), &package, &workspace.target_directory_path());
}
let circuit_dir = workspace.target_directory_path();
for (package, contract) in contract_packages.into_iter().zip(compiled_contracts) {
let contract = nargo::ops::transform_contract(contract, compile_options.expression_width);
save_contract(contract, &package, &circuit_dir, compile_options.show_artifact_paths);
}

Ok(())
}

pub(super) fn compile_workspace(
fn compile_workspace(
file_manager: &FileManager,
parsed_files: &ParsedFiles,
workspace: &Workspace,
compile_options: &CompileOptions,
) -> CompilationResult<(Vec<CompiledProgram>, Vec<CompiledContract>)> {
) -> CompilationResult<()> {
let (binary_packages, contract_packages): (Vec<_>, Vec<_>) = workspace
.into_iter()
.filter(|package| !package.is_library())
.cloned()
.partition(|package| package.is_binary());

// Compile all of the packages in parallel.
let program_results: Vec<CompilationResult<CompiledProgram>> = binary_packages
.par_iter()
.map(|package| {
let program_artifact_path = workspace.package_build_path(package);
let cached_program: Option<CompiledProgram> =
read_program_from_file(program_artifact_path)
.ok()
.filter(|p| p.noir_version == NOIR_ARTIFACT_VERSION_STRING)
.map(|p| p.into());

compile_program(file_manager, parsed_files, package, compile_options, cached_program)
})
.collect();
let contract_results: Vec<CompilationResult<CompiledContract>> = contract_packages
.par_iter()
.map(|package| compile_contract(file_manager, parsed_files, package, compile_options))
.collect();

// Collate any warnings/errors which were encountered during compilation.
let compiled_programs = collect_errors(program_results);
let compiled_contracts = collect_errors(contract_results);
let program_warnings_or_errors: CompilationResult<()> =
compile_programs(file_manager, parsed_files, workspace, &binary_packages, compile_options);
let contract_warnings_or_errors: CompilationResult<()> = compiled_contracts(
file_manager,
parsed_files,
&contract_packages,
compile_options,
&workspace.target_directory_path(),
);

match (compiled_programs, compiled_contracts) {
(Ok((programs, program_warnings)), Ok((contracts, contract_warnings))) => {
match (program_warnings_or_errors, contract_warnings_or_errors) {
(Ok((_, program_warnings)), Ok((_, contract_warnings))) => {
let warnings = [program_warnings, contract_warnings].concat();
Ok(((programs, contracts), warnings))
Ok(((), warnings))
}
(Err(program_errors), Err(contract_errors)) => {
Err([program_errors, contract_errors].concat())
Expand All @@ -195,22 +165,79 @@ pub(super) fn compile_workspace(
}
}

pub(super) fn save_program(program: CompiledProgram, package: &Package, circuit_dir: &Path) {
let program_artifact = ProgramArtifact::from(program.clone());
save_program_to_file(&program_artifact, &package.name, circuit_dir);
fn compile_programs(
file_manager: &FileManager,
parsed_files: &ParsedFiles,
workspace: &Workspace,
binary_packages: &[Package],
compile_options: &CompileOptions,
) -> CompilationResult<()> {
let load_cached_program = |package| {
let program_artifact_path = workspace.package_build_path(package);
read_program_from_file(program_artifact_path)
.ok()
.filter(|p| p.noir_version == NOIR_ARTIFACT_VERSION_STRING)
.map(|p| p.into())
};

let program_results: Vec<CompilationResult<()>> = binary_packages
.par_iter()
.map(|package| {
let (program, warnings) = compile_program(
file_manager,
parsed_files,
package,
compile_options,
load_cached_program(package),
)?;
let program = nargo::ops::transform_program(program, compile_options.expression_width);
save_program_to_file(
&program.clone().into(),
&package.name,
workspace.target_directory_path(),
);
Ok(((), warnings))
})
.collect();

// Collate any warnings/errors which were encountered during compilation.
collect_errors(program_results).map(|(_, warnings)| ((), warnings))
}

fn compiled_contracts(
file_manager: &FileManager,
parsed_files: &ParsedFiles,
contract_packages: &[Package],
compile_options: &CompileOptions,
target_dir: &Path,
) -> CompilationResult<()> {
let contract_results: Vec<CompilationResult<()>> = contract_packages
.par_iter()
.map(|package| {
let (contract, warnings) =
compile_contract(file_manager, parsed_files, package, compile_options)?;
let contract =
nargo::ops::transform_contract(contract, compile_options.expression_width);
save_contract(contract, package, target_dir, compile_options.show_artifact_paths);
Ok(((), warnings))
})
.collect();

// Collate any warnings/errors which were encountered during compilation.
collect_errors(contract_results).map(|(_, warnings)| ((), warnings))
}

fn save_contract(
contract: CompiledContract,
package: &Package,
circuit_dir: &Path,
target_dir: &Path,
show_artifact_paths: bool,
) {
let contract_name = contract.name.clone();
let artifact_path = save_contract_to_file(
&contract.into(),
&format!("{}-{}", package.name, contract_name),
circuit_dir,
target_dir,
);
if show_artifact_paths {
println!("Saved contract artifact to: {}", artifact_path.display());
Expand Down

0 comments on commit f8608e6

Please sign in to comment.