My crate builds C++ with cmake inside of build scripts.
But for building documentation (with cargo doc) I would want to skip the C++ part: as required libraries are not available in the pipeline at that point.
I can do this with a feature flag and build docs like cargo doc --features build-docs, but this seems redundant.
Maybe cargo doc already sets some envars I can reliably check against?
jofas
September 18, 2025, 1:55pm
2
I haven't tried this in a build script before, but rustdoc sets --cfg doc for conditional compilation, allowing you to use #[cfg(doc)] in your code. I assume this can be used in your build script, e.g. by guarding the part that builds the CPP dependencies behind a #[cfg(not(doc))].
Thanks!
fn main() {
#[cfg(doc)]
{
return;
}
panic!("Feature not enabled");
}
Results in:
$ cargo doc
...
thread 'main' panicked at crates\test_crate\build.rs:8:5:
Feature not enabled
It does work, however, when I build documentation for the test_crate directly:
$ cargo doc -p test_crate
...
Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.56s
UPDATE:
Actually, no, cargo doc -p doesn't run build.rs at all.
jofas
September 18, 2025, 2:14pm
6
Looks like I was wrong and --cfg doc is not passed to the build script:
opened 11:32PM - 26 Oct 20 UTC
C-bug
Command-doc
Command-rustdoc
A-build-scripts
S-needs-design
**Problem**
Some packages such as `llvm-sys` have [workarounds](https://gitlab… .com/taricorp/llvm-sys.rs/-/merge_requests/2) that allow their docs to build on [docs.rs](https://docs.rs) despite the fact that no usable binary can be generated (in this case because it relies on a platform binary that is not present on docs.rs). Essentially it uses detection of `#[cfg(doc)]` to allow builds to succeed when they would otherwise fail. This works well today.
However, when this project is a dependency in another project, `cargo doc` will not just run `rustdoc`, it will also invoke `rustc` to perform a check build. This bypasses any `#[cfg(doc)]` protections because it runs without `--cfg doc`. It is currently not possible to detect that your crate is being compiled in `check` mode as part of a larger `doc` run. The desired build characteristics, however, are the same. We don't need a working binary, and we're invoking the compiler for the purpose of docs.
It's also very strange to have a case where `cargo doc` works on a project but not when that project is a dependency.
I've produced a minimal example of this that demonstrates the issue without all the cruft of thinking about LLVM and system dependencies.
**Steps**
1. Clone [`djrenren/cargo-doc-failure`](https://github.com/djrenren/cargo-doc-failure)
2. `cd app`
3. `cargo rustdoc`
Notice this fails while `cargo rustdoc` in the dependency succeeds.
**Current Workarounds**
Local workaround:
`$ RUSTFLAGS="--cfg doc" cargo doc`
Docs.rs workaround:
Cargo.toml:
```toml
[package.metadata.docs.rs]
rustc-args = [ "--cfg" , "doc"]
```
**Suggested Solution(s)**
1. As suggested in the title of the issue, pass the doc config flag in while doing check builds as part of `cargo rustdoc`
2. Provide a standard way to add `cfg` flags to libraries when built as part of rustdoc. That is, standardize what docs.rs already does so that it works locally as well.
**Notes**
This occurs on all cargo versions I've been able to find so the version is largely irrelevant, but let's say latest stable 1.47.0
Passing a doc flag by default to check builds could produce strange results if downstream crates use doc cfg's to change the interface of their crate, which may be a point in favor of solution 2.
1 Like
kornel
September 19, 2025, 1:10am
10
Builds on docs.rs set DOCS_RS env var.
system
Closed
December 18, 2025, 1:10am
11
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.