Skip to content

Commit

Permalink
Add Cargo specific doc regarding his interaction with --check-cfg
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed May 17, 2024
1 parent 37c4a77 commit 17265f3
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
- [Instrumentation-based Code Coverage](instrument-coverage.md)
- [Linker-plugin-based LTO](linker-plugin-lto.md)
- [Checking conditional configurations](check-cfg.md)
- [Cargo specifics](check-cfg/cargo-specifics.md)
- [Exploit Mitigations](exploit-mitigations.md)
- [Symbol Mangling](symbol-mangling/index.md)
- [v0 Symbol Format](symbol-mangling/v0.md)
Expand Down
95 changes: 95 additions & 0 deletions src/doc/rustc/src/check-cfg/cargo-specifics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Cargo specifics - Checking conditional configurations

<!--
This page is the canonical place for describing the interaction between Cargo
and --check-cfg. It is placed in the rustc book rather than the Cargo book since
check-cfg is primarely a Rust/rustc feature, at least --check-cfg and the
unexpected_cfgs are owned by rustc, not Cargo.
-->

> This document is intented to summarize the principal ways Cargo interacts with
> the `unexpected_cfgs` lint and `--check-cfg` flag. It is not intended to provide
> individual details, for that refer to the [`--check-cfg` documentation](../check-cfg.md) and
> to the [Cargo book](../../cargo/index.html).
Cargo always enables [checking conditional configurations](../check-cfg.md) with Rust 1.80 and upper.

This is to help with verifying that the crate is correctly handling conditional compilation for
different target platforms or features. It ensures that the cfg settings are consistent between
what is intended and what is used, helping to catch potential bugs or errors early in the
development process.

This document express different ways users can declare expected cfgs, and in particular for
custom configs[^1] with Cargo as the build system.

[^1]: In Cargo point-of-view: a custom cfg is one that is neither defined by `rustc` nor by a Cargo
feature. Think of `tokio_unstable`, `has_foo`, ... but not `feature = "lasers"`, `unix` or
`debug_assertions`

## Cargo feature

*See the [`[features]` section in the Cargo book][cargo-features] for more details.*

With the `[features]` table Cargo provide a mechanism to express conditional compilation and
optional dependencies. Cargo *automatically* declares corresponding cfgs for every feature as
expected.

`Cargo.toml`:
```toml
[features]
serde = ["dep:serde"]
my_feature = []
```

[cargo-features]: ../../cargo/reference/features.html

## `check-cfg` in `[lints.rust]` table

<!-- Note that T-Cargo considers `[lints.rust.unexpected_cfgs.check-cfg]` to be an
implementation detail and is therefor not documented in Cargo, we therefor do that ourself -->

*See the [`[lints]` section in the Cargo book][cargo-lints-table] for more details.*

When using a custom config not set via a build-script, Cargo provides the custom lint config
`check-cfg` under `[lints.rust.unexpected_cfgs]`.

It can be used to set custom static [`--check-cfg`](../check-cfg.md) args, it is mainly useful when
the list of expected cfgs is known is advance.

`Cargo.toml`:
```toml
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(has_foo)'] }

# or

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = ['cfg(has_foo)']
```

[cargo-lints-table]: ../../cargo/reference/manifest.html#the-lints-section

## `cargo::rustc-check-cfg` for `build.rs`/build-script

*See the [`cargo::rustc-check-cfg` section in the Cargo book][cargo-rustc-check-cfg] for more details.*

When setting a custom config with [`cargo::rustc-cfg`][cargo-rustc-cfg], Cargo provides the
corrolary instruction: [`cargo::rustc-check-cfg`][cargo-rustc-check-cfg] to expect custom configs.

`build.rs`:
```rust
fn main() {
println!("cargo::rustc-check-cfg=cfg(has_foo)");
// ^^^^^^^^^^^^^^^^^^^^^^ new with Cargo 1.80
if has_foo() {
println!("cargo::rustc-cfg=has_foo");
}
}
```

> Each `cargo::rustc-cfg` should have an accompanying **unconditional** `cargo::rustc-check-cfg`
> directive to avoid warnings like this: `unexpected cfg condition name: has_foo`.
[cargo-rustc-cfg]: ../../cargo/reference/build-scripts.html#rustc-cfg
[cargo-rustc-check-cfg]: ../../cargo/reference/build-scripts.html#rustc-check-cfg

0 comments on commit 17265f3

Please sign in to comment.