Skip to content

Commit a66f41d

Browse files
committed
rustc-book: Document -C target-feature="+crt-static"
1 parent 7f3b3df commit a66f41d

File tree

2 files changed

+75
-9
lines changed

2 files changed

+75
-9
lines changed

src/doc/rustc/src/codegen-options/index.md

+74-9
Original file line numberDiff line numberDiff line change
@@ -402,12 +402,35 @@ machine. Each target has a default base CPU.
402402

403403
## target-feature
404404

405-
Individual targets will support different features; this flag lets you control
406-
enabling or disabling a feature. Each feature should be prefixed with a `+` to
407-
enable it or `-` to disable it. Separate multiple features with commas.
405+
This option controls either CPU instruction set extensions that can be used during code generation,
406+
or static linking.
408407

409-
To see the valid options and an example of use, run `rustc --print
410-
target-features`.
408+
In both cases `-C target-feature=+x` enables feature `x` and `-C target-feature=-x` disables it.
409+
410+
Multiple features can be specified by separating them with commas - `-C target-feature=+x,-y`.
411+
412+
For each supported feature `x` `target_feature = "x"` becomes a `cfg` predicate usable early during
413+
compilation.
414+
Code configured with `cfg(target_feature = "x")` is kept if the feature `x` is enabled,
415+
and removed otherwise.
416+
417+
If the enabled feature is not supported for the current target, the behavior is unspecified.
418+
<!-- There are multiple bugs here
419+
- Unknown CPU features go straight to LLVM and appear as LLVM warnings.
420+
- At configure time `crt-static` predicate is set even if the target doesn't support `crt-static`.
421+
- At link time `crt-static` is sometimes ignored
422+
if the target doesn't support it and sometimes not.
423+
-->
424+
425+
To see the valid features and an example of use, run `rustc --print target-features`.
426+
427+
#### CPU instruction set extensions
428+
429+
Target features for CPU instruction set extensions can enable or disable
430+
architecture-dependent CPU features, like `+neon` or `-sse`.
431+
432+
Each target and [`target-cpu`](#target-cpu) has a default set of enabled
433+
features.
411434

412435
Using this flag is unsafe and might result in [undefined runtime
413436
behavior](../targets/known-issues.md).
@@ -416,11 +439,53 @@ See also the [`target_feature`
416439
attribute](../../reference/attributes/codegen.md#the-target_feature-attribute)
417440
for controlling features per-function.
418441

419-
This also supports the feature `+crt-static` and `-crt-static` to control
420-
[static C runtime linkage](../../reference/linkage.html#static-and-dynamic-c-runtimes).
442+
#### Static linking
421443

422-
Each target and [`target-cpu`](#target-cpu) has a default set of enabled
423-
features.
444+
Target feature `crt-static` can be used to enable or disable static linking,
445+
with the default depending on the current target.
446+
`-C target-feature=+crt-static` is similar to `-static` in other compilers,
447+
standard C library in particular is linked statically in this case.
448+
449+
The exact meaning of `+crt-static` depends heavily
450+
on the current target and the produced crate type.
451+
452+
- ELF-based executables.
453+
If the target supports statically linked executables,
454+
then the linker will be instructed (`-static`) to produce one.
455+
The executable will be self-contained,
456+
will contain code from all the used libraries, including `libc`, inside it,
457+
and will be able to run without a dynamic loader (no `INTERP` header).
458+
459+
If the target doesn't support both position-independent and statically linked executables,
460+
then `-C target-feature=+crt-static` "wins" over `-C relocation-model=pic`,
461+
and the linker is instructed (`-static`) to produce a statically linked
462+
but not position-independent executable.
463+
464+
- ELF-based shared libraries.
465+
If the target supports statically linked shared libraries,
466+
then the linker will be instructed (`-shared -static`) to produce one.
467+
The shared library will contain code from all the used libraries, including `libc`, inside it.
468+
This option is not widely supported or used.
469+
470+
- PE-based executables (Windows).
471+
The produced executable will contain code from all the user-level libraries, including
472+
[C Run-Time Libraries (CRT)](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features),
473+
but may still link dynamically to system libraries like `kernel32.dll`.
474+
475+
- PE-based shared libraries (Windows).
476+
The produced shared library will contain code from all the user-level libraries, including
477+
[C Run-Time Libraries (CRT)](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features),
478+
but may still link dynamically to system libraries like `kernel32.dll`.
479+
480+
*WARNING!* If some libraries (native or Rust crates) in the dependency tree exist only in the
481+
dynamic variant they may be linked dynamically breaking the self-contained-ness property,
482+
re-adding the `INTERP` header for ELF executables, and possibly working incorrectly due to mismatch
483+
between dynamically linked libraries and injected startup objects specific to static linking.
484+
A request to turn this case into an error is tracked in
485+
[issue #39998](https://github.com/rust-lang/rust/issues/39998).
486+
487+
An alternative description of this feature can be found in the
488+
[reference](../../reference/linkage.html#static-and-dynamic-c-runtimes).
424489

425490
## bitcode-in-rlib
426491

src/librustc_interface/util.rs

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub fn add_configuration(
4848

4949
cfg.extend(codegen_backend.target_features(sess).into_iter().map(|feat| (tf, Some(feat))));
5050

51+
// FIXME: The predicate is currently set even if the target doesn't support `crt-static`.
5152
if sess.crt_static_feature(None) {
5253
cfg.insert((tf, Some(Symbol::intern("crt-static"))));
5354
}

0 commit comments

Comments
 (0)