diff options
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/back/linker.rs')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/linker.rs | 124 |
1 files changed, 89 insertions, 35 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 8ba124a1fa8..401d379b0d1 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -103,18 +103,19 @@ impl LinkerInfo { pub trait Linker { fn cmd(&mut self) -> &mut Command; fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path); - fn link_dylib(&mut self, lib: Symbol); + fn link_dylib(&mut self, lib: Symbol, verbatim: bool, as_needed: bool); fn link_rust_dylib(&mut self, lib: Symbol, path: &Path); - fn link_framework(&mut self, framework: Symbol); - fn link_staticlib(&mut self, lib: Symbol); + fn link_framework(&mut self, framework: Symbol, as_needed: bool); + fn link_staticlib(&mut self, lib: Symbol, verbatim: bool); fn link_rlib(&mut self, lib: &Path); fn link_whole_rlib(&mut self, lib: &Path); - fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]); + fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, search_path: &[PathBuf]); fn include_path(&mut self, path: &Path); fn framework_path(&mut self, path: &Path); fn output_filename(&mut self, path: &Path); fn add_object(&mut self, path: &Path); fn gc_sections(&mut self, keep_metadata: bool); + fn no_gc_sections(&mut self); fn full_relro(&mut self); fn partial_relro(&mut self); fn no_relro(&mut self); @@ -338,13 +339,32 @@ impl<'a> Linker for GccLinker<'a> { } } - fn link_dylib(&mut self, lib: Symbol) { + fn link_dylib(&mut self, lib: Symbol, verbatim: bool, as_needed: bool) { + if !as_needed { + if self.sess.target.is_like_osx { + // FIXME(81490): ld64 doesn't support these flags but macOS 11 + // has -needed-l{} / -needed_library {} + // but we have no way to detect that here. + self.sess.warn("`as-needed` modifier not implemented yet for ld64"); + } else if self.sess.target.linker_is_gnu { + self.linker_arg("--no-as-needed"); + } else { + self.sess.warn("`as-needed` modifier not supported for current linker"); + } + } self.hint_dynamic(); - self.cmd.arg(format!("-l{}", lib)); + self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib)); + if !as_needed { + if self.sess.target.is_like_osx { + // See above FIXME comment + } else if self.sess.target.linker_is_gnu { + self.linker_arg("--as-needed"); + } + } } - fn link_staticlib(&mut self, lib: Symbol) { + fn link_staticlib(&mut self, lib: Symbol, verbatim: bool) { self.hint_static(); - self.cmd.arg(format!("-l{}", lib)); + self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib)); } fn link_rlib(&mut self, lib: &Path) { self.hint_static(); @@ -378,8 +398,14 @@ impl<'a> Linker for GccLinker<'a> { self.cmd.arg(format!("-l{}", lib)); } - fn link_framework(&mut self, framework: Symbol) { + fn link_framework(&mut self, framework: Symbol, as_needed: bool) { self.hint_dynamic(); + if !as_needed { + // FIXME(81490): ld64 as of macOS 11 supports the -needed_framework + // flag but we have no way to detect that here. + // self.cmd.arg("-needed_framework").sym_arg(framework); + self.sess.warn("`as-needed` modifier not implemented yet for ld64"); + } self.cmd.arg("-framework").sym_arg(framework); } @@ -389,17 +415,21 @@ impl<'a> Linker for GccLinker<'a> { // don't otherwise explicitly reference them. This can occur for // libraries which are just providing bindings, libraries with generic // functions, etc. - fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]) { + fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, search_path: &[PathBuf]) { self.hint_static(); let target = &self.sess.target; if !target.is_like_osx { - self.linker_arg("--whole-archive").cmd.arg(format!("-l{}", lib)); + self.linker_arg("--whole-archive").cmd.arg(format!( + "-l{}{}", + if verbatim { ":" } else { "" }, + lib + )); self.linker_arg("--no-whole-archive"); } else { // -force_load is the macOS equivalent of --whole-archive, but it // involves passing the full path to the library to link. self.linker_arg("-force_load"); - let lib = archive::find_library(lib, search_path, &self.sess); + let lib = archive::find_library(lib, verbatim, search_path, &self.sess); self.linker_arg(&lib); } } @@ -443,6 +473,16 @@ impl<'a> Linker for GccLinker<'a> { } } + fn no_gc_sections(&mut self) { + if self.sess.target.is_like_osx { + self.linker_arg("-no_dead_strip"); + } else if self.sess.target.is_like_solaris { + self.linker_arg("-zrecord"); + } else { + self.linker_arg("--no-gc-sections"); + } + } + fn optimize(&mut self) { if !self.sess.target.linker_is_gnu { return; @@ -710,8 +750,12 @@ impl<'a> Linker for MsvcLinker<'a> { } } - fn link_dylib(&mut self, lib: Symbol) { - self.cmd.arg(&format!("{}.lib", lib)); + fn no_gc_sections(&mut self) { + self.cmd.arg("/OPT:NOREF,NOICF"); + } + + fn link_dylib(&mut self, lib: Symbol, verbatim: bool, _as_needed: bool) { + self.cmd.arg(format!("{}{}", lib, if verbatim { "" } else { ".lib" })); } fn link_rust_dylib(&mut self, lib: Symbol, path: &Path) { @@ -725,8 +769,8 @@ impl<'a> Linker for MsvcLinker<'a> { } } - fn link_staticlib(&mut self, lib: Symbol) { - self.cmd.arg(&format!("{}.lib", lib)); + fn link_staticlib(&mut self, lib: Symbol, verbatim: bool) { + self.cmd.arg(format!("{}{}", lib, if verbatim { "" } else { ".lib" })); } fn full_relro(&mut self) { @@ -764,13 +808,13 @@ impl<'a> Linker for MsvcLinker<'a> { fn framework_path(&mut self, _path: &Path) { bug!("frameworks are not supported on windows") } - fn link_framework(&mut self, _framework: Symbol) { + fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) { bug!("frameworks are not supported on windows") } - fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) { - self.link_staticlib(lib); - self.cmd.arg(format!("/WHOLEARCHIVE:{}.lib", lib)); + fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, _search_path: &[PathBuf]) { + self.link_staticlib(lib, verbatim); + self.cmd.arg(format!("/WHOLEARCHIVE:{}{}", lib, if verbatim { "" } else { ".lib" })); } fn link_whole_rlib(&mut self, path: &Path) { self.link_rlib(path); @@ -919,7 +963,7 @@ impl<'a> Linker for EmLinker<'a> { self.cmd.arg("-L").arg(path); } - fn link_staticlib(&mut self, lib: Symbol) { + fn link_staticlib(&mut self, lib: Symbol, _verbatim: bool) { self.cmd.arg("-l").sym_arg(lib); } @@ -931,14 +975,14 @@ impl<'a> Linker for EmLinker<'a> { self.cmd.arg(path); } - fn link_dylib(&mut self, lib: Symbol) { + fn link_dylib(&mut self, lib: Symbol, verbatim: bool, _as_needed: bool) { // Emscripten always links statically - self.link_staticlib(lib); + self.link_staticlib(lib, verbatim); } - fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) { + fn link_whole_staticlib(&mut self, lib: Symbol, verbatim: bool, _search_path: &[PathBuf]) { // not supported? - self.link_staticlib(lib); + self.link_staticlib(lib, verbatim); } fn link_whole_rlib(&mut self, lib: &Path) { @@ -947,7 +991,7 @@ impl<'a> Linker for EmLinker<'a> { } fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) { - self.link_dylib(lib); + self.link_dylib(lib, false, true); } fn link_rlib(&mut self, lib: &Path) { @@ -970,7 +1014,7 @@ impl<'a> Linker for EmLinker<'a> { bug!("frameworks are not supported on Emscripten") } - fn link_framework(&mut self, _framework: Symbol) { + fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) { bug!("frameworks are not supported on Emscripten") } @@ -978,6 +1022,10 @@ impl<'a> Linker for EmLinker<'a> { // noop } + fn no_gc_sections(&mut self) { + // noop + } + fn optimize(&mut self) { // Emscripten performs own optimizations self.cmd.arg(match self.sess.opts.optimize { @@ -1121,11 +1169,11 @@ impl<'a> Linker for WasmLd<'a> { } } - fn link_dylib(&mut self, lib: Symbol) { + fn link_dylib(&mut self, lib: Symbol, _verbatim: bool, _as_needed: bool) { self.cmd.arg("-l").sym_arg(lib); } - fn link_staticlib(&mut self, lib: Symbol) { + fn link_staticlib(&mut self, lib: Symbol, _verbatim: bool) { self.cmd.arg("-l").sym_arg(lib); } @@ -1159,11 +1207,11 @@ impl<'a> Linker for WasmLd<'a> { self.cmd.arg("-l").sym_arg(lib); } - fn link_framework(&mut self, _framework: Symbol) { + fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) { panic!("frameworks not supported") } - fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) { + fn link_whole_staticlib(&mut self, lib: Symbol, _verbatim: bool, _search_path: &[PathBuf]) { self.cmd.arg("-l").sym_arg(lib); } @@ -1175,6 +1223,10 @@ impl<'a> Linker for WasmLd<'a> { self.cmd.arg("--gc-sections"); } + fn no_gc_sections(&mut self) { + self.cmd.arg("--no-gc-sections"); + } + fn optimize(&mut self) { self.cmd.arg(match self.sess.opts.optimize { OptLevel::No => "-O0", @@ -1329,7 +1381,7 @@ impl<'a> Linker for PtxLinker<'a> { }); } - fn link_dylib(&mut self, _lib: Symbol) { + fn link_dylib(&mut self, _lib: Symbol, _verbatim: bool, _as_needed: bool) { panic!("external dylibs not supported") } @@ -1337,11 +1389,11 @@ impl<'a> Linker for PtxLinker<'a> { panic!("external dylibs not supported") } - fn link_staticlib(&mut self, _lib: Symbol) { + fn link_staticlib(&mut self, _lib: Symbol, _verbatim: bool) { panic!("staticlibs not supported") } - fn link_whole_staticlib(&mut self, _lib: Symbol, _search_path: &[PathBuf]) { + fn link_whole_staticlib(&mut self, _lib: Symbol, _verbatim: bool, _search_path: &[PathBuf]) { panic!("staticlibs not supported") } @@ -1349,7 +1401,7 @@ impl<'a> Linker for PtxLinker<'a> { panic!("frameworks not supported") } - fn link_framework(&mut self, _framework: Symbol) { + fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) { panic!("frameworks not supported") } @@ -1361,6 +1413,8 @@ impl<'a> Linker for PtxLinker<'a> { fn gc_sections(&mut self, _keep_metadata: bool) {} + fn no_gc_sections(&mut self) {} + fn pgo_gen(&mut self) {} fn no_crt_objects(&mut self) {} |
