Skip to content

Commit e1d775f

Browse files
committed
---
yaml --- r: 208713 b: refs/heads/snap-stage3 c: 2d5e577 h: refs/heads/master i: 208711: 9325e21 v: v3
1 parent a7829ac commit e1d775f

File tree

4 files changed

+238
-143
lines changed

4 files changed

+238
-143
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 38a97becdf3e6a6157f6f7ec2d98ade8d8edc193
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 4cc025d83c5e3e54130dff08987982a0926e4cfa
4+
refs/heads/snap-stage3: 2d5e5777fd94fcad0bf259e31982477e42bd5bf8
55
refs/heads/try: 7b4ef47b7805a402d756fb8157101f64880a522f
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d

branches/snap-stage3/src/librustc_trans/back/link.rs

Lines changed: 61 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
// except according to those terms.
1010

1111
use super::archive::{Archive, ArchiveBuilder, ArchiveConfig, METADATA_FILENAME};
12-
use super::archive;
13-
use super::rpath;
12+
use super::linker::{Linker, GnuLinker};
1413
use super::rpath::RPathConfig;
14+
use super::rpath;
1515
use super::svh::Svh;
1616
use session::config;
1717
use session::config::NoDebugInfo;
@@ -29,7 +29,6 @@ use util::sha2::{Digest, Sha256};
2929
use util::fs::fix_windows_verbatim_for_gcc;
3030
use rustc_back::tempdir::TempDir;
3131

32-
use std::ffi::OsString;
3332
use std::fs::{self, PathExt};
3433
use std::io::{self, Read, Write};
3534
use std::mem;
@@ -801,10 +800,13 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
801800
cmd.arg(root.join(obj));
802801
}
803802

804-
link_args(&mut cmd, sess, dylib, tmpdir.path(),
805-
trans, obj_filename, out_filename);
806-
if !sess.target.target.options.no_compiler_rt {
807-
cmd.arg("-lcompiler-rt");
803+
{
804+
let mut linker = GnuLinker { cmd: &mut cmd, sess: &sess };
805+
link_args(&mut linker, sess, dylib, tmpdir.path(),
806+
trans, obj_filename, out_filename);
807+
if !sess.target.target.options.no_compiler_rt {
808+
linker.link_staticlib("compiler-rt");
809+
}
808810
}
809811
for obj in &sess.target.target.options.post_link_objects {
810812
cmd.arg(root.join(obj));
@@ -858,7 +860,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
858860
}
859861
}
860862

861-
fn link_args(cmd: &mut Command,
863+
fn link_args(cmd: &mut Linker,
862864
sess: &Session,
863865
dylib: bool,
864866
tmpdir: &Path,
@@ -873,10 +875,10 @@ fn link_args(cmd: &mut Command,
873875
// target descriptor
874876
let t = &sess.target.target;
875877

876-
cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(&lib_path));
877-
878-
cmd.arg("-o").arg(out_filename).arg(obj_filename);
878+
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
879879

880+
cmd.output_filename(out_filename);
881+
cmd.add_object(obj_filename);
880882

881883
// Stack growth requires statically linking a __morestack function. Note
882884
// that this is listed *before* all other libraries. Due to the usage of the
@@ -895,89 +897,44 @@ fn link_args(cmd: &mut Command,
895897
// will include the __morestack symbol 100% of the time, always resolving
896898
// references to it even if the object above didn't use it.
897899
if t.options.morestack {
898-
if t.options.is_like_osx {
899-
let morestack = lib_path.join("libmorestack.a");
900-
901-
let mut v = OsString::from("-Wl,-force_load,");
902-
v.push(&morestack);
903-
cmd.arg(&v);
904-
} else {
905-
cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
906-
}
900+
cmd.link_whole_staticlib("morestack", &[lib_path]);
907901
}
908902

909903
// When linking a dynamic library, we put the metadata into a section of the
910904
// executable. This metadata is in a separate object file from the main
911905
// object file, so we link that in here.
912906
if dylib {
913-
cmd.arg(&obj_filename.with_extension("metadata.o"));
907+
cmd.add_object(&obj_filename.with_extension("metadata.o"));
914908
}
915909

916-
if t.options.is_like_osx {
917-
// The dead_strip option to the linker specifies that functions and data
918-
// unreachable by the entry point will be removed. This is quite useful
919-
// with Rust's compilation model of compiling libraries at a time into
920-
// one object file. For example, this brings hello world from 1.7MB to
921-
// 458K.
922-
//
923-
// Note that this is done for both executables and dynamic libraries. We
924-
// won't get much benefit from dylibs because LLVM will have already
925-
// stripped away as much as it could. This has not been seen to impact
926-
// link times negatively.
927-
//
928-
// -dead_strip can't be part of the pre_link_args because it's also used
929-
// for partial linking when using multiple codegen units (-r). So we
930-
// insert it here.
931-
cmd.arg("-Wl,-dead_strip");
932-
}
933-
934-
// If we're building a dylib, we don't use --gc-sections because LLVM has
935-
// already done the best it can do, and we also don't want to eliminate the
936-
// metadata. If we're building an executable, however, --gc-sections drops
937-
// the size of hello world from 1.8MB to 597K, a 67% reduction.
938-
if !dylib && !t.options.is_like_osx {
939-
cmd.arg("-Wl,--gc-sections");
940-
}
910+
// Try to strip as much out of the generated object by removing unused
911+
// sections if possible. See more comments in linker.rs
912+
cmd.gc_sections(dylib);
941913

942914
let used_link_args = sess.cstore.get_used_link_args().borrow();
943915

944-
if t.options.position_independent_executables {
916+
if !dylib && t.options.position_independent_executables {
945917
let empty_vec = Vec::new();
946918
let empty_str = String::new();
947919
let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
948920
let mut args = args.iter().chain(used_link_args.iter());
949-
if !dylib
950-
&& (t.options.relocation_model == "pic"
951-
|| *sess.opts.cg.relocation_model.as_ref()
952-
.unwrap_or(&empty_str) == "pic")
921+
let relocation_model = sess.opts.cg.relocation_model.as_ref()
922+
.unwrap_or(&empty_str);
923+
if (t.options.relocation_model == "pic" || *relocation_model == "pic")
953924
&& !args.any(|x| *x == "-static") {
954-
cmd.arg("-pie");
925+
cmd.position_independent_executable();
955926
}
956927
}
957928

958-
if t.options.linker_is_gnu {
959-
// GNU-style linkers support optimization with -O. GNU ld doesn't need a
960-
// numeric argument, but other linkers do.
961-
if sess.opts.optimize == config::Default ||
962-
sess.opts.optimize == config::Aggressive {
963-
cmd.arg("-Wl,-O1");
964-
}
965-
}
929+
// Pass optimization flags down to the linker.
930+
cmd.optimize();
966931

967932
// We want to prevent the compiler from accidentally leaking in any system
968933
// libraries, so we explicitly ask gcc to not link to any libraries by
969934
// default. Note that this does not happen for windows because windows pulls
970935
// in some large number of libraries and I couldn't quite figure out which
971936
// subset we wanted.
972-
if !t.options.is_like_windows {
973-
cmd.arg("-nodefaultlibs");
974-
}
975-
976-
// Mark all dynamic libraries and executables as compatible with ASLR
977-
// FIXME #17098: ASLR breaks gdb
978-
if t.options.is_like_windows && sess.opts.debuginfo == NoDebugInfo {
979-
// cmd.arg("-Wl,--dynamicbase");
980-
}
937+
cmd.no_default_libraries();
981938

982939
// Take careful note of the ordering of the arguments we pass to the linker
983940
// here. Linkers will assume that things on the left depend on things to the
@@ -1019,18 +976,7 @@ fn link_args(cmd: &mut Command,
1019976
// # Telling the linker what we're doing
1020977

1021978
if dylib {
1022-
// On mac we need to tell the linker to let this library be rpathed
1023-
if sess.target.target.options.is_like_osx {
1024-
cmd.args(&["-dynamiclib", "-Wl,-dylib"]);
1025-
1026-
if sess.opts.cg.rpath {
1027-
let mut v = OsString::from("-Wl,-install_name,@rpath/");
1028-
v.push(out_filename.file_name().unwrap());
1029-
cmd.arg(&v);
1030-
}
1031-
} else {
1032-
cmd.arg("-shared");
1033-
}
979+
cmd.build_dylib(out_filename);
1034980
}
1035981

1036982
// FIXME (#2397): At some point we want to rpath our guesses as to
@@ -1059,9 +1005,10 @@ fn link_args(cmd: &mut Command,
10591005

10601006
// Finally add all the linker arguments provided on the command line along
10611007
// with any #[link_args] attributes found inside the crate
1062-
let empty = Vec::new();
1063-
cmd.args(&sess.opts.cg.link_args.as_ref().unwrap_or(&empty));
1064-
cmd.args(&used_link_args[..]);
1008+
if let Some(ref args) = sess.opts.cg.link_args {
1009+
cmd.args(args);
1010+
}
1011+
cmd.args(&used_link_args);
10651012
}
10661013

10671014
// # Native library linking
@@ -1075,21 +1022,15 @@ fn link_args(cmd: &mut Command,
10751022
// Also note that the native libraries linked here are only the ones located
10761023
// in the current crate. Upstream crates with native library dependencies
10771024
// may have their native library pulled in above.
1078-
fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
1025+
fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
10791026
sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
10801027
match k {
1081-
PathKind::Framework => { cmd.arg("-F").arg(path); }
1082-
_ => { cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(path)); }
1028+
PathKind::Framework => { cmd.framework_path(path); }
1029+
_ => { cmd.include_path(&fix_windows_verbatim_for_gcc(path)); }
10831030
}
10841031
FileDoesntMatch
10851032
});
10861033

1087-
// Some platforms take hints about whether a library is static or dynamic.
1088-
// For those that support this, we ensure we pass the option if the library
1089-
// was flagged "static" (most defaults are dynamic) to ensure that if
1090-
// libfoo.a and libfoo.so both exist that the right one is chosen.
1091-
let takes_hints = !sess.target.target.options.is_like_osx;
1092-
10931034
let libs = sess.cstore.get_used_libraries();
10941035
let libs = libs.borrow();
10951036

@@ -1100,46 +1041,29 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
11001041
kind != cstore::NativeStatic
11011042
});
11021043

1103-
// Platforms that take hints generally also support the --whole-archive
1104-
// flag. We need to pass this flag when linking static native libraries to
1105-
// ensure the entire library is included.
1106-
//
1107-
// For more details see #15460, but the gist is that the linker will strip
1108-
// away any unused objects in the archive if we don't otherwise explicitly
1109-
// reference them. This can occur for libraries which are just providing
1110-
// bindings, libraries with generic functions, etc.
1111-
if takes_hints {
1112-
cmd.arg("-Wl,--whole-archive").arg("-Wl,-Bstatic");
1113-
}
1044+
// Some platforms take hints about whether a library is static or dynamic.
1045+
// For those that support this, we ensure we pass the option if the library
1046+
// was flagged "static" (most defaults are dynamic) to ensure that if
1047+
// libfoo.a and libfoo.so both exist that the right one is chosen.
1048+
cmd.hint_static();
1049+
11141050
let search_path = archive_search_paths(sess);
11151051
for l in staticlibs {
1116-
if takes_hints {
1117-
cmd.arg(&format!("-l{}", l));
1118-
} else {
1119-
// -force_load is the OSX equivalent of --whole-archive, but it
1120-
// involves passing the full path to the library to link.
1121-
let lib = archive::find_library(&l[..],
1122-
&sess.target.target.options.staticlib_prefix,
1123-
&sess.target.target.options.staticlib_suffix,
1124-
&search_path[..],
1125-
&sess.diagnostic().handler);
1126-
let mut v = OsString::from("-Wl,-force_load,");
1127-
v.push(&lib);
1128-
cmd.arg(&v);
1129-
}
1130-
}
1131-
if takes_hints {
1132-
cmd.arg("-Wl,--no-whole-archive").arg("-Wl,-Bdynamic");
1052+
// Here we explicitly ask that the entire archive is included into the
1053+
// result artifact. For more details see #15460, but the gist is that
1054+
// the linker will strip away any unused objects in the archive if we
1055+
// don't otherwise explicitly reference them. This can occur for
1056+
// libraries which are just providing bindings, libraries with generic
1057+
// functions, etc.
1058+
cmd.link_whole_staticlib(l, &search_path);
11331059
}
11341060

1061+
cmd.hint_dynamic();
1062+
11351063
for &(ref l, kind) in others {
11361064
match kind {
1137-
cstore::NativeUnknown => {
1138-
cmd.arg(&format!("-l{}", l));
1139-
}
1140-
cstore::NativeFramework => {
1141-
cmd.arg("-framework").arg(&l[..]);
1142-
}
1065+
cstore::NativeUnknown => cmd.link_dylib(l),
1066+
cstore::NativeFramework => cmd.link_framework(l),
11431067
cstore::NativeStatic => unreachable!(),
11441068
}
11451069
}
@@ -1150,7 +1074,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
11501074
// Rust crates are not considered at all when creating an rlib output. All
11511075
// dependencies will be linked when producing the final output (instead of
11521076
// the intermediate rlib version)
1153-
fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
1077+
fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
11541078
dylib: bool, tmpdir: &Path,
11551079
trans: &CrateTranslation) {
11561080
// All of the heavy lifting has previously been accomplished by the
@@ -1201,7 +1125,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
12011125
}
12021126

12031127
// Adds the static "rlib" versions of all crates to the command line.
1204-
fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
1128+
fn add_static_crate(cmd: &mut Linker, sess: &Session, tmpdir: &Path,
12051129
cratepath: &Path) {
12061130
// When performing LTO on an executable output, all of the
12071131
// bytecode from the upstream libraries has already been
@@ -1263,27 +1187,27 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
12631187
archive.remove_file(&format!("{}.o", name));
12641188
let files = archive.files();
12651189
if files.iter().any(|s| s.ends_with(".o")) {
1266-
cmd.arg(&dst);
1190+
cmd.link_rlib(&dst);
12671191
}
12681192
});
12691193
} else {
1270-
cmd.arg(&fix_windows_verbatim_for_gcc(cratepath));
1194+
cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
12711195
}
12721196
}
12731197

12741198
// Same thing as above, but for dynamic crates instead of static crates.
1275-
fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: &Path) {
1199+
fn add_dynamic_crate(cmd: &mut Linker, sess: &Session, cratepath: &Path) {
12761200
// If we're performing LTO, then it should have been previously required
12771201
// that all upstream rust dependencies were available in an rlib format.
12781202
assert!(!sess.lto());
12791203

12801204
// Just need to tell the linker about where the library lives and
12811205
// what its name is
12821206
if let Some(dir) = cratepath.parent() {
1283-
cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(dir));
1207+
cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
12841208
}
12851209
let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
1286-
cmd.arg(&format!("-l{}", unlib(&sess.target, filestem)));
1210+
cmd.link_dylib(&unlib(&sess.target, filestem));
12871211
}
12881212
}
12891213

@@ -1305,7 +1229,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
13051229
// generic function calls a native function, then the generic function must
13061230
// be instantiated in the target crate, meaning that the native symbol must
13071231
// also be resolved in the target crate.
1308-
fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
1232+
fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session) {
13091233
// Be sure to use a topological sorting of crates because there may be
13101234
// interdependencies between native libraries. When passing -nodefaultlibs,
13111235
// for example, almost all native libraries depend on libc, so we have to
@@ -1320,13 +1244,8 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
13201244
let libs = csearch::get_native_libraries(&sess.cstore, cnum);
13211245
for &(kind, ref lib) in &libs {
13221246
match kind {
1323-
cstore::NativeUnknown => {
1324-
cmd.arg(&format!("-l{}", *lib));
1325-
}
1326-
cstore::NativeFramework => {
1327-
cmd.arg("-framework");
1328-
cmd.arg(&lib[..]);
1329-
}
1247+
cstore::NativeUnknown => cmd.link_dylib(lib),
1248+
cstore::NativeFramework => cmd.link_framework(lib),
13301249
cstore::NativeStatic => {
13311250
sess.bug("statics shouldn't be propagated");
13321251
}

0 commit comments

Comments
 (0)