cargo/core/compiler/
crate_type.rs

1use std::fmt;
2
3/// Types of the output artifact that the compiler emits.
4/// Usually distributable or linkable either statically or dynamically.
5///
6/// See <https://doc.rust-lang.org/nightly/reference/linkage.html>.
7#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
8pub enum CrateType {
9    Bin,
10    Lib,
11    Rlib,
12    Dylib,
13    Cdylib,
14    Staticlib,
15    ProcMacro,
16    Other(String),
17}
18
19impl CrateType {
20    pub fn as_str(&self) -> &str {
21        match self {
22            CrateType::Bin => "bin",
23            CrateType::Lib => "lib",
24            CrateType::Rlib => "rlib",
25            CrateType::Dylib => "dylib",
26            CrateType::Cdylib => "cdylib",
27            CrateType::Staticlib => "staticlib",
28            CrateType::ProcMacro => "proc-macro",
29            CrateType::Other(s) => s,
30        }
31    }
32
33    pub fn can_lto(&self) -> bool {
34        match self {
35            CrateType::Bin | CrateType::Staticlib | CrateType::Cdylib => true,
36            CrateType::Lib
37            | CrateType::Rlib
38            | CrateType::Dylib
39            | CrateType::ProcMacro
40            | CrateType::Other(..) => false,
41        }
42    }
43
44    pub fn is_linkable(&self) -> bool {
45        match self {
46            CrateType::Lib | CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
47            CrateType::Bin | CrateType::Cdylib | CrateType::Staticlib | CrateType::Other(..) => {
48                false
49            }
50        }
51    }
52
53    pub fn is_dynamic(&self) -> bool {
54        match self {
55            CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => true,
56            CrateType::Lib
57            | CrateType::Rlib
58            | CrateType::Bin
59            | CrateType::Staticlib
60            | CrateType::Other(..) => false,
61        }
62    }
63
64    /// Returns whether production of this crate type requires the object files
65    /// from dependencies to be available.
66    ///
67    /// See also [`TargetKind::requires_upstream_objects`].
68    ///
69    /// [`TargetKind::requires_upstream_objects`]: crate::core::manifest::TargetKind::requires_upstream_objects
70    pub fn requires_upstream_objects(&self) -> bool {
71        // "lib" == "rlib" and is a compilation that doesn't actually
72        // require upstream object files to exist, only upstream metadata
73        // files. As a result, it doesn't require upstream artifacts
74
75        !matches!(self, CrateType::Lib | CrateType::Rlib)
76        // Everything else, however, is some form of "linkable output" or
77        // something that requires upstream object files.
78    }
79}
80
81impl fmt::Display for CrateType {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        self.as_str().fmt(f)
84    }
85}
86
87impl<'a> From<&'a String> for CrateType {
88    fn from(s: &'a String) -> Self {
89        match s.as_str() {
90            "bin" => CrateType::Bin,
91            "lib" => CrateType::Lib,
92            "rlib" => CrateType::Rlib,
93            "dylib" => CrateType::Dylib,
94            "cdylib" => CrateType::Cdylib,
95            "staticlib" => CrateType::Staticlib,
96            "procmacro" => CrateType::ProcMacro,
97            _ => CrateType::Other(s.clone()),
98        }
99    }
100}
101
102impl fmt::Debug for CrateType {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        self.to_string().fmt(f)
105    }
106}
107
108impl serde::Serialize for CrateType {
109    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
110    where
111        S: serde::ser::Serializer,
112    {
113        self.to_string().serialize(s)
114    }
115}