1# Linkage 2 3> Note: This section is described more in terms of the compiler than of 4> the language. 5 6The compiler supports various methods to link crates together both 7statically and dynamically. This section will explore the various methods to 8link crates together, and more information about native libraries can be 9found in the [FFI section of the book][ffi]. 10 11[ffi]: ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code 12 13In one session of compilation, the compiler can generate multiple artifacts 14through the usage of either command line flags or the `crate_type` attribute. 15If one or more command line flags are specified, all `crate_type` attributes will 16be ignored in favor of only building the artifacts specified by command line. 17 18* `--crate-type=bin`, `#[crate_type = "bin"]` - A runnable executable will be 19 produced. This requires that there is a `main` function in the crate which 20 will be run when the program begins executing. This will link in all Rust and 21 native dependencies, producing a single distributable binary. 22 This is the default crate type. 23 24* `--crate-type=lib`, `#[crate_type = "lib"]` - A Rust library will be produced. 25 This is an ambiguous concept as to what exactly is produced because a library 26 can manifest itself in several forms. The purpose of this generic `lib` option 27 is to generate the "compiler recommended" style of library. The output library 28 will always be usable by rustc, but the actual type of library may change from 29 time-to-time. The remaining output types are all different flavors of 30 libraries, and the `lib` type can be seen as an alias for one of them (but the 31 actual one is compiler-defined). 32 33* `--crate-type=dylib`, `#[crate_type = "dylib"]` - A dynamic Rust library will 34 be produced. This is different from the `lib` output type in that this forces 35 dynamic library generation. The resulting dynamic library can be used as a 36 dependency for other libraries and/or executables. This output type will 37 create `*.so` files on Linux, `*.dylib` files on macOS, and `*.dll` files on 38 Windows. 39 40* `--crate-type=staticlib`, `#[crate_type = "staticlib"]` - A static system 41 library will be produced. This is different from other library outputs in that 42 the compiler will never attempt to link to `staticlib` outputs. The 43 purpose of this output type is to create a static library containing all of 44 the local crate's code along with all upstream dependencies. This output type 45 will create `*.a` files on Linux, macOS and Windows (MinGW), and `*.lib` files 46 on Windows (MSVC). This format is recommended for use in situations such as 47 linking Rust code into an existing non-Rust application 48 because it will not have dynamic dependencies on other Rust code. 49 50* `--crate-type=cdylib`, `#[crate_type = "cdylib"]` - A dynamic system 51 library will be produced. This is used when compiling 52 a dynamic library to be loaded from another language. This output type will 53 create `*.so` files on Linux, `*.dylib` files on macOS, and `*.dll` files on 54 Windows. 55 56* `--crate-type=rlib`, `#[crate_type = "rlib"]` - A "Rust library" file will be 57 produced. This is used as an intermediate artifact and can be thought of as a 58 "static Rust library". These `rlib` files, unlike `staticlib` files, are 59 interpreted by the compiler in future linkage. This essentially means 60 that `rustc` will look for metadata in `rlib` files like it looks for metadata 61 in dynamic libraries. This form of output is used to produce statically linked 62 executables as well as `staticlib` outputs. 63 64* `--crate-type=proc-macro`, `#[crate_type = "proc-macro"]` - The output 65 produced is not specified, but if a `-L` path is provided to it then the 66 compiler will recognize the output artifacts as a macro and it can be loaded 67 for a program. Crates compiled with this crate type must only export 68 [procedural macros]. The compiler will automatically set the `proc_macro` 69 [configuration option]. The crates are always compiled with the same target 70 that the compiler itself was built with. For example, if you are executing 71 the compiler from Linux with an `x86_64` CPU, the target will be 72 `x86_64-unknown-linux-gnu` even if the crate is a dependency of another crate 73 being built for a different target. 74 75Note that these outputs are stackable in the sense that if multiple are 76specified, then the compiler will produce each form of output at once without 77having to recompile. However, this only applies for outputs specified by the 78same method. If only `crate_type` attributes are specified, then they will all 79be built, but if one or more `--crate-type` command line flags are specified, 80then only those outputs will be built. 81 82With all these different kinds of outputs, if crate A depends on crate B, then 83the compiler could find B in various different forms throughout the system. The 84only forms looked for by the compiler, however, are the `rlib` format and the 85dynamic library format. With these two options for a dependent library, the 86compiler must at some point make a choice between these two formats. With this 87in mind, the compiler follows these rules when determining what format of 88dependencies will be used: 89 901. If a static library is being produced, all upstream dependencies are 91 required to be available in `rlib` formats. This requirement stems from the 92 reason that a dynamic library cannot be converted into a static format. 93 94 Note that it is impossible to link in native dynamic dependencies to a static 95 library, and in this case warnings will be printed about all unlinked native 96 dynamic dependencies. 97 982. If an `rlib` file is being produced, then there are no restrictions on what 99 format the upstream dependencies are available in. It is simply required that 100 all upstream dependencies be available for reading metadata from. 101 102 The reason for this is that `rlib` files do not contain any of their upstream 103 dependencies. It wouldn't be very efficient for all `rlib` files to contain a 104 copy of `libstd.rlib`! 105 1063. If an executable is being produced and the `-C prefer-dynamic` flag is not 107 specified, then dependencies are first attempted to be found in the `rlib` 108 format. If some dependencies are not available in an rlib format, then 109 dynamic linking is attempted (see below). 110 1114. If a dynamic library or an executable that is being dynamically linked is 112 being produced, then the compiler will attempt to reconcile the available 113 dependencies in either the rlib or dylib format to create a final product. 114 115 A major goal of the compiler is to ensure that a library never appears more 116 than once in any artifact. For example, if dynamic libraries B and C were 117 each statically linked to library A, then a crate could not link to B and C 118 together because there would be two copies of A. The compiler allows mixing 119 the rlib and dylib formats, but this restriction must be satisfied. 120 121 The compiler currently implements no method of hinting what format a library 122 should be linked with. When dynamically linking, the compiler will attempt to 123 maximize dynamic dependencies while still allowing some dependencies to be 124 linked in via an rlib. 125 126 For most situations, having all libraries available as a dylib is recommended 127 if dynamically linking. For other situations, the compiler will emit a 128 warning if it is unable to determine which formats to link each library with. 129 130In general, `--crate-type=bin` or `--crate-type=lib` should be sufficient for 131all compilation needs, and the other options are just available if more 132fine-grained control is desired over the output format of a crate. 133 134## Static and dynamic C runtimes 135 136The standard library in general strives to support both statically linked and 137dynamically linked C runtimes for targets as appropriate. For example the 138`x86_64-pc-windows-msvc` and `x86_64-unknown-linux-musl` targets typically come 139with both runtimes and the user selects which one they'd like. All targets in 140the compiler have a default mode of linking to the C runtime. Typically targets 141are linked dynamically by default, but there are exceptions which are static by 142default such as: 143 144* `arm-unknown-linux-musleabi` 145* `arm-unknown-linux-musleabihf` 146* `armv7-unknown-linux-musleabihf` 147* `i686-unknown-linux-musl` 148* `x86_64-unknown-linux-musl` 149 150The linkage of the C runtime is configured to respect the `crt-static` target 151feature. These target features are typically configured from the command line 152via flags to the compiler itself. For example to enable a static runtime you 153would execute: 154 155```sh 156rustc -C target-feature=+crt-static foo.rs 157``` 158 159whereas to link dynamically to the C runtime you would execute: 160 161```sh 162rustc -C target-feature=-crt-static foo.rs 163``` 164 165Targets which do not support switching between linkage of the C runtime will 166ignore this flag. It's recommended to inspect the resulting binary to ensure 167that it's linked as you would expect after the compiler succeeds. 168 169Crates may also learn about how the C runtime is being linked. Code on MSVC, for 170example, needs to be compiled differently (e.g. with `/MT` or `/MD`) depending 171on the runtime being linked. This is exported currently through the 172[`cfg` attribute `target_feature` option]: 173 174```rust 175#[cfg(target_feature = "crt-static")] 176fn foo() { 177 println!("the C runtime should be statically linked"); 178} 179 180#[cfg(not(target_feature = "crt-static"))] 181fn foo() { 182 println!("the C runtime should be dynamically linked"); 183} 184``` 185 186Also note that Cargo build scripts can learn about this feature through 187[environment variables][cargo]. In a build script you can detect the linkage 188via: 189 190```rust 191use std::env; 192 193fn main() { 194 let linkage = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or(String::new()); 195 196 if linkage.contains("crt-static") { 197 println!("the C runtime will be statically linked"); 198 } else { 199 println!("the C runtime will be dynamically linked"); 200 } 201} 202``` 203 204[cargo]: ../cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts 205 206To use this feature locally, you typically will use the `RUSTFLAGS` environment 207variable to specify flags to the compiler through Cargo. For example to compile 208a statically linked binary on MSVC you would execute: 209 210```sh 211RUSTFLAGS='-C target-feature=+crt-static' cargo build --target x86_64-pc-windows-msvc 212``` 213 214[`cfg` attribute `target_feature` option]: conditional-compilation.md#target_feature 215[configuration option]: conditional-compilation.md 216[procedural macros]: procedural-macros.md 217