diff --git a/Cargo.toml b/Cargo.toml index 3a7c372d65e..f0523242144 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo" -version = "0.45.0" +version = "0.45.1" edition = "2018" authors = ["Yehuda Katz ", "Carl Lerche ", diff --git a/src/cargo/core/compiler/context/compilation_files.rs b/src/cargo/core/compiler/context/compilation_files.rs index 56b3c3c615b..b6d32b808fc 100644 --- a/src/cargo/core/compiler/context/compilation_files.rs +++ b/src/cargo/core/compiler/context/compilation_files.rs @@ -542,43 +542,8 @@ fn compute_metadata<'a, 'cfg>( cx: &Context<'a, 'cfg>, metas: &mut HashMap, Option>, ) -> Option { - if unit.mode.is_doc_test() { - // Doc tests do not have metadata. - return None; - } - // No metadata for dylibs because of a couple issues: - // - macOS encodes the dylib name in the executable, - // - Windows rustc multiple files of which we can't easily link all of them. - // - // No metadata for bin because of an issue: - // - wasm32 rustc/emcc encodes the `.wasm` name in the `.js` (rust-lang/cargo#4535). - // - msvc: The path to the PDB is embedded in the executable, and we don't - // want the PDB path to include the hash in it. - // - // Two exceptions: - // 1) Upstream dependencies (we aren't exporting + need to resolve name conflict), - // 2) `__CARGO_DEFAULT_LIB_METADATA` env var. - // - // Note, however, that the compiler's build system at least wants - // path dependencies (eg libstd) to have hashes in filenames. To account for - // that we have an extra hack here which reads the - // `__CARGO_DEFAULT_LIB_METADATA` environment variable and creates a - // hash in the filename if that's present. - // - // This environment variable should not be relied on! It's - // just here for rustbuild. We need a more principled method - // doing this eventually. let bcx = &cx.bcx; - let __cargo_default_lib_metadata = env::var("__CARGO_DEFAULT_LIB_METADATA"); - let short_name = bcx.target_data.short_name(&unit.kind); - if !(unit.mode.is_any_test() || unit.mode.is_check()) - && (unit.target.is_dylib() - || unit.target.is_cdylib() - || (unit.target.is_executable() && short_name.starts_with("wasm32-")) - || (unit.target.is_executable() && short_name.contains("msvc"))) - && unit.pkg.package_id().source_id().is_path() - && __cargo_default_lib_metadata.is_err() - { + if !should_use_metadata(bcx, unit) { return None; } @@ -641,7 +606,7 @@ fn compute_metadata<'a, 'cfg>( // Seed the contents of `__CARGO_DEFAULT_LIB_METADATA` to the hasher if present. // This should be the release channel, to get a different hash for each channel. - if let Ok(ref channel) = __cargo_default_lib_metadata { + if let Ok(ref channel) = env::var("__CARGO_DEFAULT_LIB_METADATA") { channel.hash(&mut hasher); } @@ -688,3 +653,53 @@ fn hash_rustc_version(bcx: &BuildContext<'_, '_>, hasher: &mut SipHasher) { // the future when cranelift sees more use, and people want to switch // between different backends without recompiling. } + +/// Returns whether or not this unit should use a metadata hash. +fn should_use_metadata(bcx: &BuildContext<'_, '_>, unit: &Unit<'_>) -> bool { + if unit.mode.is_doc_test() { + // Doc tests do not have metadata. + return false; + } + if unit.mode.is_any_test() || unit.mode.is_check() { + // These always use metadata. + return true; + } + // No metadata in these cases: + // + // - dylibs: + // - macOS encodes the dylib name in the executable, so it can't be renamed. + // - TODO: Are there other good reasons? If not, maybe this should be macos specific? + // - Windows MSVC executables: The path to the PDB is embedded in the + // executable, and we don't want the PDB path to include the hash in it. + // - wasm32 executables: When using emscripten, the path to the .wasm file + // is embedded in the .js file, so we don't want the hash in there. + // TODO: Is this necessary for wasm32-unknown-unknown? + // - apple executables: The executable name is used in the dSYM directory + // (such as `target/debug/foo.dSYM/Contents/Resources/DWARF/foo-64db4e4bf99c12dd`). + // Unfortunately this causes problems with our current backtrace + // implementation which looks for a file matching the exe name exactly. + // See https://github.com/rust-lang/rust/issues/72550#issuecomment-638501691 + // for more details. + // + // This is only done for local packages, as we don't expect to export + // dependencies. + // + // The __CARGO_DEFAULT_LIB_METADATA env var is used to override this to + // force metadata in the hash. This is only used for building libstd. For + // example, if libstd is placed in a common location, we don't want a file + // named /usr/lib/libstd.so which could conflict with other rustc + // installs. TODO: Is this still a realistic concern? + // See https://github.com/rust-lang/cargo/issues/3005 + let short_name = bcx.target_data.short_name(&unit.kind); + if (unit.target.is_dylib() + || unit.target.is_cdylib() + || (unit.target.is_executable() && short_name.starts_with("wasm32-")) + || (unit.target.is_executable() && short_name.contains("msvc")) + || (unit.target.is_executable() && short_name.contains("-apple-"))) + && unit.pkg.package_id().source_id().is_path() + && env::var("__CARGO_DEFAULT_LIB_METADATA").is_err() + { + return false; + } + true +} diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index abe60a13fcd..94b5a6d6d4c 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -4162,7 +4162,7 @@ fn uplift_dsym_of_bin_on_mac() { assert!(p.target_debug_dir().join("foo.dSYM").is_dir()); assert!(p.target_debug_dir().join("b.dSYM").is_dir()); assert!(p.target_debug_dir().join("b.dSYM").is_symlink()); - assert!(p.target_debug_dir().join("examples/c.dSYM").is_symlink()); + assert!(p.target_debug_dir().join("examples/c.dSYM").is_dir()); assert!(!p.target_debug_dir().join("c.dSYM").exists()); assert!(!p.target_debug_dir().join("d.dSYM").exists()); } diff --git a/tests/testsuite/collisions.rs b/tests/testsuite/collisions.rs index e81ef90919f..5b94aae28ec 100644 --- a/tests/testsuite/collisions.rs +++ b/tests/testsuite/collisions.rs @@ -91,9 +91,9 @@ This may become a hard error in the future; see i32 { 1 }") - .build(); - - let target = cross_compile::alternate(); - foo.cargo("build --target").arg(&target).run(); -} - #[cargo_test] fn cross_tests() { if !cross_compile::can_run_on_host() { diff --git a/tests/testsuite/freshness.rs b/tests/testsuite/freshness.rs index 1098cd9d1cc..6254966b04c 100644 --- a/tests/testsuite/freshness.rs +++ b/tests/testsuite/freshness.rs @@ -501,8 +501,8 @@ fn changing_bin_features_caches_targets() { /* Targets should be cached from the first build */ let mut e = p.cargo("build"); - // MSVC does not include hash in binary filename, so it gets recompiled. - if cfg!(target_env = "msvc") { + // MSVC/apple does not include hash in binary filename, so it gets recompiled. + if cfg!(any(target_env = "msvc", target_vendor = "apple")) { e.with_stderr("[COMPILING] foo[..]\n[FINISHED] dev[..]"); } else { e.with_stderr("[FINISHED] dev[..]"); @@ -511,7 +511,7 @@ fn changing_bin_features_caches_targets() { p.rename_run("foo", "off2").with_stdout("feature off").run(); let mut e = p.cargo("build --features foo"); - if cfg!(target_env = "msvc") { + if cfg!(any(target_env = "msvc", target_vendor = "apple")) { e.with_stderr("[COMPILING] foo[..]\n[FINISHED] dev[..]"); } else { e.with_stderr("[FINISHED] dev[..]"); diff --git a/tests/testsuite/plugins.rs b/tests/testsuite/plugins.rs index 7bd5b7772ab..1e6c499a5ad 100644 --- a/tests/testsuite/plugins.rs +++ b/tests/testsuite/plugins.rs @@ -3,217 +3,6 @@ use cargo_test_support::{basic_manifest, project}; use cargo_test_support::{is_nightly, rustc_host}; -#[cargo_test] -fn plugin_to_the_max() { - if !is_nightly() { - // plugins are unstable - return; - } - - let foo = project() - .file( - "Cargo.toml", - r#" - [package] - name = "foo" - version = "0.0.1" - authors = [] - - [lib] - name = "foo_lib" - - [dependencies.bar] - path = "../bar" - "#, - ) - .file( - "src/main.rs", - r#" - #![feature(plugin)] - #![plugin(bar)] - extern crate foo_lib; - - fn main() { foo_lib::foo(); } - "#, - ) - .file( - "src/foo_lib.rs", - r#" - #![feature(plugin)] - #![plugin(bar)] - - pub fn foo() {} - "#, - ) - .build(); - let _bar = project() - .at("bar") - .file( - "Cargo.toml", - r#" - [package] - name = "bar" - version = "0.0.1" - authors = [] - - [lib] - name = "bar" - plugin = true - - [dependencies.baz] - path = "../baz" - "#, - ) - .file( - "src/lib.rs", - r#" - #![feature(plugin_registrar, rustc_private)] - - extern crate baz; - extern crate rustc_driver; - - use rustc_driver::plugin::Registry; - - #[plugin_registrar] - pub fn foo(_reg: &mut Registry) { - println!("{}", baz::baz()); - } - "#, - ) - .build(); - let _baz = project() - .at("baz") - .file( - "Cargo.toml", - r#" - [package] - name = "baz" - version = "0.0.1" - authors = [] - - [lib] - name = "baz" - crate_type = ["dylib"] - "#, - ) - .file("src/lib.rs", "pub fn baz() -> i32 { 1 }") - .build(); - - foo.cargo("build").run(); - foo.cargo("doc").run(); -} - -#[cargo_test] -fn plugin_with_dynamic_native_dependency() { - if !is_nightly() { - // plugins are unstable - return; - } - - let build = project() - .at("builder") - .file( - "Cargo.toml", - r#" - [package] - name = "builder" - version = "0.0.1" - authors = [] - - [lib] - name = "builder" - crate-type = ["dylib"] - "#, - ) - .file("src/lib.rs", "#[no_mangle] pub extern fn foo() {}") - .build(); - - let foo = project() - .file( - "Cargo.toml", - r#" - [package] - name = "foo" - version = "0.0.1" - authors = [] - - [dependencies.bar] - path = "bar" - "#, - ) - .file( - "src/main.rs", - r#" - #![feature(plugin)] - #![plugin(bar)] - - fn main() {} - "#, - ) - .file( - "bar/Cargo.toml", - r#" - [package] - name = "bar" - version = "0.0.1" - authors = [] - build = 'build.rs' - - [lib] - name = "bar" - plugin = true - "#, - ) - .file( - "bar/build.rs", - r#" - use std::env; - use std::fs; - use std::path::PathBuf; - - fn main() { - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - let root = PathBuf::from(env::var("BUILDER_ROOT").unwrap()); - let file = format!("{}builder{}", - env::consts::DLL_PREFIX, - env::consts::DLL_SUFFIX); - let src = root.join(&file); - let dst = out_dir.join(&file); - fs::copy(src, dst).unwrap(); - if cfg!(windows) { - fs::copy(root.join("builder.dll.lib"), - out_dir.join("builder.dll.lib")).unwrap(); - } - println!("cargo:rustc-flags=-L {}", out_dir.display()); - } - "#, - ) - .file( - "bar/src/lib.rs", - r#" - #![feature(plugin_registrar, rustc_private)] - - extern crate rustc_driver; - use rustc_driver::plugin::Registry; - - #[cfg_attr(not(target_env = "msvc"), link(name = "builder"))] - #[cfg_attr(target_env = "msvc", link(name = "builder.dll"))] - extern { fn foo(); } - - #[plugin_registrar] - pub fn bar(_reg: &mut Registry) { - unsafe { foo() } - } - "#, - ) - .build(); - - build.cargo("build").run(); - - let root = build.root().join("target").join("debug"); - foo.cargo("build -v").env("BUILDER_ROOT", root).run(); -} - #[cargo_test] fn plugin_integration() { let p = project()