1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
//! <https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script>
//!
//! Build scripts communicate with Cargo by printing to stdout. Cargo will
//! interpret each line that starts with `cargo::` as an instruction that will
//! influence compilation of the package. All other lines are ignored.
//!
//! > The order of `cargo::` instructions printed by the build script may affect
//! > the order of arguments that `cargo` passes to `rustc`. In turn, the order
//! > of arguments passed to `rustc` may affect the order of arguments passed to
//! > the linker. Therefore, you will want to pay attention to the order of the
//! > build script’s instructions. For example, if object `foo` needs to link
//! > against library `bar`, you may want to make sure that library `bar`’s
//! > [`cargo::rustc-link-lib`] instruction appears _after_ instructions to link
//! > object `foo`.
/// The `rustc-link-arg` instruction tells Cargo to pass the [`-C link-arg=FLAG`
/// option] to the compiler, but only when building supported targets
/// (benchmarks, binaries, `cdylib` crates, examples, and tests). Its usage is
/// highly platform specific. It is useful to set the shared library version or
/// linker script.
///
/// [`cargo::rustc-link-lib`]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib
/// [`-C link-arg=FLAG` option]: https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
/// The `rustc-link-arg-bin` instruction tells Cargo to pass the [`-C
/// link-arg=FLAG` option] to the compiler, but only when building the binary
/// target with name `BIN`. Its usage is highly platform specific. It is useful
/// to set a linker script or other linker options.
///
/// [`-C link-arg=FLAG` option]: https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
/// The `rustc-link-arg-bins` instruction tells Cargo to pass the [`-C
/// link-arg=FLAG` option] to the compiler, but only when building a binary
/// target. Its usage is highly platform specific. It is useful to set a linker
/// script or other linker options.
///
/// [`-C link-arg=FLAG` option]: https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
/// The `rustc-link-lib` instruction tells Cargo to link the given library using
/// the compiler’s [`-l` flag]. This is typically used to link a native library
/// using [FFI].
///
/// The `LIB` string is passed directly to rustc, so it supports any syntax that
/// `-l` does. Currently the fully supported syntax for `LIB` is
/// `[KIND[:MODIFIERS]=]NAME[:RENAME]`.
///
/// The `-l` flag is only passed to the library target of the package, unless
/// there is no library target, in which case it is passed to all targets. This
/// is done because all other targets have an implicit dependency on the library
/// target, and the given library to link should only be included once. This
/// means that if a package has both a library and a binary target, the
/// _library_ has access to the symbols from the given lib, and the binary
/// should access them through the library target’s public API.
///
/// The optional `KIND` may be one of `dylib`, `static`, or `framework`. See the
/// [rustc book] for more detail.
///
/// [`-l` flag]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-l-link-lib
/// [FFI]: https://doc.rust-lang.org/nomicon/ffi.html
/// [rustc book]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-l-link-lib
/// The `rustc-link-arg-tests` instruction tells Cargo to pass the [`-C
/// link-arg=FLAG` option] to the compiler, but only when building a tests
/// target.
///
/// [`-C link-arg=FLAG` option]: https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
/// The `rustc-link-arg-examples` instruction tells Cargo to pass the [`-C
/// link-arg=FLAG` option] to the compiler, but only when building an examples
/// target.
///
/// [`-C link-arg=FLAG` option]: https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
/// The `rustc-link-arg-benches` instruction tells Cargo to pass the [`-C
/// link-arg=FLAG` option] to the compiler, but only when building a benchmark
/// target.
///
/// [`-C link-arg=FLAG` option]: https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
/// The `rustc-link-search` instruction tells Cargo to pass the [`-L` flag] to
/// the compiler to add a directory to the library search path.
///
/// The optional `KIND` may be one of `dependency`, `crate`, `native`,
/// `framework`, or `all`. See the [rustc book] for more detail.
///
/// These paths are also added to the [dynamic library search path environment
/// variable] if they are within the `OUT_DIR`. Depending on this behavior is
/// discouraged since this makes it difficult to use the resulting binary. In
/// general, it is best to avoid creating dynamic libraries in a build script
/// (using existing system libraries is fine).
///
/// [`-L` flag]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-l-search-path
/// [rustc book]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-l-search-path
/// [dynamic library search path environment variable]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#dynamic-library-paths
/// The `rustc-flags` instruction tells Cargo to pass the given space-separated
/// flags to the compiler. This only allows the `-l` and `-L` flags, and is
/// equivalent to using [`rustc-link-lib`] and [`rustc-link-search`].
///
/// [`rustc-link-lib`]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib
/// [`rustc-link-search`]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-search
/// The `rustc-cfg` instruction tells Cargo to pass the given value to the
/// [`--cfg` flag] to the compiler. This may be used for compile-time detection
/// of features to enable [conditional compilation]. Custom cfgs must either be
/// expected using the [`cargo::rustc-check-cfg`] instruction or usage will need
/// to allow the [`unexpected_cfgs`] lint to avoid unexpected cfgs warnings.
///
/// Note that this does _not_ affect Cargo’s dependency resolution. This cannot
/// be used to enable an optional dependency, or enable other Cargo features.
///
/// Be aware that [`Cargo features`] use the form `feature="foo"`. `cfg` values
/// passed with this flag are not restricted to that form, and may provide just
/// a single identifier, or any arbitrary key/value pair. For example, emitting
/// `cargo::rustc-cfg=abc` will then allow code to use `#[cfg(abc)]` (note the
/// lack of `feature=`). Or an arbitrary key/value pair may be used with an `=`
/// symbol like `cargo::rustc-cfg=my_component="foo"`. The key should be a Rust
/// identifier, the value should be a string.
///
/// [`--cfg` flag]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-cfg
/// [conditional compilation]: https://doc.rust-lang.org/reference/conditional-compilation.html
/// [`cargo::rustc-check-cfg`]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-check-cfg
/// [`unexpected_cfgs`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unexpected-cfgs
/// [`Cargo features`]: https://doc.rust-lang.org/cargo/reference/features.html
/// Add to the list of expected config names and values that is used when
/// checking the reachable cfg expressions with the [`unexpected_cfgs`] lint.
///
/// The syntax of CHECK_CFG mirrors the rustc [`--check-cfg` flag], see
/// [Checking conditional configurations] for more details.
///
/// The instruction can be used like this:
///
/// // build.rs
/// println!("cargo::rustc-check-cfg=cfg(foo, values(\"bar\"))");
/// if foo_bar_condition {
/// println!("cargo::rustc-cfg=foo=\"bar\"");
/// }
///
/// Note that all possible cfgs should be defined, regardless of which cfgs are
/// currently enabled. This includes all possible values of a given cfg name.
///
/// It is recommended to group the `cargo::rustc-check-cfg` and
/// [`cargo::rustc-cfg`] instructions as closely as possible in order to avoid
/// typos, missing check-cfg, stale cfgs…
///
/// See also the [conditional compilation] example.
///
/// [`unexpected_cfgs`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#unexpected-cfgs
/// [`--check-cfg` flag]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-check-cfg
/// [Checking conditional configurations]: https://doc.rust-lang.org/rustc/check-cfg.html
/// [`cargo::rustc-cfg`]: https://doc.rust-lang.org/rustc/command-line-arguments.html#option-cfg
/// [conditional compilation]: https://doc.rust-lang.org/cargo/reference/build-script-examples.html#conditional-compilation
/// The `rustc-env` instruction tells Cargo to set the given environment
/// variable when compiling the package. The value can be then retrieved by the
/// [`env!` macro] in the compiled crate. This is useful for embedding
/// additional metadata in crate’s code, such as the hash of git HEAD or the
/// unique identifier of a continuous integration server.
///
/// See also the [environment variables automatically included by Cargo].
///
/// > Note: These environment variables are also set when running an executable
/// > with `cargo run` or `cargo test`. However, this usage is discouraged since
/// > it ties the executable to Cargo’s execution environment. Normally, these
/// > environment variables should only be checked at compile-time with the
/// > `env!` macro.
///
/// [`env!` macro]: https://doc.rust-lang.org/std/macro.env.html
/// [environment variables automatically included by Cargo]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates
/// The `rustc-cdylib-link-arg` instruction tells Cargo to pass the [`-C
/// link-arg=FLAG` option] to the compiler, but only when building a `cdylib`
/// library target. Its usage is highly platform specific. It is useful to set
/// the shared library version or the runtime-path.
///
/// [`-C link-arg=FLAG` option]: https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
/// The `error` instruction tells Cargo to display an error after the build
/// script has finished running, and then fail the build.
///
/// > Note: Build script libraries should carefully consider if they want to use
/// > `cargo::error` versus returning a `Result`. It may be better to return a
/// > `Result`, and allow the caller to decide if the error is fatal or not. The
/// > caller can then decide whether or not to display the `Err` variant using
/// > `cargo::error`.
/// The `warning` instruction tells Cargo to display a warning after the build
/// script has finished running. Warnings are only shown for `path` dependencies
/// (that is, those you’re working on locally), so for example warnings printed
/// out in [crates.io] crates are not emitted by default, unless the build
/// fails. The `-vv` “very verbose” flag may be used to have Cargo display
/// warnings for all crates.
///
/// [crates.io]: https://crates.io/
/// The `rerun-if-changed` instruction tells Cargo to re-run the build script if
/// the file at the given path has changed. Currently, Cargo only uses the
/// filesystem last-modified “mtime” timestamp to determine if the file has
/// changed. It compares against an internal cached timestamp of when the build
/// script last ran.
///
/// If the path points to a directory, it will scan the entire directory for any
/// modifications.
///
/// If the build script inherently does not need to re-run under any
/// circumstance, then emitting `cargo::rerun-if-changed=build.rs` is a simple
/// way to prevent it from being re-run (otherwise, the default if no `rerun-if`
/// instructions are emitted is to scan the entire package directory for
/// changes). Cargo automatically handles whether or not the script itself needs
/// to be recompiled, and of course the script will be re-run after it has been
/// recompiled. Otherwise, specifying `build.rs` is redundant and unnecessary.
/// The `rerun-if-env-changed` instruction tells Cargo to re-run the build
/// script if the value of an environment variable of the given name has
/// changed.
///
/// Note that the environment variables here are intended for global environment
/// variables like `CC` and such, it is not possible to use this for environment
/// variables like `TARGET` that [Cargo sets for build scripts]. The environment
/// variables in use are those received by `cargo` invocations, not those
/// received by the executable of the build script.
///
/// [Cargo sets for build scripts]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
/// Build scripts can generate an arbitrary set of metadata in the form of
/// key-value pairs. This metadata is set with the `cargo::metadata=KEY=VALUE`
/// instruction.
///
/// The metadata is passed to the build scripts of *dependent* packages. For
/// example, if the package `foo` depends on `bar`, which links `baz`, then if
/// `bar` generates `key=value` as part of its build script metadata, then the
/// build script of `foo` will have the environment variables
/// `DEP_BAZ_KEY=value` (note that the value of the `links` key is used). See
/// the [“Using another `sys` crate”] for an example of how this can be used.
///
/// Note that metadata is only passed to immediate dependents, not transitive
/// dependents.
///
/// [“Using another `sys` crate”]: https://doc.rust-lang.org/cargo/reference/build-script-examples.html#using-another-sys-crate