From c695dbfe101e52d0b4cf36324bfdc4ef55b6a125 Mon Sep 17 00:00:00 2001 From: Vivek Date: Tue, 24 Feb 2026 17:08:10 +0530 Subject: [PATCH 1/3] doc: clarify cfg! vs CARGO_CFG_* in build scripts --- src/doc/src/reference/build-scripts.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/src/reference/build-scripts.md b/src/doc/src/reference/build-scripts.md index 71509ba3af8..d78efb40b38 100644 --- a/src/doc/src/reference/build-scripts.md +++ b/src/doc/src/reference/build-scripts.md @@ -67,6 +67,19 @@ the source directory of the build script’s package. [build-env]: environment-variables.md#environment-variables-cargo-sets-for-build-scripts +> **Note:** When checking [configuration options] like `target_os` or `target_arch` +> in a build script, do not use the `cfg!` macro or `#[cfg]` attribute, these +> check the **host** machine (where the build script runs), not the **target** +> platform you're compiling for. This distinction matters when cross-compiling. +> +> Instead, read the corresponding [`CARGO_CFG_*`][build-env] environment variables, +> which correctly reflect the target's configuration. For a typed API, consider +> using the [`build-rs`] crate. See the [build script examples] for more details. + +[configuration options]: ../../reference/conditional-compilation.html +[`build-rs`]: https://crates.io/crates/build-rs +[build script examples]: build-script-examples.md#conditional-compilation + ## Outputs of the Build Script Build scripts may save any output files or intermediate artifacts in the From 9dbb29cd2640c8f90c5b74b6784104e11e160a49 Mon Sep 17 00:00:00 2001 From: Vivek Date: Tue, 24 Feb 2026 18:07:01 +0530 Subject: [PATCH 2/3] doc: clarify cfg! vs CARGO_CFG_* in build scripts --- src/doc/src/reference/environment-variables.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/src/reference/environment-variables.md b/src/doc/src/reference/environment-variables.md index e2da513d490..df1b180a097 100644 --- a/src/doc/src/reference/environment-variables.md +++ b/src/doc/src/reference/environment-variables.md @@ -365,6 +365,11 @@ let out_dir = env::var("OUT_DIR").unwrap(); > hence variables present in one target triple might not be available in the other. > > Some cfg values like `test` are not available. + > + > **Tip:** For a typed API to read these values, consider using the [`build-rs`] + > crate instead of parsing environment variables manually. Also note that + > `CARGO_CFG_*` variables should be used instead of the `cfg!` macro or `#[cfg]` + > attribute in build scripts, those check the *host* platform, not the *target*. * `OUT_DIR` --- the folder in which all output and intermediate artifacts should be placed. This folder is inside the build directory for the package being built, and it is unique for the package in question. Cargo does not clean or reset this @@ -429,6 +434,7 @@ let out_dir = env::var("OUT_DIR").unwrap(); [`release`]: profiles.md#release [`debug`]: profiles.md#debug [`opt-level`]: profiles.md#opt-level +[`build-rs`]: https://crates.io/crates/build-rs ## Environment variables Cargo sets for `cargo test` From b3882b18a726f4db1e1f09c185e667d508342586 Mon Sep 17 00:00:00 2001 From: Vivek Date: Tue, 24 Feb 2026 18:12:41 +0530 Subject: [PATCH 3/3] doc: add reading target configuration example --- .../src/reference/build-script-examples.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/doc/src/reference/build-script-examples.md b/src/doc/src/reference/build-script-examples.md index 567870c5c6c..5cd6578fb3e 100644 --- a/src/doc/src/reference/build-script-examples.md +++ b/src/doc/src/reference/build-script-examples.md @@ -430,6 +430,36 @@ already installed. // … rest of code that makes use of zlib. ``` +## Reading target configuration + +When a build script needs to make decisions based on the target platform, it should read the `CARGO_CFG_*` environment +variables rather than using `cfg!` or `#[cfg]` attributes. This is because +the build script is compiled for and runs on the *host* machine, while +`CARGO_CFG_*` variables reflect the *target* platform, an important distinction +when cross-compiling. +```rust,ignore +// build.rs + +fn main() { + // reads the TARGET configuration + let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + + if target_os == "windows" { + println!("cargo::rustc-link-lib=userenv"); + } else if target_os == "linux" { + println!("cargo::rustc-link-lib=pthread"); + } +} +``` + +Note that some configuration values may contain multiple values separated by +commas (for example, `CARGO_CFG_TARGET_FAMILY` may be `unix,wasm`). When +checking these values, be sure to handle this appropriately. + +For a more convenient, typed API, consider using the [`build-rs`] crate +which handles these details for you. + +[`build-rs`]: https://crates.io/crates/build-rs ## Conditional compilation