diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs index ee184dace36..40f179898e3 100644 --- a/src/cargo/core/compiler/unit_dependencies.rs +++ b/src/cargo/core/compiler/unit_dependencies.rs @@ -518,12 +518,12 @@ fn dep_build_script( // build.rs unit use the same features. This is because some // people use `cfg!` and `#[cfg]` expressions to check for enabled // features instead of just checking `CARGO_FEATURE_*` at runtime. - // In the case with `-Zfeatures=host_dep`, and a shared - // dependency has different features enabled for normal vs. build, - // then the build.rs script will get compiled twice. I believe it - // is not feasible to only build it once because it would break a - // large number of scripts (they would think they have the wrong - // set of features enabled). + // In the case with the new feature resolver (decoupled host + // deps), and a shared dependency has different features enabled + // for normal vs. build, then the build.rs script will get + // compiled twice. I believe it is not feasible to only build it + // once because it would break a large number of scripts (they + // would think they have the wrong set of features enabled). let script_unit_for = UnitFor::new_host(unit_for.is_for_host_features()); new_unit_dep_with_profile( state, diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 487abcb5146..35189db8099 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -210,7 +210,7 @@ features! { [unstable] named_profiles: bool, // Opt-in new-resolver behavior. - [unstable] resolver: bool, + [stable] resolver: bool, // Allow to specify whether binaries should be stripped. [unstable] strip: bool, @@ -338,7 +338,6 @@ pub struct CliUnstable { pub no_index_update: bool, pub avoid_dev_deps: bool, pub minimal_versions: bool, - pub package_features: bool, pub advanced_env: bool, pub config_include: bool, pub dual_proc_macros: bool, @@ -445,7 +444,6 @@ impl CliUnstable { "no-index-update" => self.no_index_update = parse_empty(k, v)?, "avoid-dev-deps" => self.avoid_dev_deps = parse_empty(k, v)?, "minimal-versions" => self.minimal_versions = parse_empty(k, v)?, - "package-features" => self.package_features = parse_empty(k, v)?, "advanced-env" => self.advanced_env = parse_empty(k, v)?, "config-include" => self.config_include = parse_empty(k, v)?, "dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?, diff --git a/src/cargo/core/resolver/features.rs b/src/cargo/core/resolver/features.rs index 8b0b73e762e..e83e0cf2314 100644 --- a/src/cargo/core/resolver/features.rs +++ b/src/cargo/core/resolver/features.rs @@ -1,11 +1,8 @@ //! Feature resolver. //! //! This is a new feature resolver that runs independently of the main -//! dependency resolver. It is intended to make it easier to experiment with -//! new behaviors. When `-Zfeatures` is not used, it will fall back to using -//! the original `Resolve` feature computation. With `-Zfeatures` enabled, -//! this will walk the dependency graph and compute the features using a -//! different algorithm. +//! dependency resolver. It is enabled when the user specifies `resolver = +//! "2"` in `Cargo.toml`. //! //! One of its key characteristics is that it can avoid unifying features for //! shared dependencies in some situations. See `FeatureOpts` for the @@ -61,11 +58,11 @@ pub struct ResolvedFeatures { /// /// The value is the `name_in_toml` of the dependencies. activated_dependencies: ActivateMap, - /// This is only here for legacy support when `-Zfeatures` is not enabled. + /// This is only here for legacy support when the new resolver is not enabled. /// /// This is the set of features enabled for each package. legacy_features: Option>>, - /// This is only here for legacy support when `-Zfeatures` is not enabled. + /// This is only here for legacy support when the new resolver is not enabled. /// /// This is the set of optional dependencies enabled for each package. legacy_dependencies: Option>>, @@ -75,7 +72,7 @@ pub struct ResolvedFeatures { /// Options for how the feature resolver works. #[derive(Default)] struct FeatureOpts { - /// -Zfeatures is enabled, use new resolver. + /// Use the new resolver instead of the old one. new_resolver: bool, /// Build deps and proc-macros will not share share features with other dep kinds. decouple_host_deps: bool, diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index 3c083d1aeff..4a6adccdc83 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -637,8 +637,15 @@ impl<'cfg> Workspace<'cfg> { self.resolve_behavior.unwrap_or(ResolveBehavior::V1) } - pub fn allows_unstable_package_features(&self) -> bool { - self.config().cli_unstable().package_features + /// Returns `true` if this workspace uses the new CLI features behavior. + /// + /// The old behavior only allowed choosing the features from the package + /// in the current directory, regardless of which packages were chosen + /// with the -p flags. The new behavior allows selecting features from the + /// packages chosen on the command line (with -p or --workspace flags), + /// ignoring whatever is in the current directory. + pub fn allows_new_cli_feature_behavior(&self) -> bool { + self.is_virtual() || match self.resolve_behavior() { ResolveBehavior::V1 => false, ResolveBehavior::V2 => true, @@ -947,15 +954,16 @@ impl<'cfg> Workspace<'cfg> { .map(|m| (m, RequestedFeatures::new_all(true))) .collect()); } - if self.allows_unstable_package_features() { - self.members_with_features_pf(specs, requested_features) + if self.allows_new_cli_feature_behavior() { + self.members_with_features_new(specs, requested_features) } else { - self.members_with_features_stable(specs, requested_features) + self.members_with_features_old(specs, requested_features) } } - /// New command-line feature selection with -Zpackage-features. - fn members_with_features_pf( + /// New command-line feature selection behavior with resolver = "2" or the + /// root of a virtual workspace. See `allows_new_cli_feature_behavior`. + fn members_with_features_new( &self, specs: &[PackageIdSpec], requested_features: &RequestedFeatures, @@ -1053,30 +1061,69 @@ impl<'cfg> Workspace<'cfg> { Ok(members) } - /// This is the current "stable" behavior for command-line feature selection. - fn members_with_features_stable( + /// This is the "old" behavior for command-line feature selection. + /// See `allows_new_cli_feature_behavior`. + fn members_with_features_old( &self, specs: &[PackageIdSpec], requested_features: &RequestedFeatures, ) -> CargoResult> { + // Split off any features with the syntax `member-name/feature-name` into a map + // so that those features can be applied directly to those workspace-members. + let mut member_specific_features: HashMap<&str, BTreeSet> = HashMap::new(); + // Features for the member in the current directory. + let mut cwd_features = BTreeSet::new(); + for feature in requested_features.features.iter() { + if let Some(index) = feature.find('/') { + let name = &feature[..index]; + if specs.iter().any(|spec| spec.name() == name) { + member_specific_features + .entry(name) + .or_default() + .insert(InternedString::new(&feature[index + 1..])); + } else { + cwd_features.insert(*feature); + } + } else { + cwd_features.insert(*feature); + }; + } + let ms = self.members().filter_map(|member| { let member_id = member.package_id(); match self.current_opt() { // The features passed on the command-line only apply to // the "current" package (determined by the cwd). Some(current) if member_id == current.package_id() => { - Some((member, requested_features.clone())) + let feats = RequestedFeatures { + features: Rc::new(cwd_features.clone()), + all_features: requested_features.all_features, + uses_default_features: requested_features.uses_default_features, + }; + Some((member, feats)) } _ => { // Ignore members that are not enabled on the command-line. if specs.iter().any(|spec| spec.matches(member_id)) { - // -p for a workspace member that is not the - // "current" one, don't use the local - // `--features`, only allow `--all-features`. - Some(( - member, - RequestedFeatures::new_all(requested_features.all_features), - )) + // -p for a workspace member that is not the "current" + // one. + // + // The odd behavior here is due to backwards + // compatibility. `--features` and + // `--no-default-features` used to only apply to the + // "current" package. As an extension, this allows + // member-name/feature-name to set member-specific + // features, which should be backwards-compatible. + let feats = RequestedFeatures { + features: Rc::new( + member_specific_features + .remove(member.name().as_str()) + .unwrap_or_default(), + ), + uses_default_features: true, + all_features: requested_features.all_features, + }; + Some((member, feats)) } else { // This member was not requested on the command-line, skip. None diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 5f2a0ad50dc..3950f1e3dcc 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -310,20 +310,6 @@ pub trait ArgMatchesExt { if config.cli_unstable().avoid_dev_deps { ws.set_require_optional_deps(false); } - if ws.is_virtual() && !ws.allows_unstable_package_features() { - // --all-features is actually honored. In general, workspaces and - // feature flags are a bit of a mess right now. - for flag in &["features", "no-default-features"] { - if self._is_present(flag) { - bail!( - "--{} is not allowed in the root of a virtual workspace\n\ - note: while this was previously accepted, it didn't actually do anything\n\ - help: change the current directory to the package directory, or use the --manifest-path flag to the path of the package", - flag - ); - } - } - } Ok(ws) } diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 85728ae489a..76db59faf3a 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -883,19 +883,7 @@ impl TomlManifest { .unwrap() .clone(); package.workspace = None; - let mut cargo_features = self.cargo_features.clone(); package.resolver = ws.resolve_behavior().to_manifest(); - if package.resolver.is_some() { - // This should be removed when stabilizing. - match &mut cargo_features { - None => cargo_features = Some(vec!["resolver".to_string()]), - Some(feats) => { - if !feats.iter().any(|feat| feat == "resolver") { - feats.push("resolver".to_string()); - } - } - } - } if let Some(license_file) = &package.license_file { let license_path = Path::new(&license_file); let abs_license_path = paths::normalize_path(&package_root.join(license_path)); @@ -977,7 +965,7 @@ impl TomlManifest { patch: None, workspace: None, badges: self.badges.clone(), - cargo_features, + cargo_features: self.cargo_features.clone(), }); fn map_deps( diff --git a/src/doc/man/generated_txt/cargo-bench.txt b/src/doc/man/generated_txt/cargo-bench.txt index 963e5f5ff41..a7b54a0e42b 100644 --- a/src/doc/man/generated_txt/cargo-bench.txt +++ b/src/doc/man/generated_txt/cargo-bench.txt @@ -163,19 +163,17 @@ OPTIONS --tests --benches --examples. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -183,8 +181,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-build.txt b/src/doc/man/generated_txt/cargo-build.txt index 3c49fb8f318..d203b323703 100644 --- a/src/doc/man/generated_txt/cargo-build.txt +++ b/src/doc/man/generated_txt/cargo-build.txt @@ -106,19 +106,17 @@ OPTIONS --tests --benches --examples. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -126,8 +124,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-check.txt b/src/doc/man/generated_txt/cargo-check.txt index e61cad5da2c..39e38d6ea07 100644 --- a/src/doc/man/generated_txt/cargo-check.txt +++ b/src/doc/man/generated_txt/cargo-check.txt @@ -112,19 +112,17 @@ OPTIONS --tests --benches --examples. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -132,8 +130,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-doc.txt b/src/doc/man/generated_txt/cargo-doc.txt index bdcb9b1bc3f..dbc7262e49e 100644 --- a/src/doc/man/generated_txt/cargo-doc.txt +++ b/src/doc/man/generated_txt/cargo-doc.txt @@ -80,19 +80,17 @@ OPTIONS Document all binary targets. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -100,8 +98,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-fix.txt b/src/doc/man/generated_txt/cargo-fix.txt index 3c5eb4cbacf..6a990e2cca0 100644 --- a/src/doc/man/generated_txt/cargo-fix.txt +++ b/src/doc/man/generated_txt/cargo-fix.txt @@ -161,19 +161,17 @@ OPTIONS --tests --benches --examples. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -181,8 +179,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-install.txt b/src/doc/man/generated_txt/cargo-install.txt index 44cf89ee2a7..a56e1797a9c 100644 --- a/src/doc/man/generated_txt/cargo-install.txt +++ b/src/doc/man/generated_txt/cargo-install.txt @@ -149,19 +149,17 @@ OPTIONS The URL of the registry index to use. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -169,8 +167,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-metadata.txt b/src/doc/man/generated_txt/cargo-metadata.txt index e48aa431a34..8a600cfca65 100644 --- a/src/doc/man/generated_txt/cargo-metadata.txt +++ b/src/doc/man/generated_txt/cargo-metadata.txt @@ -299,19 +299,17 @@ OPTIONS an unaltered reproduction of the information within Cargo.toml. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -319,8 +317,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Display Options -v, --verbose diff --git a/src/doc/man/generated_txt/cargo-package.txt b/src/doc/man/generated_txt/cargo-package.txt index afc6e2ff950..e0d52a4d352 100644 --- a/src/doc/man/generated_txt/cargo-package.txt +++ b/src/doc/man/generated_txt/cargo-package.txt @@ -85,19 +85,17 @@ OPTIONS target in the root of the workspace. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -105,8 +103,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Manifest Options --manifest-path path diff --git a/src/doc/man/generated_txt/cargo-publish.txt b/src/doc/man/generated_txt/cargo-publish.txt index 82f7e4bcda1..dc214098bdc 100644 --- a/src/doc/man/generated_txt/cargo-publish.txt +++ b/src/doc/man/generated_txt/cargo-publish.txt @@ -91,19 +91,17 @@ OPTIONS target in the root of the workspace. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -111,8 +109,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Manifest Options --manifest-path path diff --git a/src/doc/man/generated_txt/cargo-run.txt b/src/doc/man/generated_txt/cargo-run.txt index 4ce62fa2b8e..2c2b4527eb8 100644 --- a/src/doc/man/generated_txt/cargo-run.txt +++ b/src/doc/man/generated_txt/cargo-run.txt @@ -35,19 +35,17 @@ OPTIONS Run the specified example. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -55,8 +53,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-rustc.txt b/src/doc/man/generated_txt/cargo-rustc.txt index d1ced70f219..dfbedc730b7 100644 --- a/src/doc/man/generated_txt/cargo-rustc.txt +++ b/src/doc/man/generated_txt/cargo-rustc.txt @@ -97,19 +97,17 @@ OPTIONS --tests --benches --examples. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -117,8 +115,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-rustdoc.txt b/src/doc/man/generated_txt/cargo-rustdoc.txt index 61ccdecc798..8021c0a39f9 100644 --- a/src/doc/man/generated_txt/cargo-rustdoc.txt +++ b/src/doc/man/generated_txt/cargo-rustdoc.txt @@ -104,19 +104,17 @@ OPTIONS --tests --benches --examples. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -124,8 +122,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-test.txt b/src/doc/man/generated_txt/cargo-test.txt index 0e625dae6f9..7be248e384f 100644 --- a/src/doc/man/generated_txt/cargo-test.txt +++ b/src/doc/man/generated_txt/cargo-test.txt @@ -181,19 +181,17 @@ OPTIONS other target options. Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -201,8 +199,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Compilation Options --target triple diff --git a/src/doc/man/generated_txt/cargo-tree.txt b/src/doc/man/generated_txt/cargo-tree.txt index 941a1c848bc..7002a408b9e 100644 --- a/src/doc/man/generated_txt/cargo-tree.txt +++ b/src/doc/man/generated_txt/cargo-tree.txt @@ -204,19 +204,17 @@ OPTIONS . Feature Selection - The feature flags allow you to control the enabled features for the - "current" package. The "current" package is the package in the current - directory, or the one specified in --manifest-path. If running in the - root of a virtual workspace, then the default features are selected for - all workspace members, or all features if --all-features is specified. + The feature flags allow you to control which features are enabled. When + no feature options are given, the default feature is activated for every + selected package. - When no feature options are given, the default feature is activated for - every selected package. + See the features documentation + + for more details. --features features - Space or comma separated list of features to activate. These - features only apply to the current directory's package. Features of - direct dependencies may be enabled with / + Space or comma separated list of features to activate. Features of + workspace members may be enabled with package-name/feature-name syntax. This flag may be specified multiple times, which enables all specified features. @@ -224,8 +222,7 @@ OPTIONS Activate all available features of all selected packages. --no-default-features - Do not activate the default feature of the current directory's - package. + Do not activate the default feature of the selected packages. Display Options -v, --verbose diff --git a/src/doc/man/includes/section-features.md b/src/doc/man/includes/section-features.md index 5d3ae324212..f4947f7f582 100644 --- a/src/doc/man/includes/section-features.md +++ b/src/doc/man/includes/section-features.md @@ -1,21 +1,18 @@ ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details. {{#options}} {{#option "`--features` _features_" }} -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with `/` syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with `package-name/feature-name` syntax. This flag may +be specified multiple times, which enables all specified features. {{/option}} {{#option "`--all-features`" }} @@ -23,7 +20,7 @@ Activate all available features of all selected packages. {{/option}} {{#option "`--no-default-features`" }} -Do not activate the `default` feature of the current directory's package. +Do not activate the `default` feature of the selected packages. {{/option}} {{/options}} diff --git a/src/doc/src/SUMMARY.md b/src/doc/src/SUMMARY.md index daba6d2f06e..db67ffd4029 100644 --- a/src/doc/src/SUMMARY.md +++ b/src/doc/src/SUMMARY.md @@ -25,6 +25,7 @@ * [Cargo Targets](reference/cargo-targets.md) * [Workspaces](reference/workspaces.md) * [Features](reference/features.md) + * [Features Examples](reference/features-examples.md) * [Profiles](reference/profiles.md) * [Configuration](reference/config.md) * [Environment Variables](reference/environment-variables.md) diff --git a/src/doc/src/commands/cargo-bench.md b/src/doc/src/commands/cargo-bench.md index ebb75c63364..317d1dc9c8d 100644 --- a/src/doc/src/commands/cargo-bench.md +++ b/src/doc/src/commands/cargo-bench.md @@ -199,22 +199,19 @@ manifest settings for the target. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -222,7 +219,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-build.md b/src/doc/src/commands/cargo-build.md index d73abb0bc59..74f9e77462a 100644 --- a/src/doc/src/commands/cargo-build.md +++ b/src/doc/src/commands/cargo-build.md @@ -138,22 +138,19 @@ manifest settings for the target. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -161,7 +158,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-check.md b/src/doc/src/commands/cargo-check.md index 1ba6fa4abf2..ff6242c5112 100644 --- a/src/doc/src/commands/cargo-check.md +++ b/src/doc/src/commands/cargo-check.md @@ -143,22 +143,19 @@ manifest settings for the target. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -166,7 +163,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-doc.md b/src/doc/src/commands/cargo-doc.md index ea3d58f5b96..2d80ff060d6 100644 --- a/src/doc/src/commands/cargo-doc.md +++ b/src/doc/src/commands/cargo-doc.md @@ -109,22 +109,19 @@ and supports common Unix glob patterns. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -132,7 +129,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-fix.md b/src/doc/src/commands/cargo-fix.md index 8a96daaef41..129aa7bf39d 100644 --- a/src/doc/src/commands/cargo-fix.md +++ b/src/doc/src/commands/cargo-fix.md @@ -203,22 +203,19 @@ manifest settings for the target. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -226,7 +223,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-install.md b/src/doc/src/commands/cargo-install.md index c792f8bf03d..b5d180363bc 100644 --- a/src/doc/src/commands/cargo-install.md +++ b/src/doc/src/commands/cargo-install.md @@ -169,22 +169,19 @@ which is defined by the registry.default config key which defaults ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -192,7 +189,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-metadata.md b/src/doc/src/commands/cargo-metadata.md index 7acf4f52e53..a95a27b9f34 100644 --- a/src/doc/src/commands/cargo-metadata.md +++ b/src/doc/src/commands/cargo-metadata.md @@ -313,22 +313,19 @@ reproduction of the information within Cargo.toml. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -336,7 +333,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-package.md b/src/doc/src/commands/cargo-package.md index df463cd86d0..eca11d6e32b 100644 --- a/src/doc/src/commands/cargo-package.md +++ b/src/doc/src/commands/cargo-package.md @@ -97,22 +97,19 @@ to target in the root of the workspace. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -120,7 +117,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-publish.md b/src/doc/src/commands/cargo-publish.md index 79a88abbbd0..3f011423a96 100644 --- a/src/doc/src/commands/cargo-publish.md +++ b/src/doc/src/commands/cargo-publish.md @@ -105,22 +105,19 @@ to target in the root of the workspace. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -128,7 +125,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-run.md b/src/doc/src/commands/cargo-run.md index c20d4e5dfe5..0123d986650 100644 --- a/src/doc/src/commands/cargo-run.md +++ b/src/doc/src/commands/cargo-run.md @@ -56,22 +56,19 @@ section of `Cargo.toml` to choose the name of the binary to run by default. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -79,7 +76,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-rustc.md b/src/doc/src/commands/cargo-rustc.md index cf3fd0a3d21..f53bf09fcbd 100644 --- a/src/doc/src/commands/cargo-rustc.md +++ b/src/doc/src/commands/cargo-rustc.md @@ -125,22 +125,19 @@ manifest settings for the target. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -148,7 +145,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-rustdoc.md b/src/doc/src/commands/cargo-rustdoc.md index fbf11b44ed3..5546708dba8 100644 --- a/src/doc/src/commands/cargo-rustdoc.md +++ b/src/doc/src/commands/cargo-rustdoc.md @@ -138,22 +138,19 @@ manifest settings for the target. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -161,7 +158,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-test.md b/src/doc/src/commands/cargo-test.md index f8df6ce6c77..e5444c62d7a 100644 --- a/src/doc/src/commands/cargo-test.md +++ b/src/doc/src/commands/cargo-test.md @@ -218,22 +218,19 @@ target options. ### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -241,7 +238,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/commands/cargo-tree.md b/src/doc/src/commands/cargo-tree.md index 70f1f6690f7..ff50f50227c 100644 --- a/src/doc/src/commands/cargo-tree.md +++ b/src/doc/src/commands/cargo-tree.md @@ -228,22 +228,19 @@ offline.

### Feature Selection -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in `--manifest-path`. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if `--all-features` is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the `default` feature is activated for every +selected package. -When no feature options are given, the `default` feature is activated for -every selected package. +See [the features documentation](../reference/features.html#command-line-feature-options) +for more details.
--features features
-
Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with <dep-name>/<feature-name> syntax. This flag may be -specified multiple times, which enables all specified features.
+
Space or comma separated list of features to activate. Features of workspace +members may be enabled with package-name/feature-name syntax. This flag may +be specified multiple times, which enables all specified features.
--all-features
@@ -251,7 +248,7 @@ specified multiple times, which enables all specified features.
--no-default-features
-
Do not activate the default feature of the current directory's package.
+
Do not activate the default feature of the selected packages.
diff --git a/src/doc/src/images/winapi-features.svg b/src/doc/src/images/winapi-features.svg new file mode 100644 index 00000000000..32327ad1d9c --- /dev/null +++ b/src/doc/src/images/winapi-features.svg @@ -0,0 +1,3 @@ + + +
foo
foo
bar
bar
winapi

features:
• fileapi
• handleapi
• std
• winnt
winapi...
fileapi, handleapi
fileapi, handleapi
std, winnt
std, winnt
my-package
my-package
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/src/doc/src/reference/features-examples.md b/src/doc/src/reference/features-examples.md new file mode 100644 index 00000000000..8a69046c915 --- /dev/null +++ b/src/doc/src/reference/features-examples.md @@ -0,0 +1,187 @@ +## Features Examples + +The following illustrates some real-world examples of features in action. + +### Minimizing build times and file sizes + +Some packages use features so that if the features are not enabled, it reduces +the size of the crate and reduces compile time. Some examples are: + +* [`syn`] is a popular crate for parsing Rust code. Since it is so popular, it + is helpful to reduce compile times since it affects so many projects. It has + a [clearly documented list][syn-features] of features which can be used to + minimize the amount of code it contains. +* [`regex`] has a [several features][regex-features] that are [well + documented][regex-docs]. Cutting out Unicode support can reduce the + resulting file size as it can remove some large tables. +* [`winapi`] has [a large number][winapi-features] of features that + limit which Windows API bindings it supports. +* [`web-sys`] is another example similar to `winapi` that provides a [huge + surface area][web-sys-features] of API bindings that are limited by using + features. + +[`winapi`]: https://crates.io/crates/winapi +[winapi-features]: https://github.com/retep998/winapi-rs/blob/0.3.9/Cargo.toml#L25-L431 +[`regex`]: https://crates.io/crates/regex +[`syn`]: https://crates.io/crates/syn +[syn-features]: https://docs.rs/syn/1.0.54/syn/#optional-features +[regex-features]: https://github.com/rust-lang/regex/blob/1.4.2/Cargo.toml#L33-L101 +[regex-docs]: https://docs.rs/regex/1.4.2/regex/#crate-features +[`web-sys`]: https://crates.io/crates/web-sys +[web-sys-features]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/crates/web-sys/Cargo.toml#L32-L1395 + +### Extending behavior + +The [`serde_json`] package has a [`preserve_order` feature][serde_json-preserve_order] +which [changes the behavior][serde_json-code] of JSON maps to preserve the +order that keys are inserted. Notice that it enables an optional dependency +[`indexmap`] to implement the new behavior. + +When changing behavior like this, be careful to make sure the changes are +[SemVer compatible]. That is, enabling the feature should not break code that +usually builds with the feature off. + +[`serde_json`]: https://crates.io/crates/serde_json +[serde_json-preserve_order]: https://github.com/serde-rs/json/blob/v1.0.60/Cargo.toml#L53-L56 +[SemVer compatible]: features.md#semver-compatibility +[serde_json-code]: https://github.com/serde-rs/json/blob/v1.0.60/src/map.rs#L23-L26 +[`indexmap`]: https://crates.io/crates/indexmap + +### `no_std` support + +Some packages want to support both [`no_std`] and `std` environments. This is +useful for supporting embedded and resource-constrained platforms, but still +allowing extended capabilities for platforms that support the full standard +library. + +The [`wasm-bindgen`] package defines a [`std` feature][wasm-bindgen-std] that +is [enabled by default][wasm-bindgen-default]. At the top of the library, it +[unconditionally enables the `no_std` attribute][wasm-bindgen-no_std]. This +ensures that `std` and the [`std` prelude] are not automatically in scope. +Then, in various places in the code ([example1][wasm-bindgen-cfg1], +[example2][wasm-bindgen-cfg2]), it uses `#[cfg(feature = "std")]` attributes +to conditionally enable extra functionality that requires `std`. + +[`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std +[`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen +[`std` prelude]: ../../std/prelude/index.html +[wasm-bindgen-std]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/Cargo.toml#L25 +[wasm-bindgen-default]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/Cargo.toml#L23 +[wasm-bindgen-no_std]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L8 +[wasm-bindgen-cfg1]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L270-L273 +[wasm-bindgen-cfg2]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L67-L75 + +### Re-exporting dependency features + +It can be convenient to re-export the features from a dependency. This allows +the user depending on the crate to control those features without needing to +specify those dependencies directly. For example, [`regex`] [re-exports the +features][regex-re-export] from the [`regex_syntax`][regex_syntax-features] +package. Users of `regex` don't need to know about the `regex_syntax` package, +but they can still access the features it contains. + +[regex-re-export]: https://github.com/rust-lang/regex/blob/1.4.2/Cargo.toml#L65-L89 +[regex_syntax-features]: https://github.com/rust-lang/regex/blob/1.4.2/regex-syntax/Cargo.toml#L17-L32 + +### Vendoring of C libraries + +Some packages provide bindings to common C libraries (sometimes referred to as +["sys" crates][sys]). Sometimes these packages give you the choice to use the +C library installed on the system, or to build it from source. For example, +the [`openssl`] package has a [`vendored` feature][openssl-vendored] which +enables the corresponding `vendored` feature of [`openssl-sys`]. The +`openssl-sys` build script has some [conditional logic][openssl-sys-cfg] which +causes it to build from a local copy of the OpenSSL source code instead of +using the version from the system. + +The [`curl-sys`] package is another example where the [`static-curl` +feature][curl-sys-static] causes it to build libcurl from source. Notice that +it also has a [`force-system-lib-on-osx`][curl-sys-macos] feature which forces +it [to use the system libcurl][curl-sys-macos-code], overriding the +static-curl setting. + +[`openssl`]: https://crates.io/crates/openssl +[`openssl-sys`]: https://crates.io/crates/openssl-sys +[sys]: build-scripts.md#-sys-packages +[openssl-vendored]: https://github.com/sfackler/rust-openssl/blob/openssl-v0.10.31/openssl/Cargo.toml#L19 +[build script]: build-scripts.md +[openssl-sys-cfg]: https://github.com/sfackler/rust-openssl/blob/openssl-v0.10.31/openssl-sys/build/main.rs#L47-L54 +[`curl-sys`]: https://crates.io/crates/curl-sys +[curl-sys-static]: https://github.com/alexcrichton/curl-rust/blob/0.4.34/curl-sys/Cargo.toml#L49 +[curl-sys-macos]: https://github.com/alexcrichton/curl-rust/blob/0.4.34/curl-sys/Cargo.toml#L52 +[curl-sys-macos-code]: https://github.com/alexcrichton/curl-rust/blob/0.4.34/curl-sys/build.rs#L15-L20 + +### Feature precedence + +Some packages may have mutually-exclusive features. One option to handle this +is to prefer one feature over another. The [`log`] package is an example. It +has [several features][log-features] for choosing the maximum logging level at +compile-time described [here][log-docs]. It uses [`cfg-if`] to [choose a +precedence][log-cfg-if]. If multiple features are enabled, the higher "max" +levels will be preferred over the lower levels. + +[`log`]: https://crates.io/crates/log +[log-features]: https://github.com/rust-lang/log/blob/0.4.11/Cargo.toml#L29-L42 +[log-docs]: https://docs.rs/log/0.4.11/log/#compile-time-filters +[log-cfg-if]: https://github.com/rust-lang/log/blob/0.4.11/src/lib.rs#L1422-L1448 +[`cfg-if`]: https://crates.io/crates/cfg-if + +### Proc-macro companion package + +Some packages have a proc-macro that is intimately tied with it. However, not +all users will need to use the proc-macro. By making the proc-macro an +optional-dependency, this allows you to conveniently choose whether or not it +is included. This is helpful, because sometimes the proc-macro version must +stay in sync with the parent package, and you don't want to force the users to +have to specify both dependencies and keep them in sync. + +An example is [`serde`] which has a [`derive`][serde-derive] feature which +enables the [`serde_derive`] proc-macro. The `serde_derive` crate is very +tightly tied to `serde`, so it uses an [equals version +requirement][serde-equals] to ensure they stay in sync. + +[`serde`]: https://crates.io/crates/serde +[`serde_derive`]: https://crates.io/crates/serde_derive +[serde-derive]: https://github.com/serde-rs/serde/blob/v1.0.118/serde/Cargo.toml#L34-L35 +[serde-equals]: https://github.com/serde-rs/serde/blob/v1.0.118/serde/Cargo.toml#L17 + +### Nightly-only features + +Some packages want to experiment with APIs or language features that are only +available on the Rust [nightly channel]. However, they may not want to require +their users to also use the nightly channel. An example is [`wasm-bindgen`] +which has a [`nightly` feature][wasm-bindgen-nightly] which enables an +[extended API][wasm-bindgen-unsize] that uses the [`Unsize`] marker trait that +is only available on the nightly channel at the time of this writing. + +Note that at the root of the crate it uses [`cfg_attr` to enable the nightly +feature][wasm-bindgen-cfg_attr]. Keep in mind that the [`feature` attribute] +is unrelated to Cargo features, and is used to opt-in to experimental language +features. + +The [`simd_support` feature][rand-simd_support] of the [`rand`] package is another example, +which relies on a dependency that only builds on the nightly channel. + +[`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen +[nightly channel]: ../../book/appendix-07-nightly-rust.html +[wasm-bindgen-nightly]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/Cargo.toml#L27 +[wasm-bindgen-unsize]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/closure.rs#L257-L269 +[`Unsize`]: ../../std/marker/trait.Unsize.html +[wasm-bindgen-cfg_attr]: https://github.com/rustwasm/wasm-bindgen/blob/0.2.69/src/lib.rs#L11 +[`feature` attribute]: ../../unstable-book/index.html +[`rand`]: https://crates.io/crates/rand +[rand-simd_support]: https://github.com/rust-random/rand/blob/0.7.3/Cargo.toml#L40 + +### Experimental features + +Some packages have new functionality that they may want to experiment with, +without having to commit to the stability of those APIs. The features are +usually documented that they are experimental, and thus may change or break in +the future, even during a minor release. An example is the [`async-std`] +package, which has an [`unstable` feature][async-std-unstable], which [gates +new APIs][async-std-gate] that people can opt-in to using, but may not be +completely ready to be relied upon. + +[`async-std`]: https://crates.io/crates/async-std +[async-std-unstable]: https://github.com/async-rs/async-std/blob/v1.8.0/Cargo.toml#L38-L42 +[async-std-gate]: https://github.com/async-rs/async-std/blob/v1.8.0/src/macros.rs#L46 diff --git a/src/doc/src/reference/features.md b/src/doc/src/reference/features.md index 382b43d631f..c68fbed43e2 100644 --- a/src/doc/src/reference/features.md +++ b/src/doc/src/reference/features.md @@ -1,134 +1,476 @@ ## Features -Cargo supports features to allow expression of: +Cargo "features" provide a mechanism to express [conditional compilation] and +[optional dependencies](#optional-dependencies). A package defines a set of +named features in the `[features]` table of `Cargo.toml`, and each feature can +either be enabled or disabled. Features for the package being built can be +enabled on the command-line with flags such as `--features`. Features for +dependencies can be enabled in the dependency declaration in `Cargo.toml`. -* conditional compilation options (usable through `cfg` attributes); -* optional dependencies, which enhance a package, but are not required; and -* clusters of optional dependencies, such as `postgres-all`, that would include the - `postgres` package, the `postgres-macros` package, and possibly other packages - (such as development-time mocking libraries, debugging tools, etc.). +See also the [Features Examples] chapter for some examples of how features can +be used. -A feature of a package is either an optional dependency, or a set of other -features. +[conditional compilation]: ../../reference/conditional-compilation.md +[Features Examples]: features-examples.md ### The `[features]` section -Features are defined in the `[features]` table of `Cargo.toml`. The format for -specifying features is: +Features are defined in the `[features]` table in `Cargo.toml`. Each feature +specifies an array of other features or optional dependencies that it enables. +The following examples illustrate how features could be used for a 2D image +processing library where support for different image formats can be optionally +included: ```toml -[package] -name = "awesome" +[features] +# Defines a feature named `webp` that does not enable any other features. +webp = [] +``` + +With this feature defined, [`cfg` expressions] can be used to conditionally +include code to support the requested feature at compile time. For example, +inside `lib.rs` of the package could include this: + +```rust +// This conditionally includes a module which implements WEBP support. +#[cfg(feature = "webp")] +pub mod webp; +``` + +Cargo sets features in the package using the `rustc` [`--cfg` flag], and code +can test for their presence with the [`cfg` attribute] or the [`cfg` macro]. + +Features can list other features to enable. For example, the ICO image format +can contain BMP and PNG images, so when it is enabled, it should make sure +those other features are enabled, too: + +```toml +[features] +bmp = [] +png = [] +ico = ["bmp", "png"] +webp = [] +``` + +Feature names may include characters from the [Unicode XID standard] (which +includes most letters), and additionally allows starting with `_` or digits +`0` through `9`, and after the first character may also contain `-`, `+`, or +`.`. +> **Note**: [crates.io] imposes additional constraints on feature name syntax +> that they must only be [ASCII alphanumeric] characters or `_`, `-`, or `+`. + +[crates.io]: https://crates.io/ +[Unicode XID standard]: https://unicode.org/reports/tr31/ +[ASCII alphanumeric]: ../../std/primitive.char.html#method.is_ascii_alphanumeric +[`--cfg` flag]: ../../rustc/command-line-arguments.md#option-cfg +[`cfg` expressions]: ../../reference/conditional-compilation.md +[`cfg` attribute]: ../../reference/conditional-compilation.md#the-cfg-attribute +[`cfg` macro]: ../../std/macro.cfg.html + +### The `default` feature + +By default, all features are disabled unless explicitly enabled. This can be +changed by specifying the `default` feature: + +```toml [features] -# The default set of optional packages. Most people will want to use these -# packages, but they are strictly optional. Note that `session` is not a package -# but rather another feature listed in this manifest. -default = ["jquery", "uglifier", "session"] +default = ["ico", "webp"] +bmp = [] +png = [] +ico = ["bmp", "png"] +webp = [] +``` -# A feature with no dependencies is used mainly for conditional compilation, -# like `#[cfg(feature = "go-faster")]`. -go-faster = [] +When the package is built, the `default` feature is enabled which in turn +enables the listed features. This behavior can be changed by: -# The `secure-password` feature depends on the bcrypt package. This aliasing -# will allow people to talk about the feature in a higher-level way and allow -# this package to add more requirements to the feature in the future. -secure-password = ["bcrypt"] +* The `--no-default-features` [command-line + flag](#command-line-feature-options) disables the default features of the + package. +* The `default-features = false` option can be specified in a [dependency + declaration](#dependency-features). -# Features can be used to reexport features of other packages. The `session` -# feature of package `awesome` will ensure that the `session` feature of the -# package `cookie` is also enabled. -session = ["cookie/session"] +> **Note**: Be careful about choosing the default feature set. The default +> features are a convenience that make it easier to use a package without +> forcing the user to carefully select which features to enable for common +> use, but there are some drawbacks. Dependencies automatically enable default +> features unless `default-features = false` is specified. This can make it +> difficult to ensure that the default features are not enabled, especially +> for a dependency that appears multiple times in the dependency graph. Every +> package must ensure that `default-features = false` is specified to avoid +> enabling them. +> +> Another issue is that it can be a [SemVer incompatible +> change](#semver-compatibility) to remove a feature from the default set, so +> you should be confident that you will keep those features. +### Optional dependencies + +Dependencies can be marked "optional", which means they will not be compiled +by default. For example, let's say that our 2D image processing library uses +an external package to handle GIF images. This can be expressed like this: + +```toml [dependencies] -# These packages are mandatory and form the core of this package’s distribution. -cookie = "1.2.0" -oauth = "1.1.0" -route-recognizer = "=2.1.0" - -# A list of all of the optional dependencies, some of which are included in the -# above `features`. They can be opted into by apps. -jquery = { version = "1.0.2", optional = true } -uglifier = { version = "1.5.3", optional = true } -bcrypt = { version = "*", optional = true } -civet = { version = "*", optional = true } +gif = { version = "0.11.1", optional = true } ``` -To use the package `awesome`: +Optional dependencies implicitly define a feature of the same name as the +dependency. This means that the same `cfg(feature = "gif")` syntax can be used +in the code, and the dependency can be enabled just like a feature such as +`--features gif` (see [Command-line feature +options](#command-line-feature-options) below). + +> **Note**: A feature in the `[feature]` table cannot use the same name as a +> dependency. Experimental support for enabling this and other extensions is +> available on the nightly channel via [namespaced +> features](unstable.md#namespaced-features). + +Explicitly defined features can enable optional dependencies, too. Just +include the name of the optional dependency in the feature list. For example, +let's say in order to support the AVIF image format, our library needs two +other dependencies to be enabled: ```toml -[dependencies.awesome] -version = "1.3.5" -default-features = false # do not include the default features, and optionally - # cherry-pick individual features -features = ["secure-password", "civet"] +[dependencies] +ravif = { version = "0.6.3", optional = true } +rgb = { version = "0.8.25", optional = true } + +[features] +avif = ["ravif", "rgb"] ``` -### Rules +In this example, the `avif` feature will enable the two listed dependencies. -The usage of features is subject to a few rules: +> **Note**: Another way to optionally include a dependency is to use +> [platform-specific dependencies]. Instead of using features, these are +> conditional based on the target platform. -* Feature names must not conflict with other package names in the manifest. This - is because they are opted into via `features = [...]`, which only has a single - namespace. -* With the exception of the `default` feature, all features are opt-in. To opt - out of the default feature, use `default-features = false` and cherry-pick - individual features. -* Feature groups are not allowed to cyclically depend on one another. -* Dev-dependencies cannot be optional. -* Feature groups can only reference optional dependencies. -* When a feature is selected, Cargo will call `rustc` with `--cfg - feature="${feature_name}"`. If a feature group is included, it and all of its - individual features will be included. This can be tested in code via - `#[cfg(feature = "foo")]`. +[platform-specific dependencies]: specifying-dependencies.md#platform-specific-dependencies -Note that it is explicitly allowed for features to not actually activate any -optional dependencies. This allows packages to internally enable/disable -features without requiring a new dependency. +### Dependency features -> **Note**: [crates.io] requires feature names to only contain ASCII letters, -> digits, `_`, `-`, or `+`. +Features of dependencies can be enabled within the dependency declaration. The +`features` key indicates which features to enable: -### Usage in end products +```toml +[dependencies] +# Enables the `derive` feature of serde. +serde = { version = "1.0.118", features = ["derive"] } +``` -One major use-case for this feature is specifying optional features in -end-products. For example, the Servo package may want to include optional -features that people can enable or disable when they build it. +The [`default` features](#the-default-feature) can be disabled using +`default-features = false`: -In that case, Servo will describe features in its `Cargo.toml` and they can be -enabled using command-line flags: +```toml +[dependencies] +flate2 = { version = "1.0.3", default-features = false, features = ["zlib"] } +``` + +> **Note**: This may not ensure the default features are disabled. If another +> dependency includes `flate2` without specifying `default-features = false`, +> then the default features will be enabled. See [feature +> unification](#feature-unification) below for more details. + +Features of dependencies can also be enabled in the `[features]` table. The +syntax is `"package-name/feature-name"`. For example: + +```toml +[dependencies] +jpeg-decoder = { version = "0.1.20", default-features = false } -```console -$ cargo build --release --features "shumway pdf" +[features] +# Enables parallel processing support by enabling the "rayon" feature of jpeg-decoder. +parallel = ["jpeg-decoder/rayon"] ``` -Default features could be excluded using `--no-default-features`. +> **Note**: The `"package-name/feature-name"` syntax will also enable +> `package-name` if it is an optional dependency. Experimental support for +> disabling that behavior is available on the nightly channel via [weak +> dependency features](unstable.md#weak-dependency-features). -### Usage in packages +### Command-line feature options -In most cases, the concept of *optional dependency* in a library is best -expressed as a separate package that the top-level application depends on. +The following command-line flags can be used to control which features are +enabled: -However, high-level packages, like Iron or Piston, may want the ability to -curate a number of packages for easy installation. The current Cargo system -allows them to curate a number of mandatory dependencies into a single package -for easy installation. +* `--features` _FEATURES_: Enables the listed features. Multiple features may + be separated with commas or spaces. If using spaces, be sure to use quotes + around all the features if running Cargo from a shell (such as `--features + "foo bar"`). If building multiple packages in a [workspace], the + `package-name/feature-name` syntax can be used to specify features for + specific workspace members. -In some cases, packages may want to provide additional curation for optional -dependencies: +* `--all-features`: Activates all features of all packages selected on the + command-line. -* grouping a number of low-level optional dependencies together into a single - high-level feature; -* specifying packages that are recommended (or suggested) to be included by - users of the package; and -* including a feature (like `secure-password` in the motivating example) that - will only work if an optional dependency is available, and would be difficult - to implement as a separate package (for example, it may be overly difficult to - design an IO package to be completely decoupled from OpenSSL, with opt-in via - the inclusion of a separate package). +* `--no-default-features`: Does not activate the [`default` + feature](#the-default-feature) of the selected packages. -In almost all cases, it is an antipattern to use these features outside of -high-level packages that are designed for curation. If a feature is optional, it -can almost certainly be expressed as a separate package. +[workspace]: workspaces.md -[crates.io]: https://crates.io/ +### Feature unification + +Features are unique to the package that defines them. Enabling a feature on a +package does not enable a feature of the same name on other packages. + +When a dependency is used by multiple packages, Cargo will use the union of +all features enabled on that dependency when building it. This helps ensure +that only a single copy of the dependency is used. See the [features section] +of the resolver documentation for more details. + +For example, let's look at the [`winapi`] package which uses a [large +number][winapi-features] of features. If your package depends on a package +`foo` which enables the "fileapi" and "handleapi" features of `winapi`, and +another dependency `bar` which enables the "std" and "winnt" features of +`winapi`, then `winapi` will be built with all four of those features enabled. + +![winapi features example](../images/winapi-features.svg) + +[`winapi`]: https://crates.io/crates/winapi +[winapi-features]: https://github.com/retep998/winapi-rs/blob/0.3.9/Cargo.toml#L25-L431 + +A consequence of this is that features should be *additive*. That is, enabling +a feature should not disable functionality, and it should usually be safe to +enable any combination of features. A feature should not introduce a +[SemVer-incompatible change](#semver-compatibility). + +For example, if you want to optionally support [`no_std`] environments, **do +not** use a `no_std` feature. Instead, use a `std` feature that *enables* +`std`. For example: + +```rust +#![no_std] + +#[cfg(feature = "std")] +extern crate std; + +#[cfg(feature = "std")] +pub fn function_that_requires_std() { + // ... +} +``` + +[`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std +[features section]: resolver.md#features + +#### Mutually exclusive features + +There are rare cases where features may be mutually incompatible with one +another. This should be avoided if at all possible, because it requires +coordinating all uses of the package in the dependency graph to cooperate to +avoid enabling them together. If it is not possible, consider adding a compile +error to detect this scenario. For example: + +```rust,ignore +#[cfg(all(feature = "foo", feature = "bar"))] +compile_error!("feature \"foo\" and feature \"bar\" cannot be enabled at the same time"); +``` + +Instead of using mutually exclusive features, consider some other options: + +* Split the functionality into separate packages. +* When there is a conflict, [choose one feature over + another][feature-precedence]. The [`cfg-if`] package can help with writing + more complex `cfg` expressions. +* Architect the code to allow the features to be enabled concurrently, and use + runtime options to control which is used. For example, use a config file, + command-line argument, or environment variable to choose which behavior to + enable. + +[`cfg-if`]: https://crates.io/crates/cfg-if +[feature-precedence]: features-examples.md#feature-precedence + +#### Inspecting resolved features + +In complex dependency graphs, it can sometimes be difficult to understand how +different features get enabled on various packages. The [`cargo tree`] command +offers several options to help inspect and visualize which features are +enabled. Some options to try: + +* `cargo tree -e features`: This will show features in the dependency graph. + Each feature will appear showing which package enabled it. +* `cargo tree -f "{p} {f}"`: This is a more compact view that shows a + comma-spearated list of features enabled on each package. +* `cargo tree -e features -i foo`: This will invert the tree, showing how + features flow into the given package "foo". This can be useful because + viewing the entire graph can be quite large and overwhelming. Use this when + you are trying to figure out which features are enabled on a specific + package and why. See the example at the bottom of the [`cargo tree`] page on + how to read this. + +[`cargo tree`]: ../commands/cargo-tree.md + +### Feature resolver version 2 + +A different feature resolver can be specified with the `resolver` field in +`Cargo.toml`, like this: + +```toml +[package] +name = "my-package" +version = "1.0.0" +resolver = "2" +``` + +See the [resolver versions] section for more detail on specifying resolver +versions. + +The version `"2"` resolver avoids unifying features in a few situations where +that unification can be unwanted. The exact situations are described in the +[resolver chapter][resolver-v2], but in short, it avoids unifying in these +situations: + +* Features enabled on [platform-specific dependencies] for targets not + currently being built are ignored. +* [Build-dependencies] and proc-macros do not share features with normal + dependencies. +* [Dev-dependencies] do not activate features unless building a target that + needs them (like tests or examples). + +Avoiding the unification is necessary for some situations. For example, if a +build-dependency enables a `std` feature, and the same dependency is used as a +normal dependency for a `no_std` environment, enabling `std` would break the +build. + +However, one drawback is that this can increase build times because the +dependency is built multiple times (each with different features). When using +the version `"2"` resolver, it is recommended to check for dependencies that +are built multiple times to reduce overall build time. If it is not *required* +to build those duplicated packages with separate features, consider adding +features to the `features` list in the [dependency +declaration](#dependency-features) so that the duplicates end up with the same +features (and thus Cargo will build it only once). You can detect these +duplicate dependencies with the [`cargo tree --duplicates`][`cargo tree`] +command. It will show which packages are built multiple times; look for any +entries listed with the same version. See [Inspecting resolved +features](#inspecting-resolved-features) for more on fetching information on +the resolved features. For build dependencies, this is not necessary if you +are cross-compiling with the `--target` flag because build dependencies are +always built separately from normal dependencies in that scenario. + +#### Resolver version 2 command-line flags + +The `resolver = "2"` setting also changes the behavior of the `--features` and +`--no-default-features` [command-line options](#command-line-feature-options). + +With version `"1"`, you can only enable features for the package in the +current working directory. For example, in a workspace with packages `foo` and +`bar`, and you are in the directory for package `foo`, and ran the command +`cargo build -p bar --features bar-feat`, this would fail because the +`--features` flag only allowed enabling features on `foo`. + +With `resolver = "2"`, the features flags allow enabling features for any of +the packages selected on the command-line with `-p` and `--workspace` flags. +For example: + +```sh +# This command is allowed with resolver = "2", regardless of which directory +# you are in. +cargo build -p foo -p bar --features foo-feat,bar-feat +``` + +Additionally, with `resolver = "1"`, the `--no-default-features` flag only +disables the default feature for the package in the current directory. With +version "2", it will disable the default features for all workspace members. + +[resolver versions]: resolver.md#resolver-versions +[build-dependencies]: specifying-dependencies.md#build-dependencies +[dev-dependencies]: specifying-dependencies.md#development-dependencies +[resolver-v2]: resolver.md#feature-resolver-version-2 + +### Build scripts + +[Build scripts] can detect which features are enabled on the package by +inspecting the `CARGO_FEATURE_` environment variable, where `` is +the feature name converted to uppercase and `-` converted to `_`. + +[build scripts]: build-scripts.md + +### Required features + +The [`required-features` field] can be used to disable specific [Cargo +targets] if a feature is not enabled. See the linked documentation for more +details. + +[`required-features` field]: cargo-targets.md#the-required-features-field +[Cargo targets]: cargo-targets.md + +### SemVer compatibility + +Enabling a feature should not introduce a SemVer-incompatible change. For +example, the feature shouldn't change an existing API in a way that could +break existing uses. More details about what changes are compatible can be +found in the [SemVer Compatibility chapter](semver.md). + +Care should be taken when adding and removing feature definitions and optional +dependencies, as these can sometimes be backwards-incompatible changes. More +details can be found in the [Cargo section](semver.md#cargo) of the SemVer +Compatibility chapter. In short, follow these rules: + +* The following is usually safe to do in a minor release: + * Add a [new feature][cargo-feature-add] or [optional dependency][cargo-dep-add]. + * [Change the features used on a dependency][cargo-change-dep-feature]. +* The following should usually **not** be done in a minor release: + * [Remove a feature][cargo-feature-remove] or [optional dependency][cargo-remove-opt-dep]. + * [Moving existing public code behind a feature][item-remove]. + * [Remove a feature from a feature list][cargo-feature-remove-another]. + +See the links for caveats and examples. + +[cargo-change-dep-feature]: semver.md#cargo-change-dep-feature +[cargo-dep-add]: semver.md#cargo-dep-add +[cargo-feature-add]: semver.md#cargo-feature-add +[item-remove]: semver.md#item-remove +[cargo-feature-remove]: semver.md#cargo-feature-remove +[cargo-remove-opt-dep]: semver.md#cargo-remove-opt-dep +[cargo-feature-remove-another]: semver.md#cargo-feature-remove-another + +### Feature documentation and discovery + +You are encouraged to document which features are available in your package. +This can be done by adding [doc comments] at the top of `lib.rs`. As an +example, see the [regex crate source], which when rendered can be viewed on +[docs.rs][regex-docs-rs]. If you have other documentation, such as a user +guide, consider adding the documentation there (for example, see [serde.rs]). +If you have a binary project, consider documenting the features in the README +or other documentation for the project (for example, see [sccache]). + +Clearly documenting the features can set expectations about features +considered "unstable" or otherwise shouldn't be used. For example, if there is +an optional dependency, but you don't want users to explicitly list that +optional dependency as a feature, exclude it from the documented list. + +Documentation published on [docs.rs] can use metadata in `Cargo.toml` to +control which features are enabled when the documentation is built. See +[docs.rs metadata documentation] for more details. + +> **Note**: Rustdoc has experimental support for annotating the documentation +> to indicate which features are required to use certain APIs. See the +> [`doc_cfg`] documentation for more details. An example is the [`syn` +> documentation], where you can see colored boxes which note which features +> are required to use it. + +[docs.rs metadata documentation]: https://docs.rs/about/metadata +[docs.rs]: https://docs.rs/ +[serde.rs]: https://serde.rs/feature-flags.html +[doc comments]: ../../rustdoc/how-to-write-documentation.html +[regex crate source]: https://github.com/rust-lang/regex/blob/1.4.2/src/lib.rs#L488-L583 +[regex-docs-rs]: https://docs.rs/regex/1.4.2/regex/#crate-features +[sccache]: https://github.com/mozilla/sccache/blob/0.2.13/README.md#build-requirements +[`doc_cfg`]: ../../unstable-book/language-features/doc-cfg.html +[`syn` documentation]: https://docs.rs/syn/1.0.54/syn/#modules + +#### Discovering features + +When features are documented in the library API, this can make it easier for +your users to discover which features are available and what they do. If the +feature documentation for a package isn't readily available, you can look at +the `Cargo.toml` file, but sometimes it can be hard to track it down. The +crate page on [crates.io] has a link to the source repository if available. +Tools like [`cargo vendor`] or [cargo-clone-crate] can be used to download the +source and inspect it. + +[`cargo vendor`]: ../commands/cargo-vendor.md +[cargo-clone-crate]: https://crates.io/crates/cargo-clone-crate diff --git a/src/doc/src/reference/index.md b/src/doc/src/reference/index.md index 1d172beba4c..ced87fa61b7 100644 --- a/src/doc/src/reference/index.md +++ b/src/doc/src/reference/index.md @@ -8,6 +8,7 @@ The reference covers the details of various areas of Cargo. * [Cargo Targets](cargo-targets.md) * [Workspaces](workspaces.md) * [Features](features.md) + * [Features Examples](features-examples.md) * [Profiles](profiles.md) * [Configuration](config.md) * [Environment Variables](environment-variables.md) diff --git a/src/doc/src/reference/manifest.md b/src/doc/src/reference/manifest.md index 89462a63bbd..e9957bd90ab 100644 --- a/src/doc/src/reference/manifest.md +++ b/src/doc/src/reference/manifest.md @@ -30,6 +30,7 @@ in the [TOML] format. Every manifest file consists of the following sections: * [`autoexamples`](cargo-targets.md#target-auto-discovery) — Disables example auto discovery. * [`autotests`](cargo-targets.md#target-auto-discovery) — Disables test auto discovery. * [`autobenches`](cargo-targets.md#target-auto-discovery) — Disables bench auto discovery. + * [`resolver`](resolver.md#resolver-versions) — Sets the dependency resolver to use. * Target tables: (see [configuration](cargo-targets.md#configuring-a-target) for settings) * [`[lib]`](cargo-targets.md#library) — Library target settings. * [`[[bin]]`](cargo-targets.md#binaries) — Binary target settings. @@ -532,9 +533,9 @@ more detail. "#virtual-manifest": "workspaces.html", "#package-selection": "workspaces.html#package-selection", "#the-features-section": "features.html#the-features-section", - "#rules": "features.html#rules", - "#usage-in-end-products": "features.html#usage-in-end-products", - "#usage-in-packages": "features.html#usage-in-packages", + "#rules": "features.html", + "#usage-in-end-products": "features.html", + "#usage-in-packages": "features.html", "#the-patch-section": "overriding-dependencies.html#the-patch-section", "#using-patch-with-multiple-versions": "overriding-dependencies.html#using-patch-with-multiple-versions", "#the-replace-section": "overriding-dependencies.html#the-replace-section", diff --git a/src/doc/src/reference/resolver.md b/src/doc/src/reference/resolver.md index 029f6b90e79..d6a97f1621b 100644 --- a/src/doc/src/reference/resolver.md +++ b/src/doc/src/reference/resolver.md @@ -193,11 +193,13 @@ the other constraints that can affect resolution. ### Features -The resolver resolves the graph as-if the [features] of all [workspace] -members are enabled. This ensures that any optional dependencies are available -and properly resolved with the rest of the graph when features are added or -removed with the `--features` command-line flag. The actual features used when -*compiling* a crate will depend on the features enabled on the command-line. +For the purpose of generating `Cargo.lock`, the resolver builds the dependency +graph as-if all [features] of all [workspace] members are enabled. This +ensures that any optional dependencies are available and properly resolved +with the rest of the graph when features are added or removed with the +[`--features` command-line flag](features.md#command-line-feature-options). +The resolver runs a second time to determine the actual features used when +*compiling* a crate, based on the features selected on the command-line. Dependencies are resolved with the union of all features enabled on them. For example, if one package depends on the [`im`] package with the [`serde` @@ -207,6 +209,12 @@ the `serde` and `rayon` crates will be included in the resolve graph. If no packages depend on `im` with those features, then those optional dependencies will be ignored, and they will not affect resolution. +When building multiple packages in a workspace (such as with `--workspace` or +multiple `-p` flags), the features of the dependencies of all of those +packages are unified. If you have a circumstance where you want to avoid that +unification for different workspace members, you will need to build them via +separate `cargo` invocations. + The resolver will skip over versions of packages that are missing required features. For example, if a package depends on version `^1` of [`regex`] with the [`perf` feature], then the oldest version it can select is `1.3.0`, @@ -227,6 +235,69 @@ optional dependency]. [removing an optional dependency]: semver.md#cargo-remove-opt-dep [workspace]: workspaces.md +#### Feature resolver version 2 + +When `resolver = "2"` is specified in `Cargo.toml` (see [resolver +versions](#resolver-versions) below), a different feature resolver is used +which uses a different algorithm for unifying features. The version `"1"` +resolver will unify features for a package no matter where it is specified. +The version `"2"` resolver will avoid unifying features in the following +situations: + +* Features for target-specific dependencies are not enabled if the target is + not currently being built. For example: + + ```toml + [dependency.common] + version = "1.0" + features = ["f1"] + + [target.'cfg(windows)'.dependencies.common] + version = "1.0" + features = ["f2"] + ``` + + When building this example for a non-Windows platform, the `f2` feature will + *not* be enabled. + +* Features enabled on [build-dependencies] or proc-macros will not be unified + when those same dependencies are used as a normal dependency. For example: + + ```toml + [dependencies] + log = "0.4" + + [build-dependencies] + log = {version = "0.4", features=['std']} + ``` + + When building the build script, the `log` crate will be built with the `std` + feature. When building the library of your package, it will not enable the + feature. + +* Features enabled on [dev-dependencies] will not be unified when those same + dependencies are used as a normal dependency, unless those dev-dependencies + are currently being built. For example: + + ```toml + [dependencies] + serde = {version = "1.0", default-features = false} + + [dev-dependencies] + serde = {version = "1.0", features = ["std"]} + ``` + + In this example, the library will normally link against `serde` without the + `std` feature. However, when built as a test or example, it will include the + `std` feature. For example, `cargo test` or `cargo build --all-targets` will + unify these features. Note that dev-dependencies in dependencies are always + ignored, this is only relevant for the top-level package or workspace + members. + +[build-dependencies]: specifying-dependencies.md#build-dependencies +[dev-dependencies]: specifying-dependencies.md#development-dependencies +[resolver-field]: features.md#resolver-versions + ### `links` The [`links` field] is used to ensure only one copy of a native library is @@ -325,6 +396,39 @@ types. If possible, try to split your package into multiple packages and restructure it so that it remains strictly acyclic. +## Resolver versions + +A different feature resolver algorithm can be used by specifying the resolver +version in `Cargo.toml` like this: + +```toml +[package] +name = "my-package" +version = "1.0.0" +resolver = "2" +``` + +The version `"1"` resolver is the original resolver that shipped with Cargo up +to version 1.50, and is the default if the `resolver` is not specified. + +The version `"2"` resolver introduces changes in [feature +unification](#features). See the [features chapter][features-2] for more +details. + +The resolver is a global option that affects the entire workspace. The +`resolver` version in dependencies is ignored, only the value in the top-level +package will be used. If using a [virtual workspace], the version should be +specified in the `[workspace]` table, for example: + +```toml +[workspace] +members = ["member1", "member2"] +resolver = "2" +``` + +[virtual workspace]: workspaces.md#virtual-manifest +[features-2]: features.md#feature-resolver-version-2 + ## Recommendations The following are some recommendations for setting the version within your diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md index f081321838e..598d88bdcf7 100644 --- a/src/doc/src/reference/semver.md +++ b/src/doc/src/reference/semver.md @@ -96,6 +96,7 @@ considered incompatible. * Cargo * [Minor: adding a new Cargo feature](#cargo-feature-add) * [Major: removing a Cargo feature](#cargo-feature-remove) + * [Major: removing a feature from a feature list if that changes functionality or public items](#cargo-feature-remove-another) * [Possibly-breaking: removing an optional dependency](#cargo-remove-opt-dep) * [Minor: changing dependency features](#cargo-change-dep-feature) * [Minor: adding dependencies](#cargo-dep-add) @@ -132,6 +133,9 @@ fn main() { } ``` +This includes adding any sort of [`cfg` attribute] which can change which +items or behavior is available based on [conditional compilation]. + Mitigating strategies: * Mark items to be removed as [deprecated], and then remove them at a later date in a SemVer-breaking release. @@ -1212,6 +1216,28 @@ Mitigation strategies: functionality. Document that the feature is deprecated, and remove it in a future major SemVer release. + +#### Major: removing a feature from a feature list if that changes functionality or public items + +If removing a feature from another feature, this can break existing users if +they are expecting that functionality to be available through that feature. + +```toml +# Breaking change example + +########################################################### +# Before +[features] +default = ["std"] +std = [] + +########################################################### +# After +[features] +default = [] # This may cause packages to fail if they are expecting std to be enabled. +std = [] +``` + #### Possibly-breaking: removing an optional dependency @@ -1301,12 +1327,14 @@ to list, so you are encouraged to use the spirit of the [SemVer] spec to guide your decisions on how to apply versioning to your application, or at least document what your commitments are. +[`cfg` attribute]: ../../reference/conditional-compilation.md#the-cfg-attribute [`no_std`]: ../../reference/crates-and-source-files.html#preludes-and-no_std [`pub use`]: ../../reference/items/use-declarations.html [Cargo feature]: features.md [Cargo features]: features.md [cfg-accessible]: https://github.com/rust-lang/rust/issues/64797 [cfg-version]: https://github.com/rust-lang/rust/issues/64796 +[conditional compilation]: ../../reference/conditional-compilation.md [Default]: ../../std/default/trait.Default.html [deprecated]: ../../reference/attributes/diagnostics.html#the-deprecated-attribute [disambiguation syntax]: ../../reference/expressions/call-expr.html#disambiguating-function-calls diff --git a/src/doc/src/reference/specifying-dependencies.md b/src/doc/src/reference/specifying-dependencies.md index c5ee0ccca52..3e679ce3088 100644 --- a/src/doc/src/reference/specifying-dependencies.md +++ b/src/doc/src/reference/specifying-dependencies.md @@ -383,7 +383,7 @@ features = ["secure-password", "civet"] ``` More information about features can be found in the [features -chapter](features.md). +chapter](features.md#dependency-features). ### Renaming dependencies in `Cargo.toml` diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 4ffc13f450f..92bc5204e91 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -577,140 +577,6 @@ cargo +nightly -Zunstable-options -Zconfig-include --config somefile.toml build CLI paths are relative to the current working directory. -### Features -* Tracking Issues: - * [itarget #7914](https://github.com/rust-lang/cargo/issues/7914) - * [build_dep #7915](https://github.com/rust-lang/cargo/issues/7915) - * [dev_dep #7916](https://github.com/rust-lang/cargo/issues/7916) - -The `-Zfeatures` option causes Cargo to use a new feature resolver that can -resolve features differently from before. It takes a comma separated list of -options to indicate which new behaviors to enable. With no options, it should -behave the same as without the flag. - -```console -cargo +nightly -Zfeatures=itarget,build_dep -``` - -The available options are: - -* `itarget` — Ignores features for target-specific dependencies for targets - that don't match the current compile target. For example: - - ```toml - [dependency.common] - version = "1.0" - features = ["f1"] - - [target.'cfg(windows)'.dependencies.common] - version = "1.0" - features = ["f2"] - ``` - - When building this example for a non-Windows platform, the `f2` feature will - *not* be enabled. - -* `host_dep` — Prevents features enabled on build dependencies or proc-macros - from being enabled for normal dependencies. For example: - - ```toml - [dependencies] - log = "0.4" - - [build-dependencies] - log = {version = "0.4", features=['std']} - ``` - - When building the build script, the `log` crate will be built with the `std` - feature. When building the library of your package, it will not enable the - feature. - - Note that proc-macro decoupling requires changes to the registry, so it - won't be decoupled until the registry is updated to support the new field. - -* `dev_dep` — Prevents features enabled on dev dependencies from being enabled - for normal dependencies. For example: - - ```toml - [dependencies] - serde = {version = "1.0", default-features = false} - - [dev-dependencies] - serde = {version = "1.0", features = ["std"]} - ``` - - In this example, the library will normally link against `serde` without the - `std` feature. However, when built as a test or example, it will include the - `std` feature. - - This mode is ignored if you are building any test, bench, or example. That - is, dev dependency features will still be unified if you run commands like - `cargo test` or `cargo build --all-targets`. - -* `all` — Enable all feature options (`itarget,build_dep,dev_dep`). - -* `compare` — This option compares the resolved features to the old resolver, - and will print any differences. - -### package-features -* Tracking Issue: [#5364](https://github.com/rust-lang/cargo/issues/5364) - -The `-Zpackage-features` flag changes the way features can be passed on the -command-line for a workspace. The normal behavior can be confusing, as the -features passed are always enabled on the package in the current directory, -even if that package is not selected with a `-p` flag. Feature flags also do -not work in the root of a virtual workspace. `-Zpackage-features` tries to -make feature flags behave in a more intuitive manner. - -* `cargo build -p other_member --features …` — This now only enables the given - features as defined in `other_member` (ignores whatever is in the current - directory). -* `cargo build -p a -p b --features …` — This now enables the given features - on both `a` and `b`. Not all packages need to define every feature, it only - enables matching features. It is still an error if none of the packages - define a given feature. -* `--features` and `--no-default-features` are now allowed in the root of a - virtual workspace. -* `member_name/feature_name` syntax may now be used on the command-line to - enable features for a specific member. - -The ability to set features for non-workspace members is no longer allowed, as -the resolver fundamentally does not support that ability. - -### Resolver -* Tracking Issue: [#8088](https://github.com/rust-lang/cargo/issues/8088) - -The `resolver` feature allows the resolver version to be specified in the -`Cargo.toml` manifest. This allows a project to opt-in to -backwards-incompatible changes in the resolver. - -```toml -cargo-features = ["resolver"] - -[package] -name = "my-package" -version = "1.0.0" -resolver = "2" -``` - -The value `"1"` is the current resolver behavior on the stable channel. A -value of `"2"` enables all of the new feature behavior of -[`-Zfeatures=all`](#features) and [`-Zpackage-features`](#package-features). - -This flag is global for a workspace. If using a virtual workspace, the root -definition should be in the `[workspace]` table like this: - -```toml -cargo-features = ["resolver"] - -[workspace] -members = ["member1", "member2"] -resolver = "2" -``` - -The `resolver` field is ignored in dependencies, only the top-level project or -workspace can control the new behavior. - ### unit-graph * Tracking Issue: [#8002](https://github.com/rust-lang/cargo/issues/8002) diff --git a/src/etc/man/cargo-bench.1 b/src/etc/man/cargo-bench.1 index f0875b1a4b4..6128671c7ff 100644 --- a/src/etc/man/cargo-bench.1 +++ b/src/etc/man/cargo-bench.1 @@ -208,21 +208,18 @@ manifest settings for the target. Benchmark all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -232,7 +229,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-build.1 b/src/etc/man/cargo-build.1 index 6f25076f277..613a72c98b2 100644 --- a/src/etc/man/cargo-build.1 +++ b/src/etc/man/cargo-build.1 @@ -129,21 +129,18 @@ manifest settings for the target. Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -153,7 +150,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-check.1 b/src/etc/man/cargo-check.1 index b088a1392d5..c135993025f 100644 --- a/src/etc/man/cargo-check.1 +++ b/src/etc/man/cargo-check.1 @@ -134,21 +134,18 @@ manifest settings for the target. Check all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -158,7 +155,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-doc.1 b/src/etc/man/cargo-doc.1 index 7d36e680850..561270dfd02 100644 --- a/src/etc/man/cargo-doc.1 +++ b/src/etc/man/cargo-doc.1 @@ -94,21 +94,18 @@ and supports common Unix glob patterns. Document all binary targets. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -118,7 +115,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-fix.1 b/src/etc/man/cargo-fix.1 index 80b4c34cd83..a66e0653fbe 100644 --- a/src/etc/man/cargo-fix.1 +++ b/src/etc/man/cargo-fix.1 @@ -207,21 +207,18 @@ manifest settings for the target. Fix all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -231,7 +228,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-install.1 b/src/etc/man/cargo-install.1 index 9aae0efb601..a755481fa38 100644 --- a/src/etc/man/cargo-install.1 +++ b/src/etc/man/cargo-install.1 @@ -202,21 +202,18 @@ which is defined by the \fBregistry.default\fR config key which defaults to The URL of the registry index to use. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -226,7 +223,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-metadata.1 b/src/etc/man/cargo-metadata.1 index aad4cdd571b..08655d3b5bf 100644 --- a/src/etc/man/cargo-metadata.1 +++ b/src/etc/man/cargo-metadata.1 @@ -307,21 +307,18 @@ dependencies. Each package definition is intended to be an unaltered reproduction of the information within \fBCargo.toml\fR\&. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -331,7 +328,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Display Options" .sp diff --git a/src/etc/man/cargo-package.1 b/src/etc/man/cargo-package.1 index 24b4395189c..c2276e782ed 100644 --- a/src/etc/man/cargo-package.1 +++ b/src/etc/man/cargo-package.1 @@ -116,21 +116,18 @@ specified with the \fBCARGO_TARGET_DIR\fR environment variable, or the to \fBtarget\fR in the root of the workspace. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -140,7 +137,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Manifest Options" .sp diff --git a/src/etc/man/cargo-publish.1 b/src/etc/man/cargo-publish.1 index 61c8562fe7a..33920279f5a 100644 --- a/src/etc/man/cargo-publish.1 +++ b/src/etc/man/cargo-publish.1 @@ -107,21 +107,18 @@ specified with the \fBCARGO_TARGET_DIR\fR environment variable, or the to \fBtarget\fR in the root of the workspace. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -131,7 +128,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Manifest Options" .sp diff --git a/src/etc/man/cargo-run.1 b/src/etc/man/cargo-run.1 index 61382426c01..c9593c217a1 100644 --- a/src/etc/man/cargo-run.1 +++ b/src/etc/man/cargo-run.1 @@ -40,21 +40,18 @@ Run the specified binary. Run the specified example. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -64,7 +61,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-rustc.1 b/src/etc/man/cargo-rustc.1 index ca205f04786..495b1de77eb 100644 --- a/src/etc/man/cargo-rustc.1 +++ b/src/etc/man/cargo-rustc.1 @@ -115,21 +115,18 @@ manifest settings for the target. Build all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -139,7 +136,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-rustdoc.1 b/src/etc/man/cargo-rustdoc.1 index 511141b61a0..a31679712a0 100644 --- a/src/etc/man/cargo-rustdoc.1 +++ b/src/etc/man/cargo-rustdoc.1 @@ -124,21 +124,18 @@ manifest settings for the target. Document all targets. This is equivalent to specifying \fB\-\-lib \-\-bins \-\-tests \-\-benches \-\-examples\fR\&. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -148,7 +145,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-test.1 b/src/etc/man/cargo-test.1 index fa66fc71451..7ce87ea1078 100644 --- a/src/etc/man/cargo-test.1 +++ b/src/etc/man/cargo-test.1 @@ -225,21 +225,18 @@ Test only the library's documentation. This cannot be mixed with other target options. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -249,7 +246,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Compilation Options" .sp diff --git a/src/etc/man/cargo-tree.1 b/src/etc/man/cargo-tree.1 index 34afebc18a9..dc315ad8403 100644 --- a/src/etc/man/cargo-tree.1 +++ b/src/etc/man/cargo-tree.1 @@ -260,21 +260,18 @@ offline. May also be specified with the \fBnet.offline\fR \fIconfig value\fR \&. .RE .SS "Feature Selection" -The feature flags allow you to control the enabled features for the "current" -package. The "current" package is the package in the current directory, or the -one specified in \fB\-\-manifest\-path\fR\&. If running in the root of a virtual -workspace, then the default features are selected for all workspace members, -or all features if \fB\-\-all\-features\fR is specified. +The feature flags allow you to control which features are enabled. When no +feature options are given, the \fBdefault\fR feature is activated for every +selected package. .sp -When no feature options are given, the \fBdefault\fR feature is activated for -every selected package. +See \fIthe features documentation\fR +for more details. .sp \fB\-\-features\fR \fIfeatures\fR .RS 4 -Space or comma separated list of features to activate. These features only -apply to the current directory's package. Features of direct dependencies -may be enabled with \fB/\fR syntax. This flag may be -specified multiple times, which enables all specified features. +Space or comma separated list of features to activate. Features of workspace +members may be enabled with \fBpackage\-name/feature\-name\fR syntax. This flag may +be specified multiple times, which enables all specified features. .RE .sp \fB\-\-all\-features\fR @@ -284,7 +281,7 @@ Activate all available features of all selected packages. .sp \fB\-\-no\-default\-features\fR .RS 4 -Do not activate the \fBdefault\fR feature of the current directory's package. +Do not activate the \fBdefault\fR feature of the selected packages. .RE .SS "Display Options" .sp diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs index 6bd49e80109..c4bc09ad473 100644 --- a/tests/testsuite/features.rs +++ b/tests/testsuite/features.rs @@ -1643,76 +1643,6 @@ fn cli_parse_ok() { p.cargo("run --features a b").run(); } -#[cargo_test] -fn virtual_ws_flags() { - // Reject features flags in the root of a virtual workspace. - let p = project() - .file( - "Cargo.toml", - r#" - [workspace] - members = ["a"] - "#, - ) - .file( - "a/Cargo.toml", - r#" - [package] - name = "a" - version = "0.1.0" - - [features] - f1 = [] - "#, - ) - .file("a/src/lib.rs", "") - .build(); - - p.cargo("build --features=f1") - .with_stderr( - "[ERROR] --features is not allowed in the root of a virtual workspace\n\ - [NOTE] while this was previously accepted, it didn't actually do anything\n\ - [HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package", - ) - .with_status(101) - .run(); - - p.cargo("build --no-default-features") - .with_stderr( - "[ERROR] --no-default-features is not allowed in the root of a virtual workspace\n\ - [NOTE] while this was previously accepted, it didn't actually do anything\n\ - [HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package", - ) - .with_status(101) - .run(); - - // It's OK if cwd is in a member. - p.cargo("check --features=f1 -v") - .cwd("a") - .with_stderr( - "\ -[CHECKING] a [..] -[RUNNING] `rustc --crate-name a a/src/lib.rs [..]--cfg [..]feature[..]f1[..] -[FINISHED] dev [..] -", - ) - .run(); - - p.cargo("clean").run(); - - // And -Zpackage-features is OK because it is designed to support this. - p.cargo("check --features=f1 -p a -Z package-features -v") - .masquerade_as_nightly_cargo() - .with_stderr( - "\ -[CHECKING] a [..] -[RUNNING] `rustc --crate-name a a/src/lib.rs [..]--cfg [..]feature[..]f1[..] -[FINISHED] dev [..] -", - ) - .run(); -} - #[cargo_test] fn all_features_virtual_ws() { // What happens with `--all-features` in the root of a virtual workspace. diff --git a/tests/testsuite/features2.rs b/tests/testsuite/features2.rs index e6731a43186..3f943d8aa44 100644 --- a/tests/testsuite/features2.rs +++ b/tests/testsuite/features2.rs @@ -5,9 +5,25 @@ use cargo_test_support::install::cargo_home; use cargo_test_support::paths::CargoPathExt; use cargo_test_support::publish::validate_crate_contents; use cargo_test_support::registry::{Dependency, Package}; -use cargo_test_support::{basic_manifest, cargo_process, project, rustc_host}; +use cargo_test_support::{basic_manifest, cargo_process, project, rustc_host, Project}; use std::fs::File; +/// Switches Cargo.toml to use `resolver = "2"`. +pub fn switch_to_resolver_2(p: &Project) { + let mut manifest = p.read_file("Cargo.toml"); + if manifest.contains("resolver =") { + panic!("did not expect manifest to already contain a resolver setting"); + } + if let Some(index) = manifest.find("[workspace]\n") { + manifest.insert_str(index + 12, "resolver = \"2\"\n"); + } else if let Some(index) = manifest.find("[package]\n") { + manifest.insert_str(index + 10, "resolver = \"2\"\n"); + } else { + panic!("expected [package] or [workspace] in manifest"); + } + p.change_file("Cargo.toml", &manifest); +} + #[cargo_test] fn inactivate_targets() { // Basic test of `itarget`. A shared dependency where an inactive [target] @@ -52,9 +68,8 @@ fn inactivate_targets() { .with_stderr_contains("[..]f1 should not activate[..]") .run(); - p.cargo("check -Zfeatures=itarget") - .masquerade_as_nightly_cargo() - .run(); + switch_to_resolver_2(&p); + p.cargo("check").run(); } #[cargo_test] @@ -167,26 +182,14 @@ fn inactive_target_optional() { .with_stdout("common\nf4\n") .run(); - p.cargo("run -Zfeatures=itarget --all-features") - .masquerade_as_nightly_cargo() + switch_to_resolver_2(&p); + p.cargo("run --all-features") .with_stdout("foo1\nfoo2\ndep1\ndep2\ncommon") .run(); - p.cargo("run -Zfeatures=itarget --features dep1") - .masquerade_as_nightly_cargo() - .with_stdout("dep1\n") - .run(); - p.cargo("run -Zfeatures=itarget --features foo1") - .masquerade_as_nightly_cargo() - .with_stdout("foo1\n") - .run(); - p.cargo("run -Zfeatures=itarget --features dep2") - .masquerade_as_nightly_cargo() - .with_stdout("dep2\n") - .run(); - p.cargo("run -Zfeatures=itarget --features common") - .masquerade_as_nightly_cargo() - .with_stdout("common") - .run(); + p.cargo("run --features dep1").with_stdout("dep1\n").run(); + p.cargo("run --features foo1").with_stdout("foo1\n").run(); + p.cargo("run --features dep2").with_stdout("dep2\n").run(); + p.cargo("run --features common").with_stdout("common").run(); } #[cargo_test] @@ -216,20 +219,16 @@ fn itarget_proc_macro() { .file("src/lib.rs", "") .build(); + // Old behavior + p.cargo("check").run(); + p.cargo("check --target").arg(alternate()).run(); + + // New behavior + switch_to_resolver_2(&p); p.cargo("check").run(); - p.cargo("check -Zfeatures=itarget") - .masquerade_as_nightly_cargo() - .run(); p.cargo("check --target").arg(alternate()).run(); - p.cargo("check -Zfeatures=itarget --target") - .arg(alternate()) - .masquerade_as_nightly_cargo() - .run(); // For good measure, just make sure things don't break. - p.cargo("check -Zfeatures=all --target") - .arg(alternate()) - .masquerade_as_nightly_cargo() - .run(); + p.cargo("check --target").arg(alternate()).run(); } #[cargo_test] @@ -279,9 +278,8 @@ fn decouple_host_deps() { .with_stderr_contains("[..]unresolved import `common::bar`[..]") .run(); - p.cargo("check -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() - .run(); + switch_to_resolver_2(&p); + p.cargo("check").run(); } #[cargo_test] @@ -344,9 +342,8 @@ fn decouple_host_deps_nested() { .with_stderr_contains("[..]unresolved import `common::bar`[..]") .run(); - p.cargo("check -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() - .run(); + switch_to_resolver_2(&p); + p.cargo("check").run(); } #[cargo_test] @@ -449,7 +446,7 @@ fn decouple_dev_deps() { #[test] fn test_main() { // Features are unified for main when run with `cargo test`, - // even with -Zfeatures=dev_dep. + // even with the new resolver. let s = std::process::Command::new("target/debug/foo") .arg("3") .status().unwrap(); @@ -459,17 +456,14 @@ fn decouple_dev_deps() { ) .build(); + // Old behavior p.cargo("run 3").run(); - - p.cargo("run -Zfeatures=dev_dep 1") - .masquerade_as_nightly_cargo() - .run(); - p.cargo("test").run(); - p.cargo("test -Zfeatures=dev_dep") - .masquerade_as_nightly_cargo() - .run(); + // New behavior + switch_to_resolver_2(&p); + p.cargo("run 1").run(); + p.cargo("test").run(); } #[cargo_test] @@ -621,7 +615,7 @@ fn build_script_runtime_features() { #[test] fn test_main() { // Features are unified for main when run with `cargo test`, - // even with -Zfeatures=dev_dep. + // even with the new resolver. let s = std::process::Command::new("target/debug/foo") .status().unwrap(); assert!(s.success()); @@ -632,32 +626,16 @@ fn build_script_runtime_features() { // Old way, unifies all 3. p.cargo("run").env("CARGO_FEATURE_EXPECT", "7").run(); + p.cargo("test").env("CARGO_FEATURE_EXPECT", "7").run(); - // normal + build unify - p.cargo("run -Zfeatures=dev_dep") - .env("CARGO_FEATURE_EXPECT", "5") - .masquerade_as_nightly_cargo() - .run(); - - // Normal only. - p.cargo("run -Zfeatures=dev_dep,host_dep") - .env("CARGO_FEATURE_EXPECT", "1") - .masquerade_as_nightly_cargo() - .run(); + // New behavior. + switch_to_resolver_2(&p); - p.cargo("test").env("CARGO_FEATURE_EXPECT", "7").run(); + // normal + build unify + p.cargo("run").env("CARGO_FEATURE_EXPECT", "1").run(); // dev_deps are still unified with `cargo test` - p.cargo("test -Zfeatures=dev_dep") - .env("CARGO_FEATURE_EXPECT", "7") - .masquerade_as_nightly_cargo() - .run(); - - // normal + dev unify - p.cargo("test -Zfeatures=host_dep") - .env("CARGO_FEATURE_EXPECT", "3") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("test").env("CARGO_FEATURE_EXPECT", "3").run(); } #[cargo_test] @@ -719,19 +697,16 @@ fn cyclical_dev_dep() { // Old way unifies features. p.cargo("run true").run(); - - // Should decouple main. - p.cargo("run -Zfeatures=dev_dep false") - .masquerade_as_nightly_cargo() - .run(); - // dev feature should always be enabled in tests. p.cargo("test").run(); + // New behavior. + switch_to_resolver_2(&p); + // Should decouple main. + p.cargo("run false").run(); + // And this should be no different. - p.cargo("test -Zfeatures=dev_dep") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("test").run(); } #[cargo_test] @@ -800,20 +775,15 @@ fn all_feature_opts() { .build(); p.cargo("run").env("EXPECTED_FEATS", "15").run(); + p.cargo("test").env("EXPECTED_FEATS", "15").run(); + // New behavior. + switch_to_resolver_2(&p); // Only normal feature. - p.cargo("run -Zfeatures=all") - .masquerade_as_nightly_cargo() - .env("EXPECTED_FEATS", "1") - .run(); - - p.cargo("test").env("EXPECTED_FEATS", "15").run(); + p.cargo("run").env("EXPECTED_FEATS", "1").run(); // only normal+dev - p.cargo("test -Zfeatures=all") - .masquerade_as_nightly_cargo() - .env("EXPECTED_FEATS", "5") - .run(); + p.cargo("test").env("EXPECTED_FEATS", "5").run(); } #[cargo_test] @@ -867,9 +837,9 @@ Consider enabling them by passing, e.g., `--features=\"bdep/f1\"` ) .run(); - p.cargo("run --features bdep/f1 -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() - .run(); + // New behavior. + switch_to_resolver_2(&p); + p.cargo("run --features bdep/f1").run(); } #[cargo_test] @@ -920,6 +890,7 @@ fn disabled_shared_host_dep() { name = "foo" version = "1.0.0" edition = "2018" + resolver = "2" [dependencies] common = "1.0" @@ -938,10 +909,7 @@ fn disabled_shared_host_dep() { ) .build(); - p.cargo("run -Zfeatures=host_dep -v") - .masquerade_as_nightly_cargo() - .with_stdout("hello from somedep") - .run(); + p.cargo("run -v").with_stdout("hello from somedep").run(); } #[cargo_test] @@ -954,6 +922,7 @@ fn required_features_inactive_dep() { [package] name = "foo" version = "0.1.0" + resolver = "2" [target.'cfg(whatever)'.dependencies] bar = {path="bar"} @@ -971,13 +940,9 @@ fn required_features_inactive_dep() { .file("bar/src/lib.rs", "") .build(); - p.cargo("check -Zfeatures=itarget") - .masquerade_as_nightly_cargo() - .with_stderr("[FINISHED] [..]") - .run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); - p.cargo("check -Zfeatures=itarget --features=feat1") - .masquerade_as_nightly_cargo() + p.cargo("check --features=feat1") .with_stderr("[CHECKING] foo[..]\n[FINISHED] [..]") .run(); } @@ -1055,24 +1020,12 @@ fn decouple_proc_macro() { .env("TEST_EXPECTS_ENABLED", "1") .with_stdout("it is true") .run(); - - p.cargo("run -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() - .with_stdout("it is false") - .run(); - // Make sure the test is fallible. p.cargo("test --doc") .with_status(101) .with_stdout_contains("[..]common is wrong[..]") .run(); - p.cargo("test --doc").env("TEST_EXPECTS_ENABLED", "1").run(); - - p.cargo("test --doc -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() - .run(); - p.cargo("doc").run(); assert!(p .build_dir() @@ -1082,9 +1035,12 @@ fn decouple_proc_macro() { // https://github.com/rust-lang/cargo/issues/6783 (same for removed items) p.build_dir().join("doc").rm_rf(); - p.cargo("doc -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() - .run(); + // New behavior. + switch_to_resolver_2(&p); + p.cargo("run").with_stdout("it is false").run(); + + p.cargo("test --doc").run(); + p.cargo("doc").run(); assert!(!p .build_dir() .join("doc/common/constant.FEAT_ONLY_CONST.html") @@ -1100,6 +1056,7 @@ fn proc_macro_ws() { r#" [workspace] members = ["foo", "pm"] + resolver = "2" "#, ) .file( @@ -1131,8 +1088,7 @@ fn proc_macro_ws() { .file("pm/src/lib.rs", "") .build(); - p.cargo("check -p pm -Zfeatures=host_dep -v") - .masquerade_as_nightly_cargo() + p.cargo("check -p pm -v") .with_stderr_contains("[RUNNING] `rustc --crate-name foo [..]--cfg[..]feat1[..]") .run(); // This may be surprising that `foo` doesn't get built separately. It is @@ -1140,8 +1096,7 @@ fn proc_macro_ws() { // feature resolver must assume that normal deps get unified with it. This // is related to the bigger issue where the features selected in a // workspace depend on which packages are selected. - p.cargo("check --workspace -Zfeatures=host_dep -v") - .masquerade_as_nightly_cargo() + p.cargo("check --workspace -v") .with_stderr( "\ [FRESH] foo v0.1.0 [..] @@ -1151,8 +1106,7 @@ fn proc_macro_ws() { ) .run(); // Selecting just foo will build without unification. - p.cargo("check -p foo -Zfeatures=host_dep -v") - .masquerade_as_nightly_cargo() + p.cargo("check -p foo -v") // Make sure `foo` is built without feat1 .with_stderr_line_without(&["[RUNNING] `rustc --crate-name foo"], &["--cfg[..]feat1"]) .run(); @@ -1212,8 +1166,7 @@ fn has_dev_dep_for_test() { ", ) .run(); - p.cargo("check -v --profile=test -Zfeatures=dev_dep") - .masquerade_as_nightly_cargo() + p.cargo("check -v --profile=test") .with_stderr( "\ [CHECKING] dep v0.1.0 [..] @@ -1224,6 +1177,9 @@ fn has_dev_dep_for_test() { ", ) .run(); + + // New resolver should not be any different. + switch_to_resolver_2(&p); p.cargo("check -v --profile=test") .with_stderr( "\ @@ -1285,75 +1241,12 @@ fn build_dep_activated() { .build(); p.cargo("check").run(); - p.cargo("check -Zfeatures=all") - .masquerade_as_nightly_cargo() - .run(); p.cargo("check --target").arg(alternate()).run(); - p.cargo("check -Zfeatures=all --target") - .arg(alternate()) - .masquerade_as_nightly_cargo() - .run(); -} - -#[cargo_test] -fn resolver_gated() { - // Check that `resolver` field is feature gated. - let p = project() - .file( - "Cargo.toml", - r#" - [package] - name = "foo" - version = "0.1.0" - resolver = "2" - "#, - ) - .file("src/lib.rs", "") - .build(); - - p.cargo("build") - .masquerade_as_nightly_cargo() - .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[..]/foo/Cargo.toml` - -Caused by: - feature `resolver` is required - - consider adding `cargo-features = [\"resolver\"]` to the manifest -", - ) - .run(); - // Test with virtual ws. - let p = project() - .file( - "Cargo.toml", - r#" - [workspace] - members = ["a"] - resolver = "2" - "#, - ) - .file("a/Cargo.toml", &basic_manifest("a", "0.1.0")) - .file("a/src/lib.rs", "") - .build(); - - p.cargo("build") - .masquerade_as_nightly_cargo() - .with_status(101) - .with_stderr( - "\ -error: failed to parse manifest at `[..]/foo/Cargo.toml` - -Caused by: - feature `resolver` is required - - consider adding `cargo-features = [\"resolver\"]` to the manifest -", - ) - .run(); + // New behavior. + switch_to_resolver_2(&p); + p.cargo("check").run(); + p.cargo("check --target").arg(alternate()).run(); } #[cargo_test] @@ -1363,7 +1256,6 @@ fn resolver_bad_setting() { .file( "Cargo.toml", r#" - cargo-features = ["resolver"] [package] name = "foo" version = "0.1.0" @@ -1374,7 +1266,6 @@ fn resolver_bad_setting() { .build(); p.cargo("build") - .masquerade_as_nightly_cargo() .with_status(101) .with_stderr( "\ @@ -1412,7 +1303,6 @@ fn resolver_original() { let manifest = |resolver| { format!( r#" - cargo-features = ["resolver"] [package] name = "foo" version = "0.1.0" @@ -1432,14 +1322,13 @@ fn resolver_original() { .build(); p.cargo("check") - .masquerade_as_nightly_cargo() .with_status(101) .with_stderr_contains("[..]f1 should not activate[..]") .run(); p.change_file("Cargo.toml", &manifest("2")); - p.cargo("check").masquerade_as_nightly_cargo().run(); + p.cargo("check").run(); } #[cargo_test] @@ -1449,7 +1338,6 @@ fn resolver_not_both() { .file( "Cargo.toml", r#" - cargo-features = ["resolver"] [workspace] resolver = "2" [package] @@ -1462,7 +1350,6 @@ fn resolver_not_both() { .build(); p.cargo("build") - .masquerade_as_nightly_cargo() .with_status(101) .with_stderr( "\ @@ -1489,7 +1376,6 @@ fn resolver_ws_member() { .file( "a/Cargo.toml", r#" - cargo-features = ["resolver"] [package] name = "a" version = "0.1.0" @@ -1500,7 +1386,6 @@ fn resolver_ws_member() { .build(); p.cargo("check") - .masquerade_as_nightly_cargo() .with_stderr( "\ warning: resolver for the non root package will be ignored, specify resolver at the workspace root: @@ -1520,7 +1405,6 @@ fn resolver_ws_root_and_member() { .file( "Cargo.toml", r#" - cargo-features = ["resolver"] [workspace] members = ["a"] resolver = "2" @@ -1529,7 +1413,6 @@ fn resolver_ws_root_and_member() { .file( "a/Cargo.toml", r#" - cargo-features = ["resolver"] [package] name = "a" version = "0.1.0" @@ -1541,7 +1424,6 @@ fn resolver_ws_root_and_member() { // Ignores if they are the same. p.cargo("check") - .masquerade_as_nightly_cargo() .with_stderr( "\ [CHECKING] a v0.1.0 [..] @@ -1578,7 +1460,6 @@ fn resolver_enables_new_features() { .file( "Cargo.toml", r#" - cargo-features = ["resolver"] [workspace] members = ["a", "b"] resolver = "2" @@ -1648,7 +1529,6 @@ fn resolver_enables_new_features() { // Only normal. p.cargo("run --bin a") - .masquerade_as_nightly_cargo() .env("EXPECTED_FEATS", "1") .with_stderr( "\ @@ -1664,16 +1544,11 @@ fn resolver_enables_new_features() { .run(); // only normal+dev - p.cargo("test") - .cwd("a") - .masquerade_as_nightly_cargo() - .env("EXPECTED_FEATS", "5") - .run(); + p.cargo("test").cwd("a").env("EXPECTED_FEATS", "5").run(); - // -Zpackage-features is enabled. + // Can specify features of packages from a different directory. p.cargo("run -p b --features=ping") .cwd("a") - .masquerade_as_nightly_cargo() .with_stdout("pong") .run(); } @@ -1698,8 +1573,6 @@ fn install_resolve_behavior() { .file( "Cargo.toml", r#" - cargo-features = ["resolver"] - [package] name = "foo" version = "1.0.0" @@ -1716,9 +1589,7 @@ fn install_resolve_behavior() { .file("src/main.rs", "fn main() {}") .publish(); - cargo_process("install foo") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo").run(); } #[cargo_test] @@ -1728,7 +1599,6 @@ fn package_includes_resolve_behavior() { .file( "Cargo.toml", r#" - cargo-features = ["resolver"] [workspace] members = ["a"] resolver = "2" @@ -1749,15 +1619,10 @@ fn package_includes_resolve_behavior() { .file("a/src/lib.rs", "") .build(); - p.cargo("package") - .cwd("a") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("package").cwd("a").run(); let rewritten_toml = format!( r#"{} -cargo-features = ["resolver"] - [package] name = "a" version = "0.1.0" @@ -1790,6 +1655,7 @@ fn tree_all() { [package] name = "foo" version = "0.1.0" + resolver = "2" [target.'cfg(whatever)'.dependencies] log = {version="*", features=["serde"]} @@ -1797,8 +1663,7 @@ fn tree_all() { ) .file("src/lib.rs", "") .build(); - p.cargo("tree --target=all -Zfeatures=all") - .masquerade_as_nightly_cargo() + p.cargo("tree --target=all") .with_stdout( "\ foo v0.1.0 ([..]/foo) @@ -1824,6 +1689,7 @@ fn shared_dep_same_but_dependencies() { r#" [workspace] members = ["bin1", "bin2"] + resolver = "2" "#, ) .file( @@ -1889,8 +1755,7 @@ fn shared_dep_same_but_dependencies() { ) .build(); - p.cargo("build --bin bin1 --bin bin2 -Zfeatures=all") - .masquerade_as_nightly_cargo() + p.cargo("build --bin bin1 --bin bin2") // unordered because bin1 and bin2 build at the same time .with_stderr_unordered( "\ @@ -1908,8 +1773,7 @@ warning: feat: enabled .run(); // Make sure everything stays cached. - p.cargo("build -v --bin bin1 --bin bin2 -Zfeatures=all") - .masquerade_as_nightly_cargo() + p.cargo("build -v --bin bin1 --bin bin2") .with_stderr_unordered( "\ [FRESH] subdep [..] @@ -1939,6 +1803,8 @@ fn test_proc_macro() { [package] name = "runtime" version = "0.1.0" + resolver = "2" + [dependencies] the-macro = { path = "the-macro", features = ['a'] } [build-dependencies] @@ -2000,9 +1866,7 @@ fn test_proc_macro() { ) .file("shared/src/lib.rs", "pub struct Foo;") .build(); - p.cargo("test -Zfeatures=all --manifest-path the-macro/Cargo.toml") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("test --manifest-path the-macro/Cargo.toml").run(); } #[cargo_test] @@ -2024,6 +1888,7 @@ fn doc_optional() { [package] name = "foo" version = "0.1.0" + resolver = "2" [target.'cfg(whatever)'.dependencies] enabler = "1.0" @@ -2035,8 +1900,7 @@ fn doc_optional() { .file("src/lib.rs", "") .build(); - p.cargo("doc -Zfeatures=itarget") - .masquerade_as_nightly_cargo() + p.cargo("doc") .with_stderr_unordered( "\ [UPDATING] [..] @@ -2168,9 +2032,11 @@ fn minimal_download() { .run(); clear(); + // New behavior + switch_to_resolver_2(&p); + // all - p.cargo("check -Zfeatures=all") - .masquerade_as_nightly_cargo() + p.cargo("check") .with_stderr_unordered( "\ [DOWNLOADING] crates ... @@ -2190,8 +2056,7 @@ fn minimal_download() { clear(); // This disables decouple_dev_deps. - p.cargo("test --no-run -Zfeatures=all") - .masquerade_as_nightly_cargo() + p.cargo("test --no-run") .with_stderr_unordered( "\ [DOWNLOADING] crates ... @@ -2215,8 +2080,7 @@ fn minimal_download() { clear(); // This disables itarget, but leaves decouple_dev_deps enabled. - p.cargo("tree -e normal --target=all -Zfeatures=all") - .masquerade_as_nightly_cargo() + p.cargo("tree -e normal --target=all") .with_stderr_unordered( "\ [DOWNLOADING] crates ... @@ -2243,8 +2107,7 @@ foo v0.1.0 ([ROOT]/foo) clear(); // This disables itarget and decouple_dev_deps. - p.cargo("tree --target=all -Zfeatures=all") - .masquerade_as_nightly_cargo() + p.cargo("tree --target=all") .with_stderr_unordered( "\ [DOWNLOADING] crates ... diff --git a/tests/testsuite/package_features.rs b/tests/testsuite/package_features.rs index 3fdb4ac293d..0893e0c5bf3 100644 --- a/tests/testsuite/package_features.rs +++ b/tests/testsuite/package_features.rs @@ -1,5 +1,6 @@ -//! Tests for -Zpackage-features +//! Tests for feature selection on the command-line. +use super::features2::switch_to_resolver_2; use cargo_test_support::registry::Package; use cargo_test_support::{basic_manifest, project}; @@ -52,18 +53,6 @@ fn virtual_no_default_features() { .build(); p.cargo("check --no-default-features") - .with_status(101) - .with_stderr( - "\ -[ERROR] --no-default-features is not allowed in the root of a virtual workspace -[NOTE] while this was previously accepted, it didn't actually do anything -[HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package -", - ) - .run(); - - p.cargo("check --no-default-features -Zpackage-features") - .masquerade_as_nightly_cargo() .with_stderr_unordered( "\ [UPDATING] [..] @@ -74,13 +63,13 @@ fn virtual_no_default_features() { ) .run(); - p.cargo("check --features foo -Zpackage-features") + p.cargo("check --features foo") .masquerade_as_nightly_cargo() .with_status(101) .with_stderr("[ERROR] none of the selected packages contains these features: foo") .run(); - p.cargo("check --features a/dep1,b/f1,b/f2,f2 -Zpackage-features") + p.cargo("check --features a/dep1,b/f1,b/f2,f2") .masquerade_as_nightly_cargo() .with_status(101) .with_stderr("[ERROR] none of the selected packages contains these features: b/f2, f2") @@ -121,18 +110,6 @@ fn virtual_features() { .build(); p.cargo("check --features f1") - .with_status(101) - .with_stderr( - "\ -[ERROR] --features is not allowed in the root of a virtual workspace -[NOTE] while this was previously accepted, it didn't actually do anything -[HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package -", - ) - .run(); - - p.cargo("check --features f1 -Zpackage-features") - .masquerade_as_nightly_cargo() .with_stderr_unordered( "\ [CHECKING] a [..] @@ -199,18 +176,6 @@ fn virtual_with_specific() { .build(); p.cargo("check -p a -p b --features f1,f2,f3") - .with_status(101) - .with_stderr( - "\ -[ERROR] --features is not allowed in the root of a virtual workspace -[NOTE] while this was previously accepted, it didn't actually do anything -[HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package -", - ) - .run(); - - p.cargo("check -p a -p b --features f1,f2,f3 -Zpackage-features") - .masquerade_as_nightly_cargo() .with_stderr_unordered( "\ [CHECKING] a [..] @@ -279,31 +244,29 @@ fn other_member_from_current() { ) .build(); + // Old behavior. p.cargo("run -p bar --features f1") .with_stdout("f3f4") .run(); - p.cargo("run -p bar --features f1 -Zpackage-features") - .masquerade_as_nightly_cargo() - .with_stdout("f1") - .run(); - p.cargo("run -p bar --features f1,f2") .with_status(101) .with_stderr("[ERROR] Package `foo[..]` does not have the feature `f2`") .run(); - p.cargo("run -p bar --features f1,f2 -Zpackage-features") - .masquerade_as_nightly_cargo() - .with_stdout("f1f2") - .run(); - p.cargo("run -p bar --features bar/f1") .with_stdout("f1f3") .run(); - p.cargo("run -p bar --features bar/f1 -Zpackage-features") - .masquerade_as_nightly_cargo() + // New behavior. + switch_to_resolver_2(&p); + p.cargo("run -p bar --features f1").with_stdout("f1").run(); + + p.cargo("run -p bar --features f1,f2") + .with_stdout("f1f2") + .run(); + + p.cargo("run -p bar --features bar/f1") .with_stdout("f1") .run(); } @@ -368,53 +331,35 @@ fn virtual_member_slash() { ) .build(); - p.cargo("check --features a/f1") - .with_status(101) - .with_stderr( - "\ -[ERROR] --features is not allowed in the root of a virtual workspace -[NOTE] while this was previously accepted, it didn't actually do anything -[HELP] change the current directory to the package directory, or use the --manifest-path flag to the path of the package -", - ) - .run(); - - p.cargo("check -p a -Zpackage-features") - .masquerade_as_nightly_cargo() + p.cargo("check -p a") .with_status(101) .with_stderr_contains("[..]f1 is set[..]") .with_stderr_does_not_contain("[..]f2 is set[..]") .with_stderr_does_not_contain("[..]b is set[..]") .run(); - p.cargo("check -p a --features a/f1 -Zpackage-features") - .masquerade_as_nightly_cargo() + p.cargo("check -p a --features a/f1") .with_status(101) .with_stderr_contains("[..]f1 is set[..]") .with_stderr_does_not_contain("[..]f2 is set[..]") .with_stderr_does_not_contain("[..]b is set[..]") .run(); - p.cargo("check -p a --features a/f2 -Zpackage-features") - .masquerade_as_nightly_cargo() + p.cargo("check -p a --features a/f2") .with_status(101) .with_stderr_contains("[..]f1 is set[..]") .with_stderr_contains("[..]f2 is set[..]") .with_stderr_does_not_contain("[..]b is set[..]") .run(); - p.cargo("check -p a --features b/bfeat -Zpackage-features") - .masquerade_as_nightly_cargo() + p.cargo("check -p a --features b/bfeat") .with_status(101) .with_stderr_contains("[..]bfeat is set[..]") .run(); - p.cargo("check -p a --no-default-features -Zpackage-features") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("check -p a --no-default-features").run(); - p.cargo("check -p a --no-default-features --features b -Zpackage-features") - .masquerade_as_nightly_cargo() + p.cargo("check -p a --no-default-features --features b") .with_status(101) .with_stderr_contains("[..]b is set[..]") .run(); @@ -431,6 +376,7 @@ fn non_member() { [package] name = "foo" version = "0.1.0" + resolver = "2" [dependencies] dep = "1.0" @@ -442,28 +388,24 @@ fn non_member() { .file("src/lib.rs", "") .build(); - p.cargo("build -Zpackage-features -p dep --features f1") - .masquerade_as_nightly_cargo() + p.cargo("build -p dep --features f1") .with_status(101) .with_stderr( "[UPDATING][..]\n[ERROR] cannot specify features for packages outside of workspace", ) .run(); - p.cargo("build -Zpackage-features -p dep --all-features") - .masquerade_as_nightly_cargo() + p.cargo("build -p dep --all-features") .with_status(101) .with_stderr("[ERROR] cannot specify features for packages outside of workspace") .run(); - p.cargo("build -Zpackage-features -p dep --no-default-features") - .masquerade_as_nightly_cargo() + p.cargo("build -p dep --no-default-features") .with_status(101) .with_stderr("[ERROR] cannot specify features for packages outside of workspace") .run(); - p.cargo("build -Zpackage-features -p dep") - .masquerade_as_nightly_cargo() + p.cargo("build -p dep") .with_stderr( "\ [DOWNLOADING] [..] @@ -474,3 +416,45 @@ fn non_member() { ) .run(); } + +#[cargo_test] +fn resolver1_member_features() { + // --features member-name/feature-name with resolver="1" + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + members = ["member1", "member2"] + "#, + ) + .file( + "member1/Cargo.toml", + r#" + [package] + name = "member1" + version = "0.1.0" + + [features] + m1-feature = [] + "#, + ) + .file( + "member1/src/main.rs", + r#" + fn main() { + if cfg!(feature = "m1-feature") { + println!("m1-feature set"); + } + } + "#, + ) + .file("member2/Cargo.toml", &basic_manifest("member2", "0.1.0")) + .file("member2/src/lib.rs", "") + .build(); + + p.cargo("run -p member1 --features member1/m1-feature") + .cwd("member2") + .with_stdout("m1-feature set") + .run(); +} diff --git a/tests/testsuite/proc_macro.rs b/tests/testsuite/proc_macro.rs index 5c810bd3b83..55e4ca10a2c 100644 --- a/tests/testsuite/proc_macro.rs +++ b/tests/testsuite/proc_macro.rs @@ -479,6 +479,7 @@ fn proc_macro_built_once() { r#" [workspace] members = ['a', 'b'] + resolver = "2" "#, ) .file( @@ -522,8 +523,7 @@ fn proc_macro_built_once() { ) .file("the-macro/src/lib.rs", "") .build(); - p.cargo("build -Zfeatures=all --verbose") - .masquerade_as_nightly_cargo() + p.cargo("build --verbose") .with_stderr_unordered( "\ [COMPILING] the-macro [..] diff --git a/tests/testsuite/tree.rs b/tests/testsuite/tree.rs index 8a9cab4e0ae..a456b3dc330 100644 --- a/tests/testsuite/tree.rs +++ b/tests/testsuite/tree.rs @@ -1,5 +1,6 @@ //! Tests for the `cargo tree` command. +use super::features2::switch_to_resolver_2; use cargo_test_support::cross_compile::{self, alternate}; use cargo_test_support::registry::{Dependency, Package}; use cargo_test_support::{basic_manifest, git, project, rustc_host, Project}; @@ -1030,7 +1031,7 @@ foo v0.1.0 ([..]/foo) [bar,default,dep,foo] #[cargo_test] fn dev_dep_feature() { - // -Zfeatures=dev_dep with optional dep + // New feature resolver with optional dep Package::new("optdep", "1.0.0").publish(); Package::new("bar", "1.0.0") .add_dep(Dependency::new("optdep", "1.0").optional(true)) @@ -1053,6 +1054,7 @@ fn dev_dep_feature() { .file("src/lib.rs", "") .build(); + // Old behavior. p.cargo("tree") .with_stdout( "\ @@ -1075,8 +1077,10 @@ foo v0.1.0 ([..]/foo) ) .run(); - p.cargo("tree -Zfeatures=dev_dep") - .masquerade_as_nightly_cargo() + // New behavior. + switch_to_resolver_2(&p); + + p.cargo("tree") .with_stdout( "\ foo v0.1.0 ([..]/foo) @@ -1088,8 +1092,7 @@ foo v0.1.0 ([..]/foo) ) .run(); - p.cargo("tree -e normal -Zfeatures=dev_dep") - .masquerade_as_nightly_cargo() + p.cargo("tree -e normal") .with_stdout( "\ foo v0.1.0 ([..]/foo) @@ -1101,7 +1104,7 @@ foo v0.1.0 ([..]/foo) #[cargo_test] fn host_dep_feature() { - // -Zfeatures=host_dep with optional dep + // New feature resolver with optional build dep Package::new("optdep", "1.0.0").publish(); Package::new("bar", "1.0.0") .add_dep(Dependency::new("optdep", "1.0").optional(true)) @@ -1125,6 +1128,7 @@ fn host_dep_feature() { .file("build.rs", "fn main() {}") .build(); + // Old behavior p.cargo("tree") .with_stdout( "\ @@ -1137,56 +1141,56 @@ foo v0.1.0 ([..]/foo) ) .run(); - p.cargo("tree -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() + // -p + p.cargo("tree -p bar") .with_stdout( "\ -foo v0.1.0 ([..]/foo) -└── bar v1.0.0 -[build-dependencies] -└── bar v1.0.0 - └── optdep v1.0.0 +bar v1.0.0 +└── optdep v1.0.0 ", ) .run(); - // -p - p.cargo("tree -p bar") + // invert + p.cargo("tree -i optdep") .with_stdout( "\ -bar v1.0.0 -└── optdep v1.0.0 +optdep v1.0.0 +└── bar v1.0.0 + └── foo v0.1.0 ([..]/foo) + [build-dependencies] + └── foo v0.1.0 ([..]/foo) ", ) .run(); - p.cargo("tree -p bar -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() + // New behavior. + switch_to_resolver_2(&p); + + p.cargo("tree") .with_stdout( "\ -bar v1.0.0 - -bar v1.0.0 -└── optdep v1.0.0 +foo v0.1.0 ([..]/foo) +└── bar v1.0.0 +[build-dependencies] +└── bar v1.0.0 + └── optdep v1.0.0 ", ) .run(); - // invert - p.cargo("tree -i optdep") + p.cargo("tree -p bar") .with_stdout( "\ -optdep v1.0.0 -└── bar v1.0.0 - └── foo v0.1.0 ([..]/foo) - [build-dependencies] - └── foo v0.1.0 ([..]/foo) +bar v1.0.0 + +bar v1.0.0 +└── optdep v1.0.0 ", ) .run(); - p.cargo("tree -i optdep -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() + p.cargo("tree -i optdep") .with_stdout( "\ optdep v1.0.0 @@ -1198,8 +1202,7 @@ optdep v1.0.0 .run(); // Check that -d handles duplicates with features. - p.cargo("tree -d -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() + p.cargo("tree -d") .with_stdout( "\ bar v1.0.0 @@ -1215,7 +1218,7 @@ bar v1.0.0 #[cargo_test] fn proc_macro_features() { - // -Zfeatures=host_dep with a proc-macro + // New feature resolver with a proc-macro Package::new("optdep", "1.0.0").publish(); Package::new("somedep", "1.0.0") .add_dep(Dependency::new("optdep", "1.0").optional(true)) @@ -1240,6 +1243,7 @@ fn proc_macro_features() { .file("src/lib.rs", "") .build(); + // Old behavior p.cargo("tree") .with_stdout( "\ @@ -1252,56 +1256,56 @@ foo v0.1.0 ([..]/foo) ) .run(); - // Note the missing (*) - p.cargo("tree -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() + // -p + p.cargo("tree -p somedep") .with_stdout( "\ -foo v0.1.0 ([..]/foo) -├── pm v1.0.0 (proc-macro) -│ └── somedep v1.0.0 -│ └── optdep v1.0.0 -└── somedep v1.0.0 +somedep v1.0.0 +└── optdep v1.0.0 ", ) .run(); - // -p - p.cargo("tree -p somedep") + // invert + p.cargo("tree -i somedep") .with_stdout( "\ somedep v1.0.0 -└── optdep v1.0.0 +├── foo v0.1.0 ([..]/foo) +└── pm v1.0.0 (proc-macro) + └── foo v0.1.0 ([..]/foo) ", ) .run(); - p.cargo("tree -p somedep -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() + // New behavior. + switch_to_resolver_2(&p); + + // Note the missing (*) + p.cargo("tree") .with_stdout( "\ -somedep v1.0.0 - -somedep v1.0.0 -└── optdep v1.0.0 +foo v0.1.0 ([..]/foo) +├── pm v1.0.0 (proc-macro) +│ └── somedep v1.0.0 +│ └── optdep v1.0.0 +└── somedep v1.0.0 ", ) .run(); - // invert - p.cargo("tree -i somedep") + p.cargo("tree -p somedep") .with_stdout( "\ somedep v1.0.0 -├── foo v0.1.0 ([..]/foo) -└── pm v1.0.0 (proc-macro) - └── foo v0.1.0 ([..]/foo) + +somedep v1.0.0 +└── optdep v1.0.0 ", ) .run(); - p.cargo("tree -i somedep -Zfeatures=host_dep") - .masquerade_as_nightly_cargo() + p.cargo("tree -i somedep") .with_stdout( "\ somedep v1.0.0 @@ -1317,7 +1321,7 @@ somedep v1.0.0 #[cargo_test] fn itarget_opt_dep() { - // -Zfeatures=itarget with optional dep + // New feature resolver with optional target dep Package::new("optdep", "1.0.0").publish(); Package::new("common", "1.0.0") .add_dep(Dependency::new("optdep", "1.0").optional(true)) @@ -1342,6 +1346,7 @@ fn itarget_opt_dep() { .file("src/lib.rs", "") .build(); + // Old behavior p.cargo("tree") .with_stdout( "\ @@ -1352,14 +1357,16 @@ foo v1.0.0 ([..]/foo) ) .run(); - p.cargo("tree -Zfeatures=itarget") + // New behavior. + switch_to_resolver_2(&p); + + p.cargo("tree") .with_stdout( "\ foo v1.0.0 ([..]/foo) └── common v1.0.0 ", ) - .masquerade_as_nightly_cargo() .run(); }