diff --git a/crates/metadata/lib.rs b/crates/metadata/lib.rs index 14f936344..17c0a1e18 100644 --- a/crates/metadata/lib.rs +++ b/crates/metadata/lib.rs @@ -267,10 +267,15 @@ impl Metadata { cargo_args.push("--no-default-features".into()); } - let mut all_rustdoc_args = self.rustdoc_args.clone(); + // Unconditionnaly set `--cfg docsrs` as it has become a de-facto way to + // distinguish docs.rs. + // + // See https://github.com/rust-lang/docs.rs/issues/2389. + let mut all_rustdoc_args = vec!["--cfg".into(), "docsrs".into()]; + all_rustdoc_args.extend_from_slice(&self.rustdoc_args); all_rustdoc_args.extend_from_slice(rustdoc_args); - if !self.rustc_args.is_empty() || !all_rustdoc_args.is_empty() { + if !self.rustc_args.is_empty() || all_rustdoc_args.len() > 2 { cargo_args.push("-Z".into()); cargo_args.push("unstable-options".into()); } @@ -655,14 +660,20 @@ mod test_targets { mod test_calculations { use super::*; - fn default_cargo_args() -> Vec { - vec!["rustdoc".into(), "--lib".into(), "-Zrustdoc-map".into()] + fn default_cargo_args(extra_args: &[String]) -> Vec { + let mut args = vec!["rustdoc".into(), "--lib".into(), "-Zrustdoc-map".into()]; + args.extend_from_slice(extra_args); + args.extend_from_slice(&[ + "--config".into(), + r#"build.rustdocflags=["--cfg", "docsrs"]"#.into(), + ]); + args } #[test] fn test_defaults() { let metadata = Metadata::default(); - assert_eq!(metadata.cargo_args(&[], &[]), default_cargo_args()); + assert_eq!(metadata.cargo_args(&[], &[]), default_cargo_args(&[])); let env = metadata.environment_variables(); assert_eq!(env.get("DOCS_RS").map(String::as_str), Some("1")); assert!(env.get("RUSTDOCFLAGS").is_none()); @@ -676,8 +687,7 @@ mod test_calculations { all_features: true, ..Metadata::default() }; - let mut expected_args = default_cargo_args(); - expected_args.push("--all-features".into()); + let expected_args = default_cargo_args(&["--all-features".into()]); assert_eq!(metadata.cargo_args(&[], &[]), expected_args); // no default features @@ -685,8 +695,7 @@ mod test_calculations { no_default_features: true, ..Metadata::default() }; - let mut expected_args = default_cargo_args(); - expected_args.push("--no-default-features".into()); + let expected_args = default_cargo_args(&["--no-default-features".into()]); assert_eq!(metadata.cargo_args(&[], &[]), expected_args); // allow passing both even though it's nonsense; cargo will give an error anyway @@ -695,9 +704,8 @@ mod test_calculations { no_default_features: true, ..Metadata::default() }; - let mut expected_args = default_cargo_args(); - expected_args.push("--all-features".into()); - expected_args.push("--no-default-features".into()); + let expected_args = + default_cargo_args(&["--all-features".into(), "--no-default-features".into()]); assert_eq!(metadata.cargo_args(&[], &[]), expected_args); // explicit empty vec @@ -711,6 +719,8 @@ mod test_calculations { "-Zrustdoc-map".into(), "--features".into(), String::new(), + "--config".into(), + r#"build.rustdocflags=["--cfg", "docsrs"]"#.into(), ]; assert_eq!(metadata.cargo_args(&[], &[]), expected_args); @@ -725,6 +735,8 @@ mod test_calculations { "-Zrustdoc-map".into(), "--features".into(), "some_feature".into(), + "--config".into(), + r#"build.rustdocflags=["--cfg", "docsrs"]"#.into(), ]; assert_eq!(metadata.cargo_args(&[], &[]), expected_args); @@ -739,6 +751,8 @@ mod test_calculations { "-Zrustdoc-map".into(), "--features".into(), "feature1 feature2".into(), + "--config".into(), + r#"build.rustdocflags=["--cfg", "docsrs"]"#.into(), ]; assert_eq!(metadata.cargo_args(&[], &[]), expected_args); @@ -761,7 +775,7 @@ mod test_calculations { "-Z".into(), "unstable-options".into(), "--config".into(), - r#"build.rustdocflags=["-Z", "unstable-options", "--static-root-path", "/", "--cap-lints", "warn"]"#.into(), + r#"build.rustdocflags=["--cfg", "docsrs", "-Z", "unstable-options", "--static-root-path", "/", "--cap-lints", "warn"]"#.into(), ]; assert_eq!(metadata.cargo_args(&[], &[]), expected_args); @@ -782,6 +796,8 @@ mod test_calculations { "-Ztarget-applies-to-host".into(), "--config".into(), "host.rustflags=[\"--cfg\", \"x\"]".into(), + "--config".into(), + "build.rustdocflags=[\"--cfg\", \"docsrs\"]".into(), ]; assert_eq!(metadata.cargo_args(&[], &[]), expected_args); @@ -794,6 +810,8 @@ mod test_calculations { String::from("rustdoc"), "--lib".into(), "-Zrustdoc-map".into(), + "--config".into(), + "build.rustdocflags=[\"--cfg\", \"docsrs\"]".into(), "-Zbuild-std".into(), ]; assert_eq!(metadata.cargo_args(&[], &[]), expected_args); diff --git a/templates/core/about/builds.html b/templates/core/about/builds.html index 93a47f7f3..497c5ea28 100644 --- a/templates/core/about/builds.html +++ b/templates/core/about/builds.html @@ -29,6 +29,13 @@

Setting a README

Detecting Docs.rs

+

+ To recognize Docs.rs from your Rust code, you can test for the docsrs cfg, e.g.: + {% filter highlight(lang="rust") %}{% filter dedent(levels=3) -%} + #[cfg(docsrs)] + mod documentation; + {%- endfilter %}{% endfilter %} +

To recognize Docs.rs from build.rs files, you can test for the environment variable DOCS_RS, e.g.: {% filter highlight(lang="rust") %}{% filter dedent(levels=3) -%} @@ -48,9 +55,9 @@

Cross-compiling

You can configure how your crate is built by adding package metadata to your Cargo.toml, e.g.: {% filter highlight(lang="toml") %}{% filter dedent -%} [package.metadata.docs.rs] - rustc-args = ["--cfg", "docsrs"] + rustc-args = ["--cfg", "my_cfg"] {%- endfilter %}{% endfilter %} - Here, the compiler arguments are set so that #[cfg(docsrs)] (not to be confused with #[cfg(doc)]) can be used for conditional compilation. + Here, the compiler arguments are set so that #[cfg(my_cfg)] (not to be confused with #[cfg(doc)]) can be used for conditional compilation. This approach is also useful for setting cargo features.