Skip to content

Commit 08cac93

Browse files
committed
rustc_trans: implement lld compatibility
1 parent 598498f commit 08cac93

File tree

2 files changed

+56
-7
lines changed

2 files changed

+56
-7
lines changed

src/librustc_trans/back/link.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,18 @@ fn link_natively(sess: &Session, dylib: bool,
621621
let (pname, mut cmd) = get_linker(sess);
622622
cmd.env("PATH", command_path(sess));
623623

624+
let is_lld = pname.ends_with("lld");
625+
626+
if is_lld {
627+
if sess.target.target.options.is_like_msvc {
628+
cmd.args(&["-flavor", "link"]);
629+
} else if sess.target.target.options.is_like_osx {
630+
cmd.args(&["-flavor", "darwin"]);
631+
} else {
632+
cmd.args(&["-flavor", "gnu"]);
633+
}
634+
}
635+
624636
if sess.target.target.options.is_like_msvc {
625637
let mut linker = MsvcLinker {
626638
name: pname,
@@ -640,6 +652,7 @@ fn link_natively(sess: &Session, dylib: bool,
640652
name: pname,
641653
cmd: cmd,
642654
sess: &sess,
655+
is_lld: is_lld,
643656
};
644657
link_natively_helper(&mut linker,
645658
sess,

src/librustc_trans/back/linker.rs

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ pub struct GnuLinker<'a> {
6565
pub name: &'a str,
6666
pub cmd: Command,
6767
pub sess: &'a Session,
68+
pub is_lld: bool,
6869
}
6970

7071
impl<'a> GnuLinker<'a> {
@@ -86,16 +87,45 @@ impl<'a> fmt::Display for GnuLinker<'a> {
8687
}
8788

8889
impl<'a> Linker for GnuLinker<'a> {
89-
fn link_dylib(&mut self, lib: &str) { self.arg("-l").arg(lib); }
90-
fn link_staticlib(&mut self, lib: &str) { self.arg("-l").arg(lib); }
90+
fn link_dylib(&mut self, lib: &str) {
91+
if self.is_lld && self.sess.target.target.options.is_like_osx {
92+
let mut v = OsString::from("-l");
93+
v.push(lib);
94+
self.arg(&v);
95+
} else {
96+
self.arg("-l").arg(lib);
97+
}
98+
}
99+
fn link_staticlib(&mut self, lib: &str) {
100+
if self.is_lld && self.sess.target.target.options.is_like_osx {
101+
let mut v = OsString::from("-l");
102+
v.push(lib);
103+
self.arg(&v);
104+
} else {
105+
self.arg("-l").arg(lib);
106+
}
107+
}
91108
fn link_rlib(&mut self, lib: &Path) { self.arg(lib); }
92109
fn include_path(&mut self, path: &Path) { self.arg("-L").arg(path); }
93110
fn framework_path(&mut self, path: &Path) { self.arg("-F").arg(path); }
94111
fn output_filename(&mut self, path: &Path) { self.arg("-o").arg(path); }
95112
fn add_object(&mut self, path: &Path) { self.arg(path); }
96113
fn position_independent_executable(&mut self) { self.arg("-pie"); }
97114
fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
98-
self.cmd.arg(arg);
115+
if self.is_lld {
116+
match arg.as_ref().to_str() {
117+
Some(args_str) => {
118+
for arg_str in args_str.trim_left_matches("-Wl,").split(',') {
119+
self.cmd.arg(arg_str);
120+
}
121+
},
122+
None => {
123+
self.cmd.arg(arg.as_ref());
124+
},
125+
}
126+
} else {
127+
self.cmd.arg(arg);
128+
}
99129
self
100130
}
101131
fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> &mut Self {
@@ -109,7 +139,13 @@ impl<'a> Linker for GnuLinker<'a> {
109139
}
110140

111141
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
112-
self.arg("-l").arg(lib);
142+
if self.is_lld && self.sess.target.target.options.is_like_osx {
143+
let mut v = OsString::from("-l");
144+
v.push(lib);
145+
self.arg(&v);
146+
} else {
147+
self.arg("-l").arg(lib);
148+
}
113149
}
114150

115151
fn link_framework(&mut self, framework: &str) {
@@ -124,9 +160,9 @@ impl<'a> Linker for GnuLinker<'a> {
124160
v.push(&archive::find_library(lib, search_path, &self.sess));
125161
self.arg(&v);
126162
} else {
127-
self.arg("-Wl,--whole-archive")
128-
.arg("-l").arg(lib)
129-
.arg("-Wl,--no-whole-archive");
163+
self.arg("-Wl,--whole-archive");
164+
self.link_staticlib(lib);
165+
self.arg("-Wl,--no-whole-archive");
130166
}
131167
}
132168

0 commit comments

Comments
 (0)