diff --git a/CHANGELOG.md b/CHANGELOG.md index 490b555df84..4c31ec59641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ - Windows GNU targets now copy `.dll.a` import library files for DLL crate types to the output directory. [#8141](https://github.com/rust-lang/cargo/pull/8141) +- Dylibs for all dependencies are now unconditionally copied to the output + directory. Some obscure scenarios can cause an old dylib to be referenced + between builds, and this ensures that all the latest copies are used. + [#8139](https://github.com/rust-lang/cargo/pull/8139) ### Fixed - Fixed copying Windows `.pdb` files to the output directory when the filename diff --git a/src/cargo/core/compiler/context/compilation_files.rs b/src/cargo/core/compiler/context/compilation_files.rs index fac6564a1c9..9fc2f4117a4 100644 --- a/src/cargo/core/compiler/context/compilation_files.rs +++ b/src/cargo/core/compiler/context/compilation_files.rs @@ -133,7 +133,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> { .map(|unit| (unit, LazyCell::new())) .collect(); CompilationFiles { - ws: &cx.bcx.ws, + ws: cx.bcx.ws, host, target, export_dir: cx.bcx.build_config.export_dir.clone(), diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 6ed4f1deaa9..c5c15a4a8b0 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -353,7 +353,7 @@ compact_debug! { kinds.clone(), self.src_path.path().unwrap().to_path_buf(), self.edition, - ).inner.clone(), + ).inner, format!("lib_target({:?}, {:?}, {:?}, {:?})", self.name, kinds, self.src_path, self.edition), ) @@ -366,21 +366,21 @@ compact_debug! { &self.name, path.to_path_buf(), self.edition, - ).inner.clone(), + ).inner, format!("custom_build_target({:?}, {:?}, {:?})", self.name, path, self.edition), ) } TargetSourcePath::Metabuild => { ( - Target::metabuild_target(&self.name).inner.clone(), + Target::metabuild_target(&self.name).inner, format!("metabuild_target({:?})", self.name), ) } } } _ => ( - Target::new(self.src_path.clone(), self.edition).inner.clone(), + Target::new(self.src_path.clone(), self.edition).inner, format!("with_path({:?}, {:?})", self.src_path, self.edition), ), } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 17d2a5ee121..31aaf361051 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -419,7 +419,7 @@ pub fn create_bcx<'a, 'cfg>( &resolved_features, &pkg_set, &profiles, - &interner, + interner, )?; let std_roots = if let Some(crates) = &config.cli_unstable().build_std { @@ -442,7 +442,7 @@ pub fn create_bcx<'a, 'cfg>( std_features, build_config.requested_kind, &pkg_set, - &interner, + interner, &profiles, )? } else { @@ -491,7 +491,7 @@ pub fn create_bcx<'a, 'cfg>( build_config.mode, &target_data, &profiles, - &interner, + interner, )?; let bcx = BuildContext::new( diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 772c6f87f67..5dcdd2ff4ed 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -823,25 +823,12 @@ fn check_filename(file: &Path, shell: &mut Shell) -> CargoResult<()> { file.display() ) } - let mut check_windows = |name| -> CargoResult<()> { - if restricted_names::is_windows_reserved(name) { - shell.warn(format!( - "file {} is a reserved Windows filename, \ + if restricted_names::is_windows_reserved_path(file) { + shell.warn(format!( + "file {} is a reserved Windows filename, \ it will not work on Windows platforms", - file.display() - ))?; - } - Ok(()) - }; - for component in file.iter() { - if let Some(component) = component.to_str() { - check_windows(component)?; - } - } - if file.extension().is_some() { - if let Some(stem) = file.file_stem().and_then(|s| s.to_str()) { - check_windows(stem)?; - } + file.display() + ))?; } Ok(()) } diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index 69e778f155d..9de9c41477f 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -811,7 +811,7 @@ fn get_source_id( reg: Option<&String>, ) -> CargoResult { match (reg, index) { - (Some(r), _) => SourceId::alt_registry(config, &r), + (Some(r), _) => SourceId::alt_registry(config, r), (_, Some(i)) => SourceId::for_registry(&i.into_url()?), _ => { let map = SourceConfigMap::new(config)?; diff --git a/src/cargo/ops/resolve.rs b/src/cargo/ops/resolve.rs index dd32b9367d6..220946ea2c1 100644 --- a/src/cargo/ops/resolve.rs +++ b/src/cargo/ops/resolve.rs @@ -127,7 +127,7 @@ pub fn resolve_ws_with_opts<'cfg>( let pkg_set = get_resolved_packages(&resolved_with_overrides, registry)?; let member_ids = ws - .members_with_features(&specs, &opts.features)? + .members_with_features(specs, &opts.features)? .into_iter() .map(|(p, _fts)| p.package_id()) .collect::>(); @@ -136,7 +136,7 @@ pub fn resolve_ws_with_opts<'cfg>( &member_ids, has_dev_units, requested_target, - &target_data, + target_data, )?; let resolved_features = FeatureResolver::resolve( diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index 9a181b9077f..4c340026cbf 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -178,7 +178,7 @@ use crate::sources::PathSource; use crate::util::errors::CargoResultExt; use crate::util::hex; use crate::util::into_url::IntoUrl; -use crate::util::{CargoResult, Config, Filesystem}; +use crate::util::{restricted_names, CargoResult, Config, Filesystem}; const PACKAGE_SOURCE_LOCK: &str = ".cargo-ok"; pub const CRATES_IO_INDEX: &str = "https://github.com/rust-lang/crates.io-index"; @@ -495,11 +495,18 @@ impl<'cfg> RegistrySource<'cfg> { prefix ) } - - // Once that's verified, unpack the entry as usual. - entry - .unpack_in(parent) - .chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?; + // Unpacking failed + let mut result = entry.unpack_in(parent).map_err(anyhow::Error::from); + if cfg!(windows) && restricted_names::is_windows_reserved_path(&entry_path) { + result = result.chain_err(|| { + format!( + "`{}` appears to contain a reserved Windows path, \ + it cannot be extracted on Windows", + entry_path.display() + ) + }); + } + result.chain_err(|| format!("failed to unpack entry at `{}`", entry_path.display()))?; } // Write to the lock file to indicate that unpacking was successful. diff --git a/src/cargo/util/restricted_names.rs b/src/cargo/util/restricted_names.rs index ad9df7dc122..3e1cb036de8 100644 --- a/src/cargo/util/restricted_names.rs +++ b/src/cargo/util/restricted_names.rs @@ -2,6 +2,7 @@ use crate::util::CargoResult; use anyhow::bail; +use std::path::Path; /// Returns `true` if the name contains non-ASCII characters. pub fn is_non_ascii_name(name: &str) -> bool { @@ -81,3 +82,13 @@ pub fn validate_package_name(name: &str, what: &str, help: &str) -> CargoResult< } Ok(()) } + +// Check the entire path for names reserved in Windows. +pub fn is_windows_reserved_path(path: &Path) -> bool { + path.iter() + .filter_map(|component| component.to_str()) + .any(|component| { + let stem = component.split('.').next().unwrap(); + is_windows_reserved(stem) + }) +} diff --git a/src/doc/src/reference/external-tools.md b/src/doc/src/reference/external-tools.md index 410db2440b1..26f99fd0b3b 100644 --- a/src/doc/src/reference/external-tools.md +++ b/src/doc/src/reference/external-tools.md @@ -48,7 +48,11 @@ alter the way the JSON messages are computed and rendered. See the description of the `--message-format` option in the [build command documentation] for more details. +If you are using Rust, the [cargo_metadata] crate can be used to parse these +messages. + [build command documentation]: ../commands/cargo-build.md +[cargo_metadata]: https://crates.io/crates/cargo_metadata #### Compiler messages diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index ddfeea58d9f..c04b7786d46 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1744,3 +1744,55 @@ src/lib.rs ) .run(); } + +#[cargo_test] +#[cfg(windows)] +fn reserved_windows_name() { + Package::new("bar", "1.0.0") + .file("src/lib.rs", "pub mod aux;") + .file("src/aux.rs", "") + .publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [project] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [dependencies] + bar = "1.0.0" + "#, + ) + .file("src/main.rs", "extern crate bar;\nfn main() { }") + .build(); + p.cargo("package") + .with_status(101) + .with_stderr_contains( + "\ +error: failed to verify package tarball + +Caused by: + failed to download replaced source registry `[..]` + +Caused by: + failed to unpack package `[..] `[..]`)` + +Caused by: + failed to unpack entry at `[..]aux.rs` + +Caused by: + `[..]aux.rs` appears to contain a reserved Windows path, it cannot be extracted on Windows + +Caused by: + failed to unpack `[..]aux.rs` + +Caused by: + failed to unpack `[..]aux.rs` into `[..]aux.rs`", + ) + .run(); +}