The Rust file designated by the `build` command (relative to the package root)
will be compiled and invoked before anything else is compiled in the package,
-allowing your Rust code to depend on the built or generated artifacts. Note
-that there is no default value for `build`, it must be explicitly specified if
-required.
+allowing your Rust code to depend on the built or generated artifacts. Note that
+if you do not specify a value for `build` but your package root does contains a
+`"build.rs"` file, Cargo will compile and invoke this file for you.
Some example use cases of the build command are:
All the lines printed to stdout by a build script are written to a file like
`target/debug/build/<pkg>/output` (the precise location may depend on your
configuration). Any line that starts with `cargo:` is interpreted directly by
-Cargo. This line must be of the form `cargo:key=value`, like the examples
-below:
+Cargo. This line must be of the form `cargo:key=value`, like the examples below:
```notrust
# specially recognized by Cargo
cargo:rustc-link-lib=static=foo
cargo:rustc-link-search=native=/path/to/foo
cargo:rustc-cfg=foo
+cargo:rustc-env=FOO=bar
# arbitrary user-defined metadata
cargo:root=/path/to/foo
cargo:libdir=/path/to/foo/lib
cargo:include=/path/to/foo/include
```
+On the other hand, lines printed to stderr are written to a file like
+`target/debug/build/<pkg>/stderr` but are not interpreted by cargo.
+
There are a few special keys that Cargo recognizes, some affecting how the
crate is built:
* `rustc-cfg=FEATURE` indicates that the specified feature will be passed as a
`--cfg` flag to the compiler. This is often useful for performing compile-time
detection of various features.
+* `rustc-env=VAR=VALUE` indicates that the specified environment variable
+ will be added to the environment which the compiler is run within.
+ 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.
* `rerun-if-changed=PATH` is a path to a file or directory which indicates that
the build script should be re-run if it changes (detected by a more-recent
last-modified timestamp on the file). Normally build scripts are re-run if
of the directory itself (which corresponds to some types of changes within the
directory, depending on platform) will trigger a rebuild. To request a re-run
on any changes within an entire directory, print a line for the directory and
- another line for everything inside it, recursively.)
+ another line for everything inside it, recursively.)
Note that if the build script itself (or one of its dependencies) changes,
then it's rebuilt and rerun unconditionally, so
`cargo:rerun-if-changed=build.rs` is almost always redundant (unless you
want to ignore changes in all other files except for `build.rs`).
+* `rerun-if-env-changed=VAR` is the name of an environment variable which
+ indicates that if the environment variable's value changes the build script
+ should be rerun. This basically behaves the same as `rerun-if-changed` except
+ that it works with environment variables instead. Note that the environment
+ variables here are intended for global environment variables like `CC` and
+ such, it's not necessary to use this for env vars like `TARGET` that Cargo
+ sets. Also note that if `rerun-if-env-changed` is printed out then Cargo will
+ *only* rerun the build script if those environment variables change or if
+ files printed out by `rerun-if-changed` change.
+
* `warning=MESSAGE` is a message that will be printed to the main console after
a build script has finished running. Warnings are only shown for path
dependencies (that is, those you're working on locally), so for example
possible for consumers.
As an example to follow, let’s take a look at one of [Cargo’s own
-dependencies][git2-rs], [libgit2][libgit2]. This library has a number of
+dependencies][git2-rs], [libgit2][libgit2]. The C library has a number of
constraints:
[git2-rs]: https://github.com/alexcrichton/git2-rs/tree/master/libgit2-sys
* It can be built from source using `cmake`.
To visualize what’s going on here, let’s take a look at the manifest for the
-relevant Cargo package.
+relevant Cargo package that links to the native C library.
```toml
[package]
worth noting that this example has a `links` entry which indicates that the
crate (`libgit2-sys`) links to the `git2` native library.
-Here we also see the unconditional dependency on `libssh2` via the
-`libssh2-sys` crate, as well as a platform-specific dependency on `openssl-sys`
-for \*nix (other variants elided for now). It may seem a little counterintuitive
-to express *C dependencies* in the *Cargo manifest*, but this is actually using
-one of Cargo’s conventions in this space.
+Here we also see that we chose to have the Rust crate have an unconditional
+dependency on `libssh2` via the `libssh2-sys` crate, as well as a
+platform-specific dependency on `openssl-sys` for \*nix (other variants elided
+for now). It may seem a little counterintuitive to express *C dependencies* in
+the *Cargo manifest*, but this is actually using one of Cargo’s conventions in
+this space.
### `*-sys` Packages
Most of the functionality of this build script is easily refactorable into
common dependencies, so our build script isn’t quite as intimidating as this
-description! In reality it’s expected that build scripts are quite succinct by
+descriptions! In reality it’s expected that build scripts are quite succinct by
farming logic such as above to build dependencies.
The Rust file designated by the `build` command (relative to the package root)
will be compiled and invoked before anything else is compiled in the package,
-allowing your Rust code to depend on the built or generated artifacts. Note that
-if you do not specify a value for `build` but your package root does contains a
+allowing your Rust code to depend on the built or generated artifacts. Note that
+if you do not specify a value for `build` but your package root does contains a
`"build.rs"` file, Cargo will compile and invoke this file for you.
Some example use cases of the build command are:
## Outputs of the Build Script
-All the lines printed to stdout by a build script are written to a file like `target/debug/build/<pkg>/output` (the precise location may depend on your configuration). Any line that starts with `cargo:` is interpreted directly by Cargo. This line must be of the form `cargo:key=value`, like the examples below:
+All the lines printed to stdout by a build script are written to a file like
+`target/debug/build/<pkg>/output` (the precise location may depend on your
+configuration). Any line that starts with `cargo:` is interpreted directly by
+Cargo. This line must be of the form `cargo:key=value`, like the examples below:
```notrust
# specially recognized by Cargo