forc_pkg/manifest/
build_profile.rs

1use serde::{Deserialize, Serialize};
2use sway_core::{Backtrace, IrCli, OptLevel, PrintAsm};
3
4use crate::DumpOpts;
5
6/// Parameters to pass through to the `sway_core::BuildConfig` during compilation.
7#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
8#[serde(rename_all = "kebab-case")]
9pub struct BuildProfile {
10    #[serde(default)]
11    pub name: String,
12    #[serde(default)]
13    pub print_ast: bool,
14    pub print_dca_graph: Option<String>,
15    pub print_dca_graph_url_format: Option<String>,
16    pub dump: DumpOpts,
17    #[serde(default)]
18    pub print_ir: IrCli,
19    #[serde(default)]
20    pub verify_ir: IrCli,
21    #[serde(default)]
22    pub print_asm: PrintAsm,
23    #[serde(default)]
24    pub print_bytecode: bool,
25    #[serde(default)]
26    pub print_bytecode_spans: bool,
27    #[serde(default)]
28    pub terse: bool,
29    #[serde(default)]
30    pub time_phases: bool,
31    #[serde(default)]
32    pub profile: bool,
33    #[serde(default)]
34    pub metrics_outfile: Option<String>,
35    #[serde(default)]
36    pub include_tests: bool,
37    #[serde(default)]
38    pub error_on_warnings: bool,
39    #[serde(default)]
40    pub reverse_results: bool,
41    #[serde(default)]
42    pub optimization_level: OptLevel,
43    #[serde(default)]
44    pub backtrace: Backtrace,
45}
46
47impl BuildProfile {
48    pub const DEBUG: &'static str = "debug";
49    pub const RELEASE: &'static str = "release";
50    pub const DEFAULT: &'static str = Self::DEBUG;
51
52    pub fn debug() -> Self {
53        Self {
54            name: Self::DEBUG.into(),
55            dump: DumpOpts::default(),
56            print_ast: false,
57            print_dca_graph: None,
58            print_dca_graph_url_format: None,
59            print_ir: IrCli::default(),
60            verify_ir: IrCli::default(),
61            print_asm: PrintAsm::default(),
62            print_bytecode: false,
63            print_bytecode_spans: false,
64            terse: false,
65            time_phases: false,
66            profile: false,
67            metrics_outfile: None,
68            include_tests: false,
69            error_on_warnings: false,
70            reverse_results: false,
71            optimization_level: OptLevel::Opt0,
72            backtrace: Backtrace::AllExceptNever,
73        }
74    }
75
76    pub fn release() -> Self {
77        Self {
78            name: Self::RELEASE.to_string(),
79            dump: DumpOpts::default(),
80            print_ast: false,
81            print_dca_graph: None,
82            print_dca_graph_url_format: None,
83            print_ir: IrCli::default(),
84            verify_ir: IrCli::default(),
85            print_asm: PrintAsm::default(),
86            print_bytecode: false,
87            print_bytecode_spans: false,
88            terse: false,
89            time_phases: false,
90            profile: false,
91            metrics_outfile: None,
92            include_tests: false,
93            error_on_warnings: false,
94            reverse_results: false,
95            optimization_level: OptLevel::Opt1,
96            backtrace: Backtrace::OnlyAlways,
97        }
98    }
99
100    pub fn is_release(&self) -> bool {
101        self.name == Self::RELEASE
102    }
103}
104
105impl Default for BuildProfile {
106    fn default() -> Self {
107        Self::debug()
108    }
109}
110
111#[cfg(test)]
112mod tests {
113    use crate::{BuildProfile, DumpOpts, PackageManifest};
114    use sway_core::{Backtrace, IrCli, OptLevel, PrintAsm};
115
116    #[test]
117    fn test_build_profiles() {
118        let manifest = PackageManifest::from_dir("./tests/sections").expect("manifest");
119        let build_profiles = manifest.build_profile.expect("build profile");
120        assert_eq!(build_profiles.len(), 5);
121
122        // Standard debug profile without adaptations.
123        let expected = BuildProfile::debug();
124        let profile = build_profiles.get("debug").expect("debug profile");
125        assert_eq!(*profile, expected);
126
127        // Profile based on debug profile with adjusted ASM printing options.
128        let expected = BuildProfile {
129            name: "".into(),
130            print_asm: PrintAsm::r#final(),
131            ..BuildProfile::debug()
132        };
133        let profile = build_profiles.get("custom_asm").expect("custom profile");
134        assert_eq!(*profile, expected);
135
136        // Profile based on debug profile with adjusted IR printing options.
137        let expected = BuildProfile {
138            name: "".into(),
139            print_ir: IrCli {
140                initial: true,
141                r#final: false,
142                modified_only: true,
143                passes: vec!["dce".to_string(), "sroa".to_string()],
144            },
145            ..BuildProfile::debug()
146        };
147        let profile = build_profiles
148            .get("custom_ir")
149            .expect("custom profile for IR");
150        assert_eq!(*profile, expected);
151
152        // Profile based on debug profile with adjusted backtrace option.
153        let expected = BuildProfile {
154            name: "".into(),
155            backtrace: Backtrace::OnlyAlways,
156            ..BuildProfile::debug()
157        };
158        let profile = build_profiles
159            .get("custom_backtrace")
160            .expect("custom profile for backtrace");
161        assert_eq!(*profile, expected);
162
163        // Adapted release profile.
164        let expected = BuildProfile {
165            name: "".into(),
166            dump: DumpOpts::default(),
167            print_ast: true,
168            print_dca_graph: Some("dca_graph".into()),
169            print_dca_graph_url_format: Some("print_dca_graph_url_format".into()),
170            print_ir: IrCli::r#final(),
171            verify_ir: IrCli::none(),
172            print_asm: PrintAsm::all(),
173            print_bytecode: true,
174            print_bytecode_spans: false,
175            terse: true,
176            time_phases: true,
177            profile: false,
178            metrics_outfile: Some("metrics_outfile".into()),
179            include_tests: true,
180            error_on_warnings: true,
181            reverse_results: true,
182            optimization_level: OptLevel::Opt0,
183            backtrace: Backtrace::None,
184        };
185        let profile = build_profiles.get("release").expect("release profile");
186        assert_eq!(*profile, expected);
187    }
188}