Skip to content

rustc_trans: Link archives with --whole-archive #19183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/liballoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ pub fn oom() -> ! {
// reference to this symbol will cause this library's object file
// to get linked in to libstd successfully (the linker won't
// optimize it out).
// NOTE: remove after snapshot
#[cfg(stage0)]
#[doc(hidden)]
pub fn fixme_14344_be_sure_to_link_to_collections() {}

Expand Down
2 changes: 2 additions & 0 deletions src/libcollections/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ pub mod btree_set {
#[cfg(test)] mod bench;

// FIXME(#14344) this shouldn't be necessary
// NOTE: remove after snapshot
#[cfg(stage0)]
#[doc(hidden)]
pub fn fixme_14344_be_sure_to_link_to_collections() {}

Expand Down
4 changes: 2 additions & 2 deletions src/liblibc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4989,7 +4989,7 @@ pub mod funcs {
}
}

// NOTE: remove after snapshot
#[cfg(stage0)]
#[doc(hidden)]
pub fn issue_14344_workaround() {} // FIXME #14344 force linkage to happen correctly

#[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows
90 changes: 49 additions & 41 deletions src/librustc_trans/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1197,54 +1197,62 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
//
// If we're not doing LTO, then our job is simply to just link
// against the archive.
if sess.lto() {
let name = cratepath.filename_str().unwrap();
let name = name.slice(3, name.len() - 5); // chop off lib/.rlib
time(sess.time_passes(),
format!("altering {}.rlib", name).as_slice(),
(), |()| {
let dst = tmpdir.join(cratepath.filename().unwrap());
match fs::copy(&cratepath, &dst) {
Ok(..) => {}
Err(e) => {
sess.err(format!("failed to copy {} to {}: {}",
cratepath.display(),
dst.display(),
e).as_slice());
sess.abort_if_errors();
}
let name = cratepath.filename_str().unwrap();
let name = name.slice(3, name.len() - 5); // chop off lib/.rlib
time(sess.time_passes(),
format!("altering {}.rlib", name).as_slice(),
(), |()| {

let dst = tmpdir.join(cratepath.filename().unwrap());
match fs::copy(&cratepath, &dst) {
Ok(..) => {}
Err(e) => {
sess.err(format!("failed to copy {} to {}: {}",
cratepath.display(),
dst.display(),
e).as_slice());
sess.abort_if_errors();
}
// Fix up permissions of the copy, as fs::copy() preserves
// permissions, but the original file may have been installed
// by a package manager and may be read-only.
match fs::chmod(&dst, io::USER_READ | io::USER_WRITE) {
Ok(..) => {}
Err(e) => {
sess.err(format!("failed to chmod {} when preparing \
for LTO: {}", dst.display(),
e).as_slice());
sess.abort_if_errors();
}
}
// Fix up permissions of the copy, as fs::copy() preserves
// permissions, but the original file may have been installed
// by a package manager and may be read-only.
match fs::chmod(&dst, io::USER_READ | io::USER_WRITE) {
Ok(..) => {}
Err(e) => {
sess.err(format!("failed to chmod {} when preparing \
for LTO: {}", dst.display(),
e).as_slice());
sess.abort_if_errors();
}
let handler = &sess.diagnostic().handler;
let config = ArchiveConfig {
handler: handler,
dst: dst.clone(),
lib_search_paths: archive_search_paths(sess),
slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
maybe_ar_prog: sess.opts.cg.ar.clone()
};
let mut archive = Archive::open(config);
}
let handler = &sess.diagnostic().handler;
let config = ArchiveConfig {
handler: handler,
dst: dst.clone(),
lib_search_paths: archive_search_paths(sess),
slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
maybe_ar_prog: sess.opts.cg.ar.clone()
};
let mut archive = Archive::open(config);

if sess.lto() {
archive.remove_file(format!("{}.o", name).as_slice());
let files = archive.files();
if files.iter().any(|s| s.as_slice().ends_with(".o")) {
cmd.arg(dst);
}
});
} else {
cmd.arg(cratepath);
}
} else {
let files = archive.files();
for file in files.iter() {
if !file.ends_with(".o") {
archive.remove_file(file[]);
}
}
cmd.args(&[b"-Wl,--whole-archive", dst.as_vec(), b"-Wl,--no-whole-archive"]);
}
});
}

// Same thing as above, but for dynamic crates instead of static crates.
Expand Down
16 changes: 12 additions & 4 deletions src/librustrt/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,18 @@ pub fn init(argc: int, argv: *const *const u8) {
thread::init();
}

// FIXME(#14344) this shouldn't be necessary
collections::fixme_14344_be_sure_to_link_to_collections();
alloc::fixme_14344_be_sure_to_link_to_collections();
libc::issue_14344_workaround();
fixme_14344();

// NOTE: remove after snapshot
#[cfg(stage0)]
fn fixme_14344() {
// FIXME(#14344) this shouldn't be necessary
collections::fixme_14344_be_sure_to_link_to_collections();
alloc::fixme_14344_be_sure_to_link_to_collections();
libc::issue_14344_workaround();
}
#[cfg(not(stage0))]
fn fixme_14344() {}
}

/// Enqueues a procedure to run when the runtime is cleaned up
Expand Down