1
1
# Linkage
2
2
3
+ r[ link]
4
+
3
5
> Note: This section is described more in terms of the compiler than of
4
6
> the language.
5
7
8
+ r[ link.intro]
6
9
The compiler supports various methods to link crates together both
7
10
statically and dynamically. This section will explore the various methods to
8
11
link crates together, and more information about native libraries can be
9
12
found in the [ FFI section of the book] [ ffi ] .
10
13
11
14
[ ffi ] : ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code
12
15
16
+ r[ link.type]
13
17
In one session of compilation, the compiler can generate multiple artifacts
14
18
through the usage of either command line flags or the ` crate_type ` attribute.
15
19
If one or more command line flags are specified, all ` crate_type ` attributes will
16
20
be ignored in favor of only building the artifacts specified by command line.
17
21
22
+ r[ link.bin]
18
23
* ` --crate-type=bin ` , ` #![crate_type = "bin"] ` - A runnable executable will be
19
24
produced. This requires that there is a ` main ` function in the crate which
20
25
will be run when the program begins executing. This will link in all Rust and
21
26
native dependencies, producing a single distributable binary.
22
27
This is the default crate type.
23
28
29
+ r[ link.lib]
24
30
* ` --crate-type=lib ` , ` #![crate_type = "lib"] ` - A Rust library will be produced.
25
31
This is an ambiguous concept as to what exactly is produced because a library
26
32
can manifest itself in several forms. The purpose of this generic ` lib ` option
@@ -30,13 +36,15 @@ be ignored in favor of only building the artifacts specified by command line.
30
36
libraries, and the ` lib ` type can be seen as an alias for one of them (but the
31
37
actual one is compiler-defined).
32
38
39
+ r[ link.dylib]
33
40
* ` --crate-type=dylib ` , ` #![crate_type = "dylib"] ` - A dynamic Rust library will
34
41
be produced. This is different from the ` lib ` output type in that this forces
35
42
dynamic library generation. The resulting dynamic library can be used as a
36
43
dependency for other libraries and/or executables. This output type will
37
44
create ` *.so ` files on Linux, ` *.dylib ` files on macOS, and ` *.dll ` files on
38
45
Windows.
39
46
47
+ r[ link.staticlib]
40
48
* ` --crate-type=staticlib ` , ` #![crate_type = "staticlib"] ` - A static system
41
49
library will be produced. This is different from other library outputs in that
42
50
the compiler will never attempt to link to ` staticlib ` outputs. The
@@ -62,12 +70,14 @@ be ignored in favor of only building the artifacts specified by command line.
62
70
dependencies that is not actually used (e.g. ` --gc-sections ` or ` -dead_strip `
63
71
for macOS).
64
72
73
+ r[ link.cdylib]
65
74
* ` --crate-type=cdylib ` , ` #![crate_type = "cdylib"] ` - A dynamic system
66
75
library will be produced. This is used when compiling
67
76
a dynamic library to be loaded from another language. This output type will
68
77
create ` *.so ` files on Linux, ` *.dylib ` files on macOS, and ` *.dll ` files on
69
78
Windows.
70
79
80
+ r[ link.rlib]
71
81
* ` --crate-type=rlib ` , ` #![crate_type = "rlib"] ` - A "Rust library" file will be
72
82
produced. This is used as an intermediate artifact and can be thought of as a
73
83
"static Rust library". These ` rlib ` files, unlike ` staticlib ` files, are
@@ -76,6 +86,7 @@ be ignored in favor of only building the artifacts specified by command line.
76
86
in dynamic libraries. This form of output is used to produce statically linked
77
87
executables as well as ` staticlib ` outputs.
78
88
89
+ r[ link.proc-macro]
79
90
* ` --crate-type=proc-macro ` , ` #![crate_type = "proc-macro"] ` - The output
80
91
produced is not specified, but if a ` -L ` path is provided to it then the
81
92
compiler will recognize the output artifacts as a macro and it can be loaded
@@ -87,13 +98,15 @@ be ignored in favor of only building the artifacts specified by command line.
87
98
` x86_64-unknown-linux-gnu ` even if the crate is a dependency of another crate
88
99
being built for a different target.
89
100
101
+ r[ link.repetition]
90
102
Note that these outputs are stackable in the sense that if multiple are
91
103
specified, then the compiler will produce each form of output without
92
104
having to recompile. However, this only applies for outputs specified by the
93
105
same method. If only ` crate_type ` attributes are specified, then they will all
94
106
be built, but if one or more ` --crate-type ` command line flags are specified,
95
107
then only those outputs will be built.
96
108
109
+ r[ link.dependency]
97
110
With all these different kinds of outputs, if crate A depends on crate B, then
98
111
the compiler could find B in various different forms throughout the system. The
99
112
only forms looked for by the compiler, however, are the ` rlib ` format and the
@@ -102,6 +115,7 @@ compiler must at some point make a choice between these two formats. With this
102
115
in mind, the compiler follows these rules when determining what format of
103
116
dependencies will be used:
104
117
118
+ r[ link.dependency-staticlib]
105
119
1 . If a static library is being produced, all upstream dependencies are
106
120
required to be available in ` rlib ` formats. This requirement stems from the
107
121
reason that a dynamic library cannot be converted into a static format.
@@ -110,6 +124,8 @@ dependencies will be used:
110
124
library, and in this case warnings will be printed about all unlinked native
111
125
dynamic dependencies.
112
126
127
+ r[ link.dependency-rlib]
128
+
113
129
2 . If an ` rlib ` file is being produced, then there are no restrictions on what
114
130
format the upstream dependencies are available in. It is simply required that
115
131
all upstream dependencies be available for reading metadata from.
@@ -118,11 +134,15 @@ dependencies will be used:
118
134
dependencies. It wouldn't be very efficient for all ` rlib ` files to contain a
119
135
copy of ` libstd.rlib ` !
120
136
137
+ r[ link.dependency-prefer-dynamic]
138
+
121
139
3 . If an executable is being produced and the ` -C prefer-dynamic ` flag is not
122
140
specified, then dependencies are first attempted to be found in the ` rlib `
123
141
format. If some dependencies are not available in an rlib format, then
124
142
dynamic linking is attempted (see below).
125
143
144
+ r[ link.dependency-dynamic]
145
+
126
146
4 . If a dynamic library or an executable that is being dynamically linked is
127
147
being produced, then the compiler will attempt to reconcile the available
128
148
dependencies in either the rlib or dylib format to create a final product.
@@ -148,6 +168,9 @@ fine-grained control is desired over the output format of a crate.
148
168
149
169
## Static and dynamic C runtimes
150
170
171
+ r[ link.crt]
172
+
173
+ r[ link.crt.intro]
151
174
The standard library in general strives to support both statically linked and
152
175
dynamically linked C runtimes for targets as appropriate. For example the
153
176
` x86_64-pc-windows-msvc ` and ` x86_64-unknown-linux-musl ` targets typically come
@@ -162,6 +185,7 @@ default such as:
162
185
* ` i686-unknown-linux-musl `
163
186
* ` x86_64-unknown-linux-musl `
164
187
188
+ r[ link.crt.crt-static]
165
189
The linkage of the C runtime is configured to respect the ` crt-static ` target
166
190
feature. These target features are typically configured from the command line
167
191
via flags to the compiler itself. For example to enable a static runtime you
@@ -177,10 +201,12 @@ whereas to link dynamically to the C runtime you would execute:
177
201
rustc -C target-feature=-crt-static foo.rs
178
202
```
179
203
204
+ r[ link.crt.ineffective]
180
205
Targets which do not support switching between linkage of the C runtime will
181
206
ignore this flag. It's recommended to inspect the resulting binary to ensure
182
207
that it's linked as you would expect after the compiler succeeds.
183
208
209
+ r[ link.crt.target_feature]
184
210
Crates may also learn about how the C runtime is being linked. Code on MSVC, for
185
211
example, needs to be compiled differently (e.g. with ` /MT ` or ` /MD ` ) depending
186
212
on the runtime being linked. This is exported currently through the
0 commit comments