diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 1ad0dec064006..c26a44f541484 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1197,20 +1197,29 @@ fn add_sanitizer_libraries( crate_type: CrateType, linker: &mut dyn Linker, ) { - // On macOS and Windows using MSVC the runtimes are distributed as dylibs - // which should be linked to both executables and dynamic libraries. - // Everywhere else the runtimes are currently distributed as static - // libraries which should be linked to executables only. - let needs_runtime = !sess.target.is_like_android - && match crate_type { - CrateType::Executable => true, - CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => { - sess.target.is_like_osx || sess.target.is_like_msvc - } - CrateType::Rlib | CrateType::Staticlib => false, - }; + if sess.target.is_like_android { + // Sanitizer runtime libraries are provided dynamically on Android + // targets. + return; + } - if !needs_runtime { + if sess.opts.cg.link_self_contained.is_sanitizers_disabled() { + // Linking against in-tree sanitizer runtimes is disabled via + // `-C link-self-contained=-sanitizers` + return; + } + + // On macOS the runtimes are distributed as dylibs which should be linked to + // both executables and dynamic shared objects. On most other platforms the + // runtimes are currently distributed as static libraries which should be + // linked to executables only. + if matches!(crate_type, CrateType::Rlib | CrateType::Staticlib) { + return; + } + + if matches!(crate_type, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) + && (sess.target.is_like_osx || sess.target.is_like_msvc) + { return; } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 0a330da87b0cd..4665becc3f8a2 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -278,17 +278,29 @@ impl LinkSelfContained { } /// Returns whether the self-contained linker component was enabled on the CLI, using the - /// `-C link-self-contained=+linker` syntax, or one of the `true` shorcuts. + /// `-C link-self-contained=+linker` syntax, or one of the `true` shortcuts. pub fn is_linker_enabled(&self) -> bool { self.enabled_components.contains(LinkSelfContainedComponents::LINKER) } /// Returns whether the self-contained linker component was disabled on the CLI, using the - /// `-C link-self-contained=-linker` syntax, or one of the `false` shorcuts. + /// `-C link-self-contained=-linker` syntax, or one of the `false` shortcuts. pub fn is_linker_disabled(&self) -> bool { self.disabled_components.contains(LinkSelfContainedComponents::LINKER) } + // Returns whether the self-contained sanitizer component was enabled on the CLI, using the + // `-C link-self-contained=+sanitizers` syntax, or one of the `true` shortcuts. + pub fn is_sanitizers_enabled(&self) -> bool { + self.enabled_components.contains(LinkSelfContainedComponents::SANITIZERS) + } + + /// Returns whether the self-contained sanitizer component was disabled on the CLI, using the + /// `-C link-self-contained=-sanitizers` syntax, or one of the `false` shortcuts. + pub fn is_sanitizers_disabled(&self) -> bool { + self.disabled_components.contains(LinkSelfContainedComponents::SANITIZERS) + } + /// Returns CLI inconsistencies to emit errors: individual components were both enabled and /// disabled. fn check_consistency(&self) -> Option {