Skip to content

Commit 50501c6

Browse files
committed
linker: Refactor APIs for linking dynamic libraries
Rename `link_(dylib,framework)`, remove `link_rust_dylib`.
1 parent 5d3d347 commit 50501c6

File tree

2 files changed

+33
-93
lines changed

2 files changed

+33
-93
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ fn link_sanitizer_runtime(
12651265
let path = find_sanitizer_runtime(sess, &filename);
12661266
let rpath = path.to_str().expect("non-utf8 component in path");
12671267
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
1268-
linker.link_dylib(&filename, false, true);
1268+
linker.link_dylib_by_name(&filename, false, true);
12691269
} else if sess.target.is_like_msvc && flavor == LinkerFlavor::Msvc(Lld::No) && name == "asan" {
12701270
// MSVC provides the `/INFERASANLIBS` argument to automatically find the
12711271
// compatible ASAN library.
@@ -2526,7 +2526,7 @@ fn add_native_libs_from_crate(
25262526
}
25272527
NativeLibKind::Dylib { as_needed } => {
25282528
if link_dynamic {
2529-
cmd.link_dylib(name, verbatim, as_needed.unwrap_or(true))
2529+
cmd.link_dylib_by_name(name, verbatim, as_needed.unwrap_or(true))
25302530
}
25312531
}
25322532
NativeLibKind::Unspecified => {
@@ -2538,13 +2538,13 @@ fn add_native_libs_from_crate(
25382538
}
25392539
} else {
25402540
if link_dynamic {
2541-
cmd.link_dylib(name, verbatim, true);
2541+
cmd.link_dylib_by_name(name, verbatim, true);
25422542
}
25432543
}
25442544
}
25452545
NativeLibKind::Framework { as_needed } => {
25462546
if link_dynamic {
2547-
cmd.link_framework(name, as_needed.unwrap_or(true))
2547+
cmd.link_framework_by_name(name, verbatim, as_needed.unwrap_or(true))
25482548
}
25492549
}
25502550
NativeLibKind::RawDylib => {
@@ -2859,13 +2859,20 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
28592859
// Just need to tell the linker about where the library lives and
28602860
// what its name is
28612861
let parent = cratepath.parent();
2862+
// When producing a dll, the MSVC linker may not actually emit a
2863+
// `foo.lib` file if the dll doesn't actually export any symbols, so we
2864+
// check to see if the file is there and just omit linking to it if it's
2865+
// not present.
2866+
if sess.target.is_like_msvc && !cratepath.with_extension("dll.lib").exists() {
2867+
return;
2868+
}
28622869
if let Some(dir) = parent {
28632870
cmd.include_path(&rehome_sysroot_lib_dir(sess, dir));
28642871
}
28652872
let stem = cratepath.file_stem().unwrap().to_str().unwrap();
28662873
// Convert library file-stem into a cc -l argument.
28672874
let prefix = if stem.starts_with("lib") && !sess.target.is_like_windows { 3 } else { 0 };
2868-
cmd.link_rust_dylib(&stem[prefix..], parent.unwrap_or_else(|| Path::new("")));
2875+
cmd.link_dylib_by_name(&stem[prefix..], false, true);
28692876
}
28702877

28712878
fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 21 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,10 @@ pub fn get_linker<'a>(
166166
pub trait Linker {
167167
fn cmd(&mut self) -> &mut Command;
168168
fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path);
169-
fn link_dylib(&mut self, lib: &str, verbatim: bool, as_needed: bool);
170-
fn link_rust_dylib(&mut self, lib: &str, path: &Path);
171-
fn link_framework(&mut self, framework: &str, as_needed: bool);
169+
fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool);
170+
fn link_framework_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) {
171+
bug!("framework linked with unsupported linker")
172+
}
172173
fn link_staticlib(&mut self, lib: &str, verbatim: bool);
173174
fn link_rlib(&mut self, lib: &Path);
174175
fn link_whole_rlib(&mut self, lib: &Path);
@@ -432,8 +433,8 @@ impl<'a> Linker for GccLinker<'a> {
432433
}
433434
}
434435

435-
fn link_dylib(&mut self, lib: &str, verbatim: bool, as_needed: bool) {
436-
if self.sess.target.os == "illumos" && lib == "c" {
436+
fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, as_needed: bool) {
437+
if self.sess.target.os == "illumos" && name == "c" {
437438
// libc will be added via late_link_args on illumos so that it will
438439
// appear last in the library search order.
439440
// FIXME: This should be replaced by a more complete and generic
@@ -454,7 +455,7 @@ impl<'a> Linker for GccLinker<'a> {
454455
}
455456
}
456457
self.hint_dynamic();
457-
self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },));
458+
self.cmd.arg(format!("-l{}{name}", if verbatim && self.is_gnu { ":" } else { "" },));
458459
if !as_needed {
459460
if self.sess.target.is_like_osx {
460461
// See above FIXME comment
@@ -493,20 +494,15 @@ impl<'a> Linker for GccLinker<'a> {
493494
self.linker_args(&["-z", "norelro"]);
494495
}
495496

496-
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
497-
self.hint_dynamic();
498-
self.cmd.arg(format!("-l{lib}"));
499-
}
500-
501-
fn link_framework(&mut self, framework: &str, as_needed: bool) {
497+
fn link_framework_by_name(&mut self, name: &str, _verbatim: bool, as_needed: bool) {
502498
self.hint_dynamic();
503499
if !as_needed {
504500
// FIXME(81490): ld64 as of macOS 11 supports the -needed_framework
505501
// flag but we have no way to detect that here.
506-
// self.cmd.arg("-needed_framework").arg(framework);
502+
// self.cmd.arg("-needed_framework").arg(name);
507503
self.sess.dcx().emit_warn(errors::Ld64UnimplementedModifier);
508504
}
509-
self.cmd.arg("-framework").arg(framework);
505+
self.cmd.arg("-framework").arg(name);
510506
}
511507

512508
// Here we explicitly ask that the entire archive is included into the
@@ -845,19 +841,8 @@ impl<'a> Linker for MsvcLinker<'a> {
845841
self.cmd.arg("/OPT:NOREF,NOICF");
846842
}
847843

848-
fn link_dylib(&mut self, lib: &str, verbatim: bool, _as_needed: bool) {
849-
self.cmd.arg(format!("{}{}", lib, if verbatim { "" } else { ".lib" }));
850-
}
851-
852-
fn link_rust_dylib(&mut self, lib: &str, path: &Path) {
853-
// When producing a dll, the MSVC linker may not actually emit a
854-
// `foo.lib` file if the dll doesn't actually export any symbols, so we
855-
// check to see if the file is there and just omit linking to it if it's
856-
// not present.
857-
let name = format!("{lib}.dll.lib");
858-
if path.join(&name).exists() {
859-
self.cmd.arg(name);
860-
}
844+
fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) {
845+
self.cmd.arg(format!("{}{}", name, if verbatim { "" } else { ".lib" }));
861846
}
862847

863848
fn link_staticlib(&mut self, lib: &str, verbatim: bool) {
@@ -899,9 +884,6 @@ impl<'a> Linker for MsvcLinker<'a> {
899884
fn framework_path(&mut self, _path: &Path) {
900885
bug!("frameworks are not supported on windows")
901886
}
902-
fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
903-
bug!("frameworks are not supported on windows")
904-
}
905887

906888
fn link_whole_staticlib(&mut self, lib: &str, verbatim: bool, _search_path: &[PathBuf]) {
907889
self.cmd.arg(format!("/WHOLEARCHIVE:{}{}", lib, if verbatim { "" } else { ".lib" }));
@@ -1073,9 +1055,9 @@ impl<'a> Linker for EmLinker<'a> {
10731055
self.cmd.arg(path);
10741056
}
10751057

1076-
fn link_dylib(&mut self, lib: &str, verbatim: bool, _as_needed: bool) {
1058+
fn link_dylib_by_name(&mut self, name: &str, verbatim: bool, _as_needed: bool) {
10771059
// Emscripten always links statically
1078-
self.link_staticlib(lib, verbatim);
1060+
self.link_staticlib(name, verbatim);
10791061
}
10801062

10811063
fn link_whole_staticlib(&mut self, lib: &str, verbatim: bool, _search_path: &[PathBuf]) {
@@ -1088,10 +1070,6 @@ impl<'a> Linker for EmLinker<'a> {
10881070
self.link_rlib(lib);
10891071
}
10901072

1091-
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
1092-
self.link_dylib(lib, false, true);
1093-
}
1094-
10951073
fn link_rlib(&mut self, lib: &Path) {
10961074
self.add_object(lib);
10971075
}
@@ -1112,10 +1090,6 @@ impl<'a> Linker for EmLinker<'a> {
11121090
bug!("frameworks are not supported on Emscripten")
11131091
}
11141092

1115-
fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
1116-
bug!("frameworks are not supported on Emscripten")
1117-
}
1118-
11191093
fn gc_sections(&mut self, _keep_metadata: bool) {
11201094
// noop
11211095
}
@@ -1249,8 +1223,8 @@ impl<'a> Linker for WasmLd<'a> {
12491223
}
12501224
}
12511225

1252-
fn link_dylib(&mut self, lib: &str, _verbatim: bool, _as_needed: bool) {
1253-
self.cmd.arg("-l").arg(lib);
1226+
fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) {
1227+
self.cmd.arg("-l").arg(name);
12541228
}
12551229

12561230
fn link_staticlib(&mut self, lib: &str, _verbatim: bool) {
@@ -1283,14 +1257,6 @@ impl<'a> Linker for WasmLd<'a> {
12831257

12841258
fn no_relro(&mut self) {}
12851259

1286-
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
1287-
self.cmd.arg("-l").arg(lib);
1288-
}
1289-
1290-
fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
1291-
panic!("frameworks not supported")
1292-
}
1293-
12941260
fn link_whole_staticlib(&mut self, lib: &str, _verbatim: bool, _search_path: &[PathBuf]) {
12951261
self.cmd.arg("--whole-archive").arg("-l").arg(lib).arg("--no-whole-archive");
12961262
}
@@ -1398,7 +1364,7 @@ pub struct L4Bender<'a> {
13981364
}
13991365

14001366
impl<'a> Linker for L4Bender<'a> {
1401-
fn link_dylib(&mut self, _lib: &str, _verbatim: bool, _as_needed: bool) {
1367+
fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) {
14021368
bug!("dylibs are not supported on L4Re");
14031369
}
14041370
fn link_staticlib(&mut self, lib: &str, _verbatim: bool) {
@@ -1442,14 +1408,6 @@ impl<'a> Linker for L4Bender<'a> {
14421408

14431409
fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {}
14441410

1445-
fn link_rust_dylib(&mut self, _: &str, _: &Path) {
1446-
panic!("Rust dylibs not supported");
1447-
}
1448-
1449-
fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
1450-
bug!("frameworks not supported on L4Re");
1451-
}
1452-
14531411
fn link_whole_staticlib(&mut self, lib: &str, _verbatim: bool, _search_path: &[PathBuf]) {
14541412
self.hint_static();
14551413
self.cmd.arg("--whole-archive").arg(format!("-l{lib}"));
@@ -1571,9 +1529,9 @@ impl<'a> AixLinker<'a> {
15711529
}
15721530

15731531
impl<'a> Linker for AixLinker<'a> {
1574-
fn link_dylib(&mut self, lib: &str, _verbatim: bool, _as_needed: bool) {
1532+
fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) {
15751533
self.hint_dynamic();
1576-
self.cmd.arg(format!("-l{lib}"));
1534+
self.cmd.arg(format!("-l{name}"));
15771535
}
15781536

15791537
fn link_staticlib(&mut self, lib: &str, _verbatim: bool) {
@@ -1626,15 +1584,6 @@ impl<'a> Linker for AixLinker<'a> {
16261584
}
16271585
}
16281586

1629-
fn link_rust_dylib(&mut self, lib: &str, _: &Path) {
1630-
self.hint_dynamic();
1631-
self.cmd.arg(format!("-l{lib}"));
1632-
}
1633-
1634-
fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
1635-
bug!("frameworks not supported on AIX");
1636-
}
1637-
16381587
fn link_whole_staticlib(&mut self, lib: &str, verbatim: bool, search_path: &[PathBuf]) {
16391588
self.hint_static();
16401589
let lib = find_native_static_library(lib, verbatim, search_path, self.sess);
@@ -1844,11 +1793,7 @@ impl<'a> Linker for PtxLinker<'a> {
18441793
self.cmd.arg("-o").arg(path);
18451794
}
18461795

1847-
fn link_dylib(&mut self, _lib: &str, _verbatim: bool, _as_needed: bool) {
1848-
panic!("external dylibs not supported")
1849-
}
1850-
1851-
fn link_rust_dylib(&mut self, _lib: &str, _path: &Path) {
1796+
fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) {
18521797
panic!("external dylibs not supported")
18531798
}
18541799

@@ -1864,10 +1809,6 @@ impl<'a> Linker for PtxLinker<'a> {
18641809
panic!("frameworks not supported")
18651810
}
18661811

1867-
fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
1868-
panic!("frameworks not supported")
1869-
}
1870-
18711812
fn full_relro(&mut self) {}
18721813

18731814
fn partial_relro(&mut self) {}
@@ -1942,11 +1883,7 @@ impl<'a> Linker for BpfLinker<'a> {
19421883
self.cmd.arg("-o").arg(path);
19431884
}
19441885

1945-
fn link_dylib(&mut self, _lib: &str, _verbatim: bool, _as_needed: bool) {
1946-
panic!("external dylibs not supported")
1947-
}
1948-
1949-
fn link_rust_dylib(&mut self, _lib: &str, _path: &Path) {
1886+
fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) {
19501887
panic!("external dylibs not supported")
19511888
}
19521889

@@ -1962,10 +1899,6 @@ impl<'a> Linker for BpfLinker<'a> {
19621899
panic!("frameworks not supported")
19631900
}
19641901

1965-
fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
1966-
panic!("frameworks not supported")
1967-
}
1968-
19691902
fn full_relro(&mut self) {}
19701903

19711904
fn partial_relro(&mut self) {}

0 commit comments

Comments
 (0)