Skip to main content

foundry_cli/opts/build/
mod.rs

1use clap::Parser;
2use foundry_compilers::artifacts::{EvmVersion, output_selection::ContractOutputSelection};
3use serde::Serialize;
4
5mod core;
6pub use self::core::BuildOpts;
7
8mod paths;
9pub use self::paths::ProjectPathOpts;
10
11mod utils;
12pub use self::utils::*;
13
14// A set of solc compiler settings that can be set via command line arguments, which are intended
15// to be merged into an existing `foundry_config::Config`.
16//
17// See also `BuildArgs`.
18#[derive(Clone, Debug, Default, Serialize, Parser)]
19#[command(next_help_heading = "Compiler options")]
20pub struct CompilerOpts {
21    /// Includes the AST as JSON in the compiler output.
22    #[arg(long, help_heading = "Compiler options")]
23    #[serde(skip)]
24    pub ast: bool,
25
26    /// The target EVM version.
27    #[arg(long, value_name = "VERSION")]
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub evm_version: Option<EvmVersion>,
30
31    /// Activate the Solidity optimizer.
32    #[arg(long, default_missing_value="true", num_args = 0..=1)]
33    #[serde(skip)]
34    pub optimize: Option<bool>,
35
36    /// The number of runs specifies roughly how often each opcode of the deployed code will be
37    /// executed across the life-time of the contract. This means it is a trade-off parameter
38    /// between code size (deploy cost) and code execution cost (cost after deployment).
39    /// An `optimizer_runs` parameter of `1` will produce short but expensive code. In contrast, a
40    /// larger `optimizer_runs` parameter will produce longer but more gas efficient code.
41    #[arg(long, value_name = "RUNS")]
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub optimizer_runs: Option<usize>,
44
45    /// Use the Yul intermediate representation compilation pipeline.
46    #[arg(long, help_heading = "Compiler options")]
47    #[serde(skip)]
48    pub via_ir: bool,
49
50    /// Turn on SSA CFG-based code generation via the IR (experimental).
51    ///
52    /// This passes `--via-ssa-cfg` to solc. Implies `--via-ir`. Requires `--experimental` to be
53    /// set (as of Solidity 0.8.35+). This is false by default.
54    #[arg(long, help_heading = "Compiler options")]
55    #[serde(skip)]
56    pub via_ssa_cfg: bool,
57
58    /// Enable Solidity's experimental mode.
59    ///
60    /// This passes `--experimental` to solc, which is required by Solidity 0.8.35+ for
61    /// experimental features.
62    #[arg(long, help_heading = "Compiler options")]
63    #[serde(skip)]
64    pub experimental: bool,
65
66    /// Extra output to include in the contract's artifact.
67    ///
68    /// Example keys: evm.assembly, ewasm, ir, irOptimized, metadata
69    ///
70    /// For a full description, see <https://docs.soliditylang.org/en/v0.8.13/using-the-compiler.html#input-description>
71    #[arg(long, num_args(1..), value_name = "SELECTOR")]
72    #[serde(skip_serializing_if = "Vec::is_empty")]
73    pub extra_output: Vec<ContractOutputSelection>,
74
75    /// Extra output to write to separate files.
76    ///
77    /// Valid values: metadata, ir, irOptimized, ewasm, evm.assembly
78    #[arg(long, num_args(1..), value_name = "SELECTOR")]
79    #[serde(skip_serializing_if = "Vec::is_empty")]
80    pub extra_output_files: Vec<ContractOutputSelection>,
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn can_parse_evm_version() {
89        let args: CompilerOpts =
90            CompilerOpts::parse_from(["foundry-cli", "--evm-version", "london"]);
91        assert_eq!(args.evm_version, Some(EvmVersion::London));
92    }
93
94    #[test]
95    fn can_parse_extra_output() {
96        let args: CompilerOpts =
97            CompilerOpts::parse_from(["foundry-cli", "--extra-output", "metadata", "ir-optimized"]);
98        assert_eq!(
99            args.extra_output,
100            vec![ContractOutputSelection::Metadata, ContractOutputSelection::IrOptimized]
101        );
102    }
103
104    #[test]
105    fn can_parse_experimental() {
106        let args: CompilerOpts = CompilerOpts::parse_from(["foundry-cli", "--experimental"]);
107        assert!(args.experimental);
108    }
109
110    #[test]
111    fn can_parse_via_ssa_cfg() {
112        let args: CompilerOpts = CompilerOpts::parse_from(["foundry-cli", "--via-ssa-cfg"]);
113        assert!(args.via_ssa_cfg);
114    }
115
116    #[test]
117    fn can_parse_extra_output_files() {
118        let args: CompilerOpts = CompilerOpts::parse_from([
119            "foundry-cli",
120            "--extra-output-files",
121            "metadata",
122            "ir-optimized",
123        ]);
124        assert_eq!(
125            args.extra_output_files,
126            vec![ContractOutputSelection::Metadata, ContractOutputSelection::IrOptimized]
127        );
128    }
129}