Skip to content

Commit 14bb861

Browse files
authored
Merge pull request rust-lang#17 from alexcrichton/crt-static
Add documentation for crt-static
2 parents 9e46a30 + 4530f5b commit 14bb861

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

src/linkage.md

+80
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,83 @@ dependencies will be used:
125125
In general, `--crate-type=bin` or `--crate-type=lib` should be sufficient for
126126
all compilation needs, and the other options are just available if more
127127
fine-grained control is desired over the output format of a Rust crate.
128+
129+
## Static and dynamic C runtimes
130+
131+
The standard library in general strives to support both statically linked and
132+
dynamically linked C runtimes for targets as appropriate. For example the
133+
`x86_64-pc-windows-msvc` and `x86_64-unknown-linux-musl` targets typically come
134+
with both runtimes and the user selects which one they'd like. All targets in
135+
the compiler have a default mode of linking to the C runtime. Typicall targets
136+
linked dynamically by default, but there are exceptions which are static by
137+
default such as:
138+
139+
* `arm-unknown-linux-musleabi`
140+
* `arm-unknown-linux-musleabihf`
141+
* `armv7-unknown-linux-musleabihf`
142+
* `i686-unknown-linux-musl`
143+
* `x86_64-unknown-linux-musl`
144+
145+
The linkage of the C runtime is configured to respect the `crt-static` target
146+
feature. These target features are typically configured from the command line
147+
via flags to the compiler itself. For example to enable a static runtime you
148+
would execute:
149+
150+
```notrust
151+
rustc -C target-feature=+crt-static foo.rs
152+
```
153+
154+
whereas to link dynamically to the C runtime you would execute:
155+
156+
```notrust
157+
rustc -C target-feature=-crt-static foo.rs
158+
```
159+
160+
Targets which do not support switching between linkage of the C runtime will
161+
ignore this flag. It's recommended to inspect the resulting binary to ensure
162+
that it's linked as you would expect after the compiler succeeds.
163+
164+
Crates may also learn about how the C runtime is being linked. Code on MSVC, for
165+
example, needs to be compiled differently (e.g. with `/MT` or `/MD`) depending
166+
on the runtime being linked. This is exported currently through the
167+
`target_feature` attribute (note this is a nightly feature):
168+
169+
```rust,ignore
170+
#[cfg(target_feature = "crt-static")]
171+
fn foo() {
172+
println!("the C runtime should be statically linked");
173+
}
174+
175+
#[cfg(not(target_feature = "crt-static"))]
176+
fn foo() {
177+
println!("the C runtime should be dynamically linked");
178+
}
179+
```
180+
181+
Also note that Cargo build scripts can learn about this feature through
182+
[environment variables][cargo]. In a build script you can detect the linkage
183+
via:
184+
185+
```rust
186+
use std::env;
187+
188+
fn main() {
189+
let linkage = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or(String::new());
190+
191+
if linkage.contains("crt-static") {
192+
println!("the C runtime will be statically linked");
193+
} else {
194+
println!("the C runtime will be dynamically linked");
195+
}
196+
}
197+
```
198+
199+
[cargo]: http://doc.crates.io/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
200+
201+
To use this feature locally, you typically will use the `RUSTFLAGS` environment
202+
variable to specify flags to the compiler through Cargo. For example to compile
203+
a statically linked binary on MSVC you would execute:
204+
205+
```ignore,notrust
206+
RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-pc-windows-msvc
207+
```

0 commit comments

Comments
 (0)