Skip to content

Commit c30d8f2

Browse files
committed
Purge manual use of -Wl and -Xlinker
...outside of target specifications - that'll come next. Updates rust-lang#11937.
1 parent cc6b88c commit c30d8f2

File tree

5 files changed

+76
-110
lines changed

5 files changed

+76
-110
lines changed

src/bootstrap/bin/rustc.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -206,31 +206,35 @@ fn main() {
206206
// Cargo will be very different than the runtime directory structure.
207207
//
208208
// All that's a really long winded way of saying that if we use
209-
// `-Crpath` then the executables generated have the wrong rpath of
209+
// `-C rpath` then the executables generated have the wrong rpath of
210210
// something like `$ORIGIN/deps` when in fact the way we distribute
211211
// rustc requires the rpath to be `$ORIGIN/../lib`.
212212
//
213213
// So, all in all, to set up the correct rpath we pass the linker
214-
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
214+
// argument manually via `-C link-args=-rpath,...`. Plus isn't it
215215
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
216216
// to change a flag in a binary?
217217
if env::var("RUSTC_RPATH") == Ok("true".to_string()) {
218-
let rpath = if target.contains("apple") {
219-
218+
let rpath_flags = if target.contains("apple") {
220219
// Note that we need to take one extra step on macOS to also pass
221-
// `-Wl,-instal_name,@rpath/...` to get things to work right. To
220+
// `-install_name,@rpath/...` to get things to work right. To
222221
// do that we pass a weird flag to the compiler to get it to do
223222
// so. Note that this is definitely a hack, and we should likely
224223
// flesh out rpath support more fully in the future.
225224
cmd.arg("-Z").arg("osx-rpath-install-name");
226-
Some("-Wl,-rpath,@loader_path/../lib")
225+
Some(&["-rpath", "@loader_path/../lib"])
227226
} else if !target.contains("windows") {
228-
Some("-Wl,-rpath,$ORIGIN/../lib")
227+
Some(&["-rpath", "$ORIGIN/../lib"])
229228
} else {
230229
None
231230
};
232-
if let Some(rpath) = rpath {
233-
cmd.arg("-C").arg(format!("link-args={}", rpath));
231+
if let Some(rpath_flags) = rpath_flags {
232+
for rpath_flag in rpath_flags {
233+
if stage == "0" {
234+
cmd.arg("-C").arg("link-arg=-Xlinker");
235+
}
236+
cmd.arg("-C").arg(format!("link-arg={}", rpath_flag));
237+
}
234238
}
235239
}
236240

src/librustc_trans/back/link.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1108,9 +1108,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
11081108
}
11091109
}
11101110

1111-
// We must link the sanitizer runtime using -Wl,--whole-archive but since
1112-
// it's packed in a .rlib, it contains stuff that are not objects that will
1113-
// make the linker error. So we must remove those bits from the .rlib before
1111+
// We must link the sanitizer runtime using --whole-archive but since it's
1112+
// packed in a .rlib, it contains stuff that are not objects that will make
1113+
// the linker error. So we must remove those bits from the .rlib before
11141114
// linking it.
11151115
fn link_sanitizer_runtime(cmd: &mut Linker,
11161116
sess: &Session,
@@ -1129,7 +1129,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
11291129
// FIXME: Remove this logic into librustc_*san once Cargo supports it
11301130
let rpath = cratepath.parent().unwrap();
11311131
let rpath = rpath.to_str().expect("non-utf8 component in path");
1132-
cmd.args(&["-Wl,-rpath".into(), "-Xlinker".into(), rpath.into()]);
1132+
cmd.args(&["-rpath".into(), rpath.into()]);
11331133
}
11341134

11351135
let dst = tmpdir.join(cratepath.file_name().unwrap());

src/librustc_trans/back/linker.rs

+38-41
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,22 @@ pub struct GccLinker<'a> {
131131
impl<'a> GccLinker<'a> {
132132
/// Argument that must be passed *directly* to the linker
133133
///
134-
/// These arguments need to be prepended with '-Wl,' when a gcc-style linker is used
134+
/// These arguments need to be preceded by '-Xlinker' when a gcc-style
135+
/// linker is used.
135136
fn linker_arg<S>(&mut self, arg: S) -> &mut Self
136137
where S: AsRef<OsStr>
137138
{
138139
if !self.is_ld {
139-
let mut os = OsString::from("-Wl,");
140-
os.push(arg.as_ref());
141-
self.cmd.arg(os);
142-
} else {
143-
self.cmd.arg(arg);
140+
self.cmd.arg("-Xlinker");
144141
}
142+
self.cmd.arg(arg);
143+
self
144+
}
145+
146+
fn add_lib<S: AsRef<OsStr>>(&mut self, lib: S) -> &mut Self {
147+
let mut os = OsString::from("-l");
148+
os.push(lib.as_ref());
149+
self.cmd.arg(os);
145150
self
146151
}
147152

@@ -171,8 +176,8 @@ impl<'a> GccLinker<'a> {
171176
}
172177

173178
impl<'a> Linker for GccLinker<'a> {
174-
fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg("-l").arg(lib); }
175-
fn link_staticlib(&mut self, lib: &str) { self.hint_static(); self.cmd.arg("-l").arg(lib); }
179+
fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.add_lib(lib); }
180+
fn link_staticlib(&mut self, lib: &str) { self.hint_static(); self.add_lib(lib); }
176181
fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
177182
fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); }
178183
fn framework_path(&mut self, path: &Path) { self.cmd.arg("-F").arg(path); }
@@ -182,11 +187,15 @@ impl<'a> Linker for GccLinker<'a> {
182187
fn partial_relro(&mut self) { self.linker_arg("-z,relro"); }
183188
fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); }
184189
fn build_static_executable(&mut self) { self.cmd.arg("-static"); }
185-
fn args(&mut self, args: &[String]) { self.cmd.args(args); }
190+
fn args(&mut self, args: &[String]) {
191+
for arg in args {
192+
self.linker_arg(arg);
193+
}
194+
}
186195

187196
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
188197
self.hint_dynamic();
189-
self.cmd.arg("-l").arg(lib);
198+
self.add_lib(lib);
190199
}
191200

192201
fn link_framework(&mut self, framework: &str) {
@@ -202,25 +211,22 @@ impl<'a> Linker for GccLinker<'a> {
202211
// functions, etc.
203212
fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]) {
204213
self.hint_static();
205-
let target = &self.sess.target.target;
206-
if !target.options.is_like_osx {
207-
self.linker_arg("--whole-archive").cmd.arg("-l").arg(lib);
208-
self.linker_arg("--no-whole-archive");
214+
if self.sess.target.target.options.is_like_osx {
215+
self.linker_arg("-force_load");
216+
// let-binding needed to appease borrowck.
217+
let lib = archive::find_library(lib, search_path, &self.sess);
218+
self.linker_arg(lib);
209219
} else {
210-
// -force_load is the macOS equivalent of --whole-archive, but it
211-
// involves passing the full path to the library to link.
212-
let mut v = OsString::from("-force_load,");
213-
v.push(&archive::find_library(lib, search_path, &self.sess));
214-
self.linker_arg(&v);
220+
self.linker_arg("--whole-archive").add_lib(lib);
221+
self.linker_arg("--no-whole-archive");
215222
}
216223
}
217224

218225
fn link_whole_rlib(&mut self, lib: &Path) {
219226
self.hint_static();
220227
if self.sess.target.target.options.is_like_osx {
221-
let mut v = OsString::from("-force_load,");
222-
v.push(lib);
223-
self.linker_arg(&v);
228+
self.linker_arg("-force_load");
229+
self.linker_arg(lib);
224230
} else {
225231
self.linker_arg("--whole-archive").cmd.arg(lib);
226232
self.linker_arg("--no-whole-archive");
@@ -282,16 +288,16 @@ impl<'a> Linker for GccLinker<'a> {
282288
fn build_dylib(&mut self, out_filename: &Path) {
283289
// On mac we need to tell the linker to let this library be rpathed
284290
if self.sess.target.target.options.is_like_osx {
285-
self.cmd.arg("-dynamiclib");
286291
self.linker_arg("-dylib");
287292

288293
// Note that the `osx_rpath_install_name` option here is a hack
289294
// purely to support rustbuild right now, we should get a more
290295
// principled solution at some point to force the compiler to pass
291-
// the right `-Wl,-install_name` with an `@rpath` in it.
296+
// the right `-install_name` with an `@rpath` in it.
292297
if self.sess.opts.cg.rpath ||
293298
self.sess.opts.debugging_opts.osx_rpath_install_name {
294-
let mut v = OsString::from("-install_name,@rpath/");
299+
self.linker_arg("-install_name");
300+
let mut v = OsString::from("@rpath/");
295301
v.push(out_filename.file_name().unwrap());
296302
self.linker_arg(&v);
297303
}
@@ -313,7 +319,6 @@ impl<'a> Linker for GccLinker<'a> {
313319
return
314320
}
315321

316-
let mut arg = OsString::new();
317322
let path = tmpdir.join("list");
318323

319324
debug!("EXPORTED SYMBOLS:");
@@ -349,24 +354,16 @@ impl<'a> Linker for GccLinker<'a> {
349354
}
350355

351356
if self.sess.target.target.options.is_like_osx {
352-
if !self.is_ld {
353-
arg.push("-Wl,")
354-
}
355-
arg.push("-exported_symbols_list,");
357+
self.linker_arg("-exported_symbols_list");
358+
self.linker_arg(&path);
356359
} else if self.sess.target.target.options.is_like_solaris {
357-
if !self.is_ld {
358-
arg.push("-Wl,")
359-
}
360-
arg.push("-M,");
360+
self.linker_arg("-M");
361+
self.linker_arg(&path);
361362
} else {
362-
if !self.is_ld {
363-
arg.push("-Wl,")
364-
}
365-
arg.push("--version-script=");
363+
let mut arg = OsString::from("--version-script=");
364+
arg.push(&path);
365+
self.linker_arg(&arg);
366366
}
367-
368-
arg.push(&path);
369-
self.cmd.arg(arg);
370367
}
371368

372369
fn subsystem(&mut self, subsystem: &str) {

src/librustc_trans/back/rpath.rs

+17-55
Original file line numberDiff line numberDiff line change
@@ -26,41 +26,30 @@ pub struct RPathConfig<'a> {
2626
}
2727

2828
pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
29-
// No rpath on windows
30-
if !config.has_rpath {
31-
return Vec::new();
32-
}
33-
3429
let mut flags = Vec::new();
3530

36-
debug!("preparing the RPATH!");
31+
// No rpath on windows
32+
if config.has_rpath {
33+
debug!("preparing the RPATH!");
34+
35+
let libs = config.used_crates.iter().filter_map(|&(_, ref l)| {
36+
l.option()
37+
}).collect::<Vec<_>>();
3738

38-
let libs = config.used_crates.clone();
39-
let libs = libs.iter().filter_map(|&(_, ref l)| l.option()).collect::<Vec<_>>();
40-
let rpaths = get_rpaths(config, &libs);
41-
flags.extend_from_slice(&rpaths_to_flags(&rpaths));
39+
for rpath in get_rpaths(config, &libs) {
40+
flags.push("-rpath".into());
41+
flags.push(rpath);
42+
}
4243

43-
// Use DT_RUNPATH instead of DT_RPATH if available
44-
if config.linker_is_gnu {
45-
flags.push("-Wl,--enable-new-dtags".to_string());
44+
// Use DT_RUNPATH instead of DT_RPATH if available
45+
if config.linker_is_gnu {
46+
flags.push("--enable-new-dtags".into());
47+
}
4648
}
4749

4850
flags
4951
}
5052

51-
fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
52-
let mut ret = Vec::new();
53-
for rpath in rpaths {
54-
if rpath.contains(',') {
55-
ret.push("-Wl,-rpath".into());
56-
ret.push("-Xlinker".into());
57-
ret.push(rpath.clone());
58-
} else {
59-
ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
60-
}
61-
}
62-
return ret;
63-
}
6453

6554
fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
6655
debug!("output: {:?}", config.out_filename.display());
@@ -91,8 +80,7 @@ fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
9180
rpaths.extend_from_slice(&fallback_rpaths);
9281

9382
// Remove duplicates
94-
let rpaths = minimize_rpaths(&rpaths);
95-
return rpaths;
83+
minimize_rpaths(&rpaths)
9684
}
9785

9886
fn get_rpaths_relative_to_output(config: &mut RPathConfig,
@@ -187,20 +175,9 @@ fn minimize_rpaths(rpaths: &[String]) -> Vec<String> {
187175
#[cfg(all(unix, test))]
188176
mod tests {
189177
use super::{RPathConfig};
190-
use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
178+
use super::{minimize_rpaths, get_rpath_relative_to_output};
191179
use std::path::{Path, PathBuf};
192180

193-
#[test]
194-
fn test_rpaths_to_flags() {
195-
let flags = rpaths_to_flags(&[
196-
"path1".to_string(),
197-
"path2".to_string()
198-
]);
199-
assert_eq!(flags,
200-
["-Wl,-rpath,path1",
201-
"-Wl,-rpath,path2"]);
202-
}
203-
204181
#[test]
205182
fn test_minimize1() {
206183
let res = minimize_rpaths(&[
@@ -264,19 +241,4 @@ mod tests {
264241
assert_eq!(res, "$ORIGIN/../lib");
265242
}
266243
}
267-
268-
#[test]
269-
fn test_xlinker() {
270-
let args = rpaths_to_flags(&[
271-
"a/normal/path".to_string(),
272-
"a,comma,path".to_string()
273-
]);
274-
275-
assert_eq!(args, vec![
276-
"-Wl,-rpath,a/normal/path".to_string(),
277-
"-Wl,-rpath".to_string(),
278-
"-Xlinker".to_string(),
279-
"a,comma,path".to_string()
280-
]);
281-
}
282244
}

src/test/run-make/fpic/Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ ifeq ($(UNAME),Darwin)
77
all:
88
else ifdef IS_WINDOWS
99
all:
10-
else
10+
else ifeq ($(findstring stage0,$(RUST_BUILD_STAGE)),stage0)
1111
all:
1212
$(RUSTC) hello.rs -C link-args=-Wl,-z,text
13+
else
14+
all:
15+
$(RUSTC) hello.rs -C link-args='-z text'
1316
endif

0 commit comments

Comments
 (0)