diff --git a/Cargo.lock b/Cargo.lock index dea2efe0edb..3c5d5941ed2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -462,7 +462,7 @@ dependencies = [ [[package]] name = "cargo-util-schemas" -version = "0.6.1" +version = "0.7.0" dependencies = [ "semver", "serde", diff --git a/Cargo.toml b/Cargo.toml index 0b0782099a7..a56f391867e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ cargo-platform = { path = "crates/cargo-platform", version = "0.1.5" } cargo-test-macro = { version = "0.3.0", path = "crates/cargo-test-macro" } cargo-test-support = { version = "0.5.0", path = "crates/cargo-test-support" } cargo-util = { version = "0.2.14", path = "crates/cargo-util" } -cargo-util-schemas = { version = "0.6.0", path = "crates/cargo-util-schemas" } +cargo-util-schemas = { version = "0.7.0", path = "crates/cargo-util-schemas" } cargo_metadata = "0.18.1" clap = "4.5.18" clap_complete = { version = "4.5.29", features = ["unstable-dynamic"] } diff --git a/crates/cargo-util-schemas/Cargo.toml b/crates/cargo-util-schemas/Cargo.toml index 9bd76226fbf..87d133b490a 100644 --- a/crates/cargo-util-schemas/Cargo.toml +++ b/crates/cargo-util-schemas/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-util-schemas" -version = "0.6.1" +version = "0.7.0" rust-version = "1.81" # MSRV:1 edition.workspace = true license.workspace = true diff --git a/crates/cargo-util-schemas/src/manifest/mod.rs b/crates/cargo-util-schemas/src/manifest/mod.rs index e3e7eca5e50..0fa5be5c12d 100644 --- a/crates/cargo-util-schemas/src/manifest/mod.rs +++ b/crates/cargo-util-schemas/src/manifest/mod.rs @@ -173,6 +173,7 @@ pub struct TomlPackage { pub publish: Option, pub workspace: Option, pub im_a_teapot: Option, + pub autolib: Option, pub autobins: Option, pub autoexamples: Option, pub autotests: Option, @@ -217,6 +218,7 @@ impl TomlPackage { publish: None, workspace: None, im_a_teapot: None, + autolib: None, autobins: None, autoexamples: None, autotests: None, diff --git a/src/cargo/util/toml/embedded.rs b/src/cargo/util/toml/embedded.rs index 618ff0036f5..ae072c10e96 100644 --- a/src/cargo/util/toml/embedded.rs +++ b/src/cargo/util/toml/embedded.rs @@ -8,7 +8,13 @@ use crate::GlobalContext; const DEFAULT_EDITION: crate::core::features::Edition = crate::core::features::Edition::LATEST_STABLE; -const AUTO_FIELDS: &[&str] = &["autobins", "autoexamples", "autotests", "autobenches"]; +const AUTO_FIELDS: &[&str] = &[ + "autolib", + "autobins", + "autoexamples", + "autotests", + "autobenches", +]; pub(super) fn expand_manifest( content: &str, @@ -289,6 +295,7 @@ path = "/home/me/test.rs" autobenches = false autobins = false autoexamples = false +autolib = false autotests = false build = false edition = "2021" @@ -324,6 +331,7 @@ time = "0.1.25" autobenches = false autobins = false autoexamples = false +autolib = false autotests = false build = false edition = "2021" @@ -359,6 +367,7 @@ time = "0.1.25" autobenches = false autobins = false autoexamples = false +autolib = false autotests = false build = false edition = "2021" diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 85dcc1a0540..54bd34d5ef8 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -334,6 +334,7 @@ fn normalize_toml( package_root, &original_package.name, edition, + original_package.autolib, warnings, )?; normalized_toml.bin = Some(targets::normalize_bins( @@ -624,6 +625,7 @@ fn normalize_package_toml<'a>( .map(manifest::InheritableField::Value), workspace: original_package.workspace.clone(), im_a_teapot: original_package.im_a_teapot.clone(), + autolib: Some(false), autobins: Some(false), autoexamples: Some(false), autotests: Some(false), diff --git a/src/cargo/util/toml/targets.rs b/src/cargo/util/toml/targets.rs index c80b31dba61..ebade72da19 100644 --- a/src/cargo/util/toml/targets.rs +++ b/src/cargo/util/toml/targets.rs @@ -129,48 +129,63 @@ pub fn normalize_lib( package_root: &Path, package_name: &str, edition: Edition, + autodiscover: Option, warnings: &mut Vec, ) -> CargoResult> { - let inferred = inferred_lib(package_root); - let lib = original_lib.cloned().or_else(|| { - inferred.as_ref().map(|lib| TomlTarget { - path: Some(PathValue(lib.clone())), - ..TomlTarget::new() - }) - }); - let Some(mut lib) = lib else { return Ok(None) }; - lib.name - .get_or_insert_with(|| package_name.replace("-", "_")); + if is_normalized(original_lib, autodiscover) { + let Some(lib) = original_lib.cloned() else { + return Ok(None); + }; - // Check early to improve error messages - validate_lib_name(&lib, warnings)?; + // Check early to improve error messages + validate_lib_name(&lib, warnings)?; - validate_proc_macro(&lib, "library", edition, warnings)?; - validate_crate_types(&lib, "library", edition, warnings)?; + validate_proc_macro(&lib, "library", edition, warnings)?; + validate_crate_types(&lib, "library", edition, warnings)?; - if lib.path.is_none() { - if let Some(inferred) = inferred { - lib.path = Some(PathValue(inferred)); - } else { - let name = name_or_panic(&lib); - let legacy_path = Path::new("src").join(format!("{name}.rs")); - if edition == Edition::Edition2015 && package_root.join(&legacy_path).exists() { - warnings.push(format!( - "path `{}` was erroneously implicitly accepted for library `{name}`,\n\ - please rename the file to `src/lib.rs` or set lib.path in Cargo.toml", - legacy_path.display(), - )); - lib.path = Some(PathValue(legacy_path)); + Ok(Some(lib)) + } else { + let inferred = inferred_lib(package_root); + let lib = original_lib.cloned().or_else(|| { + inferred.as_ref().map(|lib| TomlTarget { + path: Some(PathValue(lib.clone())), + ..TomlTarget::new() + }) + }); + let Some(mut lib) = lib else { return Ok(None) }; + lib.name + .get_or_insert_with(|| package_name.replace("-", "_")); + + // Check early to improve error messages + validate_lib_name(&lib, warnings)?; + + validate_proc_macro(&lib, "library", edition, warnings)?; + validate_crate_types(&lib, "library", edition, warnings)?; + + if lib.path.is_none() { + if let Some(inferred) = inferred { + lib.path = Some(PathValue(inferred)); } else { - anyhow::bail!( - "can't find library `{name}`, \ + let name = name_or_panic(&lib); + let legacy_path = Path::new("src").join(format!("{name}.rs")); + if edition == Edition::Edition2015 && package_root.join(&legacy_path).exists() { + warnings.push(format!( + "path `{}` was erroneously implicitly accepted for library `{name}`,\n\ + please rename the file to `src/lib.rs` or set lib.path in Cargo.toml", + legacy_path.display(), + )); + lib.path = Some(PathValue(legacy_path)); + } else { + anyhow::bail!( + "can't find library `{name}`, \ rename file to `src/lib.rs` or specify lib.path", - ) + ) + } } } - } - Ok(Some(lib)) + Ok(Some(lib)) + } } #[tracing::instrument(skip_all)] @@ -239,7 +254,7 @@ pub fn normalize_bins( errors: &mut Vec, has_lib: bool, ) -> CargoResult> { - if is_normalized(toml_bins, autodiscover) { + if are_normalized(toml_bins, autodiscover) { let toml_bins = toml_bins.cloned().unwrap_or_default(); for bin in &toml_bins { validate_bin_name(bin, warnings)?; @@ -526,7 +541,15 @@ fn to_bench_targets( Ok(result) } -fn is_normalized(toml_targets: Option<&Vec>, autodiscover: Option) -> bool { +fn is_normalized(toml_target: Option<&TomlTarget>, autodiscover: Option) -> bool { + are_normalized_(toml_target.map(std::slice::from_ref), autodiscover) +} + +fn are_normalized(toml_targets: Option<&Vec>, autodiscover: Option) -> bool { + are_normalized_(toml_targets.map(|v| v.as_slice()), autodiscover) +} + +fn are_normalized_(toml_targets: Option<&[TomlTarget]>, autodiscover: Option) -> bool { if autodiscover != Some(false) { return false; } @@ -579,7 +602,7 @@ fn normalize_targets_with_legacy_path( legacy_path: &mut dyn FnMut(&TomlTarget) -> Option, autodiscover_flag_name: &str, ) -> CargoResult> { - if is_normalized(toml_targets, autodiscover) { + if are_normalized(toml_targets, autodiscover) { let toml_targets = toml_targets.cloned().unwrap_or_default(); for target in &toml_targets { // Check early to improve error messages diff --git a/src/doc/src/reference/cargo-targets.md b/src/doc/src/reference/cargo-targets.md index 6eb7570f49d..410df80a207 100644 --- a/src/doc/src/reference/cargo-targets.md +++ b/src/doc/src/reference/cargo-targets.md @@ -323,13 +323,14 @@ configuration tables, such as `[lib]`, `[[bin]]`, `[[test]]`, `[[bench]]`, or standard directory layout. The automatic target discovery can be disabled so that only manually -configured targets will be built. Setting the keys `autobins`, `autoexamples`, +configured targets will be built. Setting the keys `autolib`, `autobins`, `autoexamples`, `autotests`, or `autobenches` to `false` in the `[package]` section will disable auto-discovery of the corresponding target type. ```toml [package] # ... +autolib = false autobins = false autoexamples = false autotests = false @@ -363,6 +364,9 @@ autobins = false > is `false` if at least one target is manually defined in `Cargo.toml`. > Beginning with the 2018 edition, the default is always `true`. +> **MSRV:** Respected as of 1.27 for `autobins`, `autoexamples`, `autotests`, and `autobenches` + +> **MSRV:** Respected as of 1.83 for `autolib` [Build cache]: ../guide/build-cache.md [Rust Edition]: ../../edition-guide/index.html diff --git a/src/doc/src/reference/manifest.md b/src/doc/src/reference/manifest.md index 0fcf02b4276..cedf62766b7 100644 --- a/src/doc/src/reference/manifest.md +++ b/src/doc/src/reference/manifest.md @@ -30,6 +30,7 @@ Every manifest file consists of the following sections: * [`publish`](#the-publish-field) --- Can be used to prevent publishing the package. * [`metadata`](#the-metadata-table) --- Extra settings for external tools. * [`default-run`](#the-default-run-field) --- The default binary to run by [`cargo run`]. + * [`autolib`](cargo-targets.md#target-auto-discovery) --- Disables library auto discovery. * [`autobins`](cargo-targets.md#target-auto-discovery) --- Disables binary auto discovery. * [`autoexamples`](cargo-targets.md#target-auto-discovery) --- Disables example auto discovery. * [`autotests`](cargo-targets.md#target-auto-discovery) --- Disables test auto discovery. diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 20f2175b7a0..489bbd45b90 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -1314,7 +1314,7 @@ Inferred / defaulted manifest fields: Disallowed manifest fields: - `[workspace]`, `[lib]`, `[[bin]]`, `[[example]]`, `[[test]]`, `[[bench]]` -- `package.workspace`, `package.build`, `package.links`, `package.autobins`, `package.autoexamples`, `package.autotests`, `package.autobenches` +- `package.workspace`, `package.build`, `package.links`, `package.autolib`, `package.autobins`, `package.autoexamples`, `package.autotests`, `package.autobenches` The default `CARGO_TARGET_DIR` for single-file packages is at `$CARGO_HOME/target/`: - Avoid conflicts from multiple single-file packages being in the same directory diff --git a/tests/testsuite/artifact_dep.rs b/tests/testsuite/artifact_dep.rs index b8cb270a31d..adaad2a11f8 100644 --- a/tests/testsuite/artifact_dep.rs +++ b/tests/testsuite/artifact_dep.rs @@ -2272,6 +2272,7 @@ name = "foo" version = "0.1.0" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false diff --git a/tests/testsuite/features2.rs b/tests/testsuite/features2.rs index 58de2d32a11..5bcd1e2cc54 100644 --- a/tests/testsuite/features2.rs +++ b/tests/testsuite/features2.rs @@ -1800,6 +1800,7 @@ name = "a" version = "0.1.0" authors = ["Zzz"] build = false +autolib = false autobins = false autoexamples = false autotests = false diff --git a/tests/testsuite/features_namespaced.rs b/tests/testsuite/features_namespaced.rs index d1727fe8a98..a620f441b69 100644 --- a/tests/testsuite/features_namespaced.rs +++ b/tests/testsuite/features_namespaced.rs @@ -985,6 +985,7 @@ edition = "2015" name = "foo" version = "0.1.0" build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -1112,6 +1113,7 @@ edition = "2015" name = "foo" version = "0.1.0" build = false +autolib = false autobins = false autoexamples = false autotests = false diff --git a/tests/testsuite/inheritable_workspace_fields.rs b/tests/testsuite/inheritable_workspace_fields.rs index 335dd1ece77..8af4724a8aa 100644 --- a/tests/testsuite/inheritable_workspace_fields.rs +++ b/tests/testsuite/inheritable_workspace_fields.rs @@ -224,6 +224,7 @@ include = [ "Cargo.toml", ] publish = true +autolib = false autobins = false autoexamples = false autotests = false @@ -394,6 +395,7 @@ name = "bar" version = "0.2.0" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -533,6 +535,7 @@ name = "bar" version = "0.2.0" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -793,6 +796,7 @@ include = [ "README.md", ] publish = true +autolib = false autobins = false autoexamples = false autotests = false @@ -966,6 +970,7 @@ name = "bar" version = "0.2.0" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index d5c9ea26eaf..046635a0534 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1334,6 +1334,7 @@ version = "0.0.1" authors = [] build = false exclude = ["*.txt"] +autolib = false autobins = false autoexamples = false autotests = false @@ -1419,6 +1420,7 @@ name = "bar" version = "0.1.0" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -1496,6 +1498,7 @@ edition = "2015" name = "foo" version = "0.0.1" build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -1524,6 +1527,7 @@ edition = "2015" name = "foo" version = "0.0.1" build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -2986,6 +2990,7 @@ edition = "2021" name = "bar" version = "0.1.0" build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -3015,6 +3020,7 @@ edition = "2015" name = "baz" version = "0.1.0" build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -3087,6 +3093,7 @@ version = "0.0.1" authors = [] build = false exclude = ["*.txt"] +autolib = false autobins = false autoexamples = false autotests = false @@ -3189,6 +3196,7 @@ name = "foo" version = "0.0.1" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -3304,6 +3312,7 @@ name = "foo" version = "0.0.1" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -3496,6 +3505,7 @@ version = "0.0.1" authors = [] build = false exclude = ["*.txt"] +autolib = false autobins = false autoexamples = false autotests = false @@ -3902,6 +3912,7 @@ name = "foo" version = "0.0.1" authors = [] build = "src/build.rs" +autolib = false autobins = false autoexamples = false autotests = false @@ -3996,6 +4007,7 @@ include = [ "src/lib.rs", "build.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -4072,6 +4084,7 @@ version = "0.0.1" authors = [] build = false include = ["src/lib.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -4151,6 +4164,7 @@ include = [ "src/lib.rs", "build.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -4228,6 +4242,7 @@ version = "0.0.1" authors = [] build = false include = ["src/lib.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -4312,6 +4327,7 @@ include = [ "src/main.rs", "src/lib.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -4392,6 +4408,7 @@ version = "0.0.1" authors = [] build = false include = ["src/main.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -4479,6 +4496,7 @@ include = [ "src/main.rs", "src/lib.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -4562,6 +4580,7 @@ version = "0.0.1" authors = [] build = false include = ["src/main.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -4655,6 +4674,7 @@ include = [ "tests/test_foo.rs", "benches/bench_foo.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -4753,6 +4773,7 @@ version = "0.0.1" authors = [] build = false include = ["src/lib.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -4858,6 +4879,7 @@ include = [ "tests/test_foo.rs", "benches/bench_foo.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -4968,6 +4990,7 @@ version = "0.0.1" authors = [] build = false include = ["src/lib.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -5066,6 +5089,7 @@ name = "foo" version = "0.0.1" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -5275,6 +5299,7 @@ name = "level1" version = "0.0.1" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index 2ee6639743d..3fd31cf9b19 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -1583,6 +1583,7 @@ You may press ctrl-c to skip waiting; the crate should be available shortly. version = \"0.1.0\"\n\ authors = []\n\ build = false\n\ + autolib = false\n\ autobins = false\n\ autoexamples = false\n\ autotests = false\n\ @@ -1963,6 +1964,7 @@ name = "foo" version = "0.1.0" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false diff --git a/tests/testsuite/script.rs b/tests/testsuite/script.rs index 6cf34b4e4d5..e5b3ac75af2 100644 --- a/tests/testsuite/script.rs +++ b/tests/testsuite/script.rs @@ -813,6 +813,34 @@ Hello world! .run(); } +#[cargo_test] +fn test_no_autolib() { + let script = r#"#!/usr/bin/env cargo + +fn main() { + println!("Hello world!"); +}"#; + let p = cargo_test_support::project() + .file("script.rs", script) + .file("src/lib.rs", r#"compile_error!{"must not be built"}"#) + .build(); + + p.cargo("-Zscript -v script.rs --help") + .masquerade_as_nightly_cargo(&["script"]) + .with_stdout_data(str![[r#" +Hello world! + +"#]]) + .with_stderr_data(str![[r#" +[WARNING] `package.edition` is unspecified, defaulting to `2021` +[COMPILING] script v0.0.0 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `[ROOT]/home/.cargo/target/[HASH]/debug/script[EXE] --help` + +"#]]) + .run(); +} + #[cargo_test] fn implicit_target_dir() { let script = ECHO_SCRIPT; diff --git a/tests/testsuite/vendor.rs b/tests/testsuite/vendor.rs index 39651268b3c..8a399fc45ee 100644 --- a/tests/testsuite/vendor.rs +++ b/tests/testsuite/vendor.rs @@ -294,6 +294,7 @@ include = [ "src/lib.rs", "build.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -379,6 +380,7 @@ version = "0.0.1" authors = [] build = false include = ["src/lib.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -467,6 +469,7 @@ include = [ "src/main.rs", "src/lib.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -556,6 +559,7 @@ version = "0.0.1" authors = [] build = false include = ["src/main.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -650,6 +654,7 @@ include = [ "tests/test_foo.rs", "benches/bench_foo.rs", ] +autolib = false autobins = false autoexamples = false autotests = false @@ -754,6 +759,7 @@ version = "0.0.1" authors = [] build = false include = ["src/lib.rs"] +autolib = false autobins = false autoexamples = false autotests = false @@ -1527,6 +1533,7 @@ name = "git_dep" version = "0.0.1" authors = [] build = false +autolib = false autobins = false autoexamples = false autotests = false @@ -1542,27 +1549,27 @@ path = "src/lib.rs" [[example]] name = "a" -path = [..] +path = "examples/a.rs" [[example]] name = "b" -path = [..] +path = "examples/b.rs" [[example]] name = "c" -path = [..] +path = "examples/c.rs" [[example]] name = "x" -path = [..] +path = "examples/x.rs" [[example]] name = "y" -path = [..] +path = "examples/y.rs" [[example]] name = "z" -path = [..] +path = "examples/z.rs" "##]], ); diff --git a/tests/testsuite/weak_dep_features.rs b/tests/testsuite/weak_dep_features.rs index b5411545905..3e931be3a6f 100644 --- a/tests/testsuite/weak_dep_features.rs +++ b/tests/testsuite/weak_dep_features.rs @@ -630,6 +630,7 @@ edition = "2015" name = "foo" version = "0.1.0" build = false +autolib = false autobins = false autoexamples = false autotests = false