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 /// Returns whether production of this crate type could benefit from splitting metadata
81 /// into a .rmeta file.
82 ///
83 /// See also [`TargetKind::benefits_from_no_embed_metadata`].
84 ///
85 /// [`TargetKind::benefits_from_no_embed_metadata`]: crate::core::manifest::TargetKind::benefits_from_no_embed_metadata
86 pub fn benefits_from_no_embed_metadata(&self) -> bool {
87 match self {
88 // rlib/libs generate .rmeta files for pipelined compilation.
89 // If we also include metadata inside of them, we waste disk space, since the metadata
90 // will be located both in the lib/rlib and the .rmeta file.
91 CrateType::Lib |
92 CrateType::Rlib |
93 // Dylibs do not have to contain metadata when they are used as a runtime dependency.
94 // If we split the metadata into a separate .rmeta file, the dylib file (that
95 // can be shipped as a runtime dependency) can be smaller.
96 CrateType::Dylib => true,
97 // Proc macros contain metadata that specifies what macro functions are available in
98 // it, but the metadata is typically very small. The metadata of proc macros is also
99 // self-contained (unlike rlibs/dylibs), so let's not unnecessarily split it into
100 // multiple files.
101 CrateType::ProcMacro |
102 // cdylib and staticlib produce artifacts that are used through the C ABI and do not
103 // contain Rust-specific metadata.
104 CrateType::Cdylib |
105 CrateType::Staticlib |
106 // Binaries also do not contain metadata
107 CrateType::Bin |
108 CrateType::Other(_) => false
109 }
110 }
111}
112
113impl fmt::Display for CrateType {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 self.as_str().fmt(f)
116 }
117}
118
119impl<'a> From<&'a String> for CrateType {
120 fn from(s: &'a String) -> Self {
121 match s.as_str() {
122 "bin" => CrateType::Bin,
123 "lib" => CrateType::Lib,
124 "rlib" => CrateType::Rlib,
125 "dylib" => CrateType::Dylib,
126 "cdylib" => CrateType::Cdylib,
127 "staticlib" => CrateType::Staticlib,
128 "procmacro" => CrateType::ProcMacro,
129 _ => CrateType::Other(s.clone()),
130 }
131 }
132}
133
134impl fmt::Debug for CrateType {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 self.to_string().fmt(f)
137 }
138}
139
140impl serde::Serialize for CrateType {
141 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
142 where
143 S: serde::ser::Serializer,
144 {
145 self.to_string().serialize(s)
146 }
147}