[][src]Crate cargo_rustc_cfg

The goal of this library, a.k.a. crate, is to provide access to the compiler configuration at Cargo build time of a project for use with third-party Cargo custom subcommands by running the cargo rustc --lib -- --print cfg command and parsing its output. This library is not recommended for build scripts as the compiler configuration information is available via Cargo environment variables that are passed to build scripts at run time.

If the Rust compiler (rustc) target is x86_64-pc-windows-msvc, then the output from the cargo rustc --lib -- --print cfg command will look similar to this:

PS C:\Path\to\Rust\Project> cargo rustc --lib -- --print cfg
  Compiling <PACKAGE> vX.X.X (<PACKAGE_PATH>)
debug_assertions
target_arch="x86_64"
target_endian="little"
target_env="msvc"
target_family="windows"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_os="windows"
target_pointer_width="64"
target_vendor="pc"
windows
  Finished dev [unoptimized + debuginfo] target(s) in 0.10s

where <PACKAGE> is replaced with the name of the Rust package, the vX.X.X is replaced with the Semantic Version number defined in the package's manifest (Cargo.toml), and the <PACKAGE_PATH> is replaced with the absolute path to the package's root directory. The output may vary depending on the rustc target and development environment.

This crate parses the above output and provides the Cfg and Target types for accessing the various values from the output. The values for any lines containing a key-value pair and prepended by the target_ string are available in the Target type with the double quotes, ", removed. Any lines that are not recognized and/or not a target key-value pair are stored (unaltered) and can be obtained with the Cfg::extras method.

The CargoRustcPrintCfg type can be used to customize the cargo rustc --lib -- --print cfg command.

Examples

Get the host configuration with Cargo modifications if the host is x86_64-pc-windows-msvc:

let cfg = Cfg::host()?;
assert_eq!(cfg.target().arch(), "x86_64");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), Some("msvc"));
assert_eq!(cfg.target().family(), Some("windows"));
assert_eq!(cfg.target().os(), "windows");
assert_eq!(cfg.target().pointer_width(), "64");
assert_eq!(cfg.target().vendor(), Some("pc"));

If the host is x86_64-pc-windows-gnu, then:

let cfg = Cfg::host()?;
assert_eq!(cfg.target().arch(), "x86_64");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), Some("gnu"));
assert_eq!(cfg.target().family(), Some("windows"));
assert_eq!(cfg.target().os(), "windows");
assert_eq!(cfg.target().pointer_width(), "64");
assert_eq!(cfg.target().vendor(), Some("pc"));

If the host is x86_64-unknown-linux-gnu, then:

let cfg = Cfg::host()?;
assert_eq!(cfg.target().arch(), "x86_64");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), None);
assert_eq!(cfg.target().family(), Some("unix"));
assert_eq!(cfg.target().os(), "os");
assert_eq!(cfg.target().pointer_width(), "64");
assert_eq!(cfg.target().vendor(), Some("unknown"));

If the host is x86_64-apple-darwin, then:

let cfg = Cfg::host()?;
assert_eq!(cfg.target().arch(), "x86_64");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), None);
assert_eq!(cfg.target().family(), Some("unix"));
assert_eq!(cfg.target().os(), "os");
assert_eq!(cfg.target().pointer_width(), "64");
assert_eq!(cfg.target().vendor(), Some("apple"));

If the host is i686-pc-windows-msvc, then:

let cfg = Cfg::host()?;
assert_eq!(cfg.target().arch(), "x86");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), Some("msvc"));
assert_eq!(cfg.target().family(), Some("windows"));
assert_eq!(cfg.target().os(), "windows");
assert_eq!(cfg.target().pointer_width(), "32");
assert_eq!(cfg.target().vendor(), Some("pc"));

If the host is i686-pc-windows-gnu, then:

let cfg = Cfg::host()?;
assert_eq!(cfg.target().arch(), "x86_64");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), Some("gnu"));
assert_eq!(cfg.target().family(), Some("windows"));
assert_eq!(cfg.target().os(), "windows");
assert_eq!(cfg.target().pointer_width(), "32");
assert_eq!(cfg.target().vendor(), Some("pc"));

If the host is i686-unknown-linux-gnu, then:

let cfg = Cfg::host()?;
assert_eq!(cfg.target().arch(), "x86");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), None);
assert_eq!(cfg.target().family(), Some("unix"));
assert_eq!(cfg.target().os(), "os");
assert_eq!(cfg.target().pointer_width(), "32");
assert_eq!(cfg.target().vendor(), Some("unknown"));

If the host is i686-apple-darwin, then:

let cfg = Cfg::host()?;
assert_eq!(cfg.target().arch(), "x86");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), None);
assert_eq!(cfg.target().family(), Some("unix"));
assert_eq!(cfg.target().os(), "os");
assert_eq!(cfg.target().pointer_width(), "32");
assert_eq!(cfg.target().vendor(), Some("apple"));

Get the configuration for a rustc target that is not the host, i.e. cross-compilation, using the CargoRustcPrintCfg type and the rustc_target method:

let cfg = CargoRustcPrintCfg::default()
    .rustc_target("i686-pc-windows-msvc")
    .execute()?;
assert_eq!(cfg.target().arch(), "x86");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), Some("msvc"));
assert_eq!(cfg.target().family(), Some("windows"));
assert_eq!(cfg.target().os(), "windows");
assert_eq!(cfg.target().pointer_width(), "32");
assert_eq!(cfg.target().vendor(), Some("pc"));

The above use-case is relatively common, but it is tedious to routinely use the CargoRustcPrintCfg builder. The Cfg::rustc_target method is available as a shorthand for the previous example:

let cfg = Cfg::rustc_target("i686-pc-windows-msvc")?;
assert_eq!(cfg.target().arch(), "x86");
assert_eq!(cfg.target().endian(), "little");
assert_eq!(cfg.target().env(), Some("msvc"));
assert_eq!(cfg.target().family(), Some("windows"));
assert_eq!(cfg.target().os(), "windows");
assert_eq!(cfg.target().pointer_width(), "32");
assert_eq!(cfg.target().vendor(), Some("pc"));

Regardless of using the long or short form to specify a rustc target, the rustc target must still be installed and available on the host system. It is recommended to use rustup and the rustup target add <TRIPLE> command to install rustc targets.

Structs

CargoRustcPrintCfg

A builder type for the cargo rustc --lib -- --print cfg command.

Cfg

A container for the parsed output from the cargo rustc --lib -- --print cfg command.

Target

A container for all lines from the output that are prefixed with the target_ string.

Enums

CargoTarget

The various types of Cargo targets.

Error

The error type for cargo-rustc-cfg operations and associated traits.

Constants

CARGO

The command line name of the Cargo application.

CARGO_VARIABLE

The environment variable name for the Cargo appplication.

RUSTC

The command line name of the Rust compiler subcommand for Cargo.