Skip to main content

cargo_wizard/
predefined.rs

1use rustc_version::Version;
2
3use crate::template::{TemplateItemId, dev_profile, release_profile};
4use crate::toml::TomlValue;
5use crate::utils::get_core_count;
6use crate::{Template, WizardOptions};
7
8/// Enumeration of predefined templates.
9#[derive(clap::ValueEnum, Clone, Copy, Debug)]
10pub enum PredefinedTemplateKind {
11    /// Profile designed for fast compilation times.
12    FastCompile,
13    /// Profile designed for fast runtime performance.
14    FastRuntime,
15    /// Profile designed for minimal binary size.
16    MinSize,
17}
18
19impl PredefinedTemplateKind {
20    pub fn build_template(&self, options: &WizardOptions) -> Template {
21        match self {
22            PredefinedTemplateKind::FastCompile => fast_compile_template(options),
23            PredefinedTemplateKind::FastRuntime => fast_runtime_template(),
24            PredefinedTemplateKind::MinSize => min_size_template(),
25        }
26    }
27}
28
29#[cfg(unix)]
30fn is_macos_host(host: &str) -> bool {
31    host.ends_with("-apple-darwin")
32}
33
34#[cfg(unix)]
35fn should_suggest_lld(version: &Version, host: &str) -> bool {
36    if is_macos_host(host) {
37        return false;
38    }
39
40    version < &Version::new(1, 90, 0) || host != "x86_64-unknown-linux-gnu"
41}
42
43/// Template that focuses on quick compile time.
44pub fn fast_compile_template(options: &WizardOptions) -> Template {
45    let mut builder = dev_profile().item(TemplateItemId::DebugInfo, TomlValue::int(0));
46
47    #[cfg(unix)]
48    match rustc_version::version_meta() {
49        Ok(meta) => {
50            if should_suggest_lld(&meta.semver, &meta.host) {
51                builder = builder.item(TemplateItemId::Linker, TomlValue::string("lld"));
52            }
53        }
54        Err(error) => {
55            if !cfg!(target_os = "macos") {
56                builder = builder.item(TemplateItemId::Linker, TomlValue::string("lld"));
57            }
58            eprintln!("Cannot get compiler version metadata. ({error:?})");
59        }
60    }
61
62    if options.nightly_items_enabled() {
63        builder = builder
64            .item(
65                TemplateItemId::CodegenBackend,
66                TomlValue::string("cranelift"),
67            )
68            .item(
69                TemplateItemId::FrontendThreads,
70                TomlValue::Int(get_core_count()),
71            )
72    }
73    builder.build()
74}
75
76/// Template that focuses on maximum runtime performance.
77pub fn fast_runtime_template() -> Template {
78    release_profile()
79        .item(TemplateItemId::Lto, TomlValue::bool(true))
80        .item(TemplateItemId::CodegenUnits, TomlValue::int(1))
81        .item(TemplateItemId::Panic, TomlValue::string("abort"))
82        .item(
83            TemplateItemId::TargetCpuInstructionSet,
84            TomlValue::string("native"),
85        )
86        .build()
87}
88
89/// Template that template focuses on minimal binary size.
90pub fn min_size_template() -> Template {
91    release_profile()
92        .item(TemplateItemId::DebugInfo, TomlValue::bool(false))
93        .item(TemplateItemId::Strip, TomlValue::bool(true))
94        .item(TemplateItemId::Lto, TomlValue::bool(true))
95        .item(TemplateItemId::OptimizationLevel, TomlValue::string("z"))
96        .item(TemplateItemId::CodegenUnits, TomlValue::int(1))
97        .item(TemplateItemId::Panic, TomlValue::string("abort"))
98        .build()
99}
100
101/// Test that the predefined templates can be created without panicking.
102#[cfg(test)]
103mod tests {
104    use crate::{WizardOptions, fast_compile_template, fast_runtime_template, min_size_template};
105
106    #[cfg(unix)]
107    use super::should_suggest_lld;
108    #[cfg(unix)]
109    use rustc_version::Version;
110
111    #[test]
112    fn create_fast_compile_template() {
113        fast_compile_template(&WizardOptions::default());
114    }
115
116    #[test]
117    fn create_fast_runtime_template() {
118        fast_runtime_template();
119    }
120
121    #[test]
122    fn create_min_size_template() {
123        min_size_template();
124    }
125
126    #[test]
127    #[cfg(unix)]
128    fn fast_compile_linker_matrix_matches_supported_hosts() {
129        assert!(should_suggest_lld(
130            &Version::new(1, 89, 0),
131            "x86_64-unknown-linux-gnu"
132        ));
133        assert!(!should_suggest_lld(
134            &Version::new(1, 90, 0),
135            "x86_64-unknown-linux-gnu"
136        ));
137        assert!(should_suggest_lld(
138            &Version::new(1, 90, 0),
139            "aarch64-unknown-linux-gnu"
140        ));
141        assert!(!should_suggest_lld(
142            &Version::new(1, 89, 0),
143            "x86_64-apple-darwin"
144        ));
145        assert!(!should_suggest_lld(
146            &Version::new(1, 90, 0),
147            "aarch64-apple-darwin"
148        ));
149    }
150}