Skip to content

Use linker optimizations on Linux #10620

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
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
13 changes: 13 additions & 0 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,13 @@ pub fn link_args(sess: Session,
args.push("-L" + path.as_str().unwrap().to_owned());
}

if sess.targ_cfg.os == abi::OsLinux {
// GNU-style linkers will use this to omit linking to libraries which don't actually fulfill
// any relocations, but only for libraries which follow this flag. Thus, use it before
// specifing libraries to link to.
args.push(~"-Wl,--as-needed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a subtle change in linking that no one is able to change without recompiling the compiler. What are the benefits of doing this? The quote I found from the manpage was:

This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the --as-needed option. Normally the linker will add a DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is actually needed or not. --as-needed causes a DT_NEEDED tag to only be emitted for a library that satisfies an undefined symbol reference from a regular object file or, if the library is not found in the DT_NEEDED lists of other libraries linked up to that point, an undefined symbol reference from another dynamic library. --no-as-needed restores the default behaviour.

Which sounds like a library may not link to a native dynamic library even if I ask the compiler to do so. I don't really know of a use case for doing that, but I don't want to prohibit that from happening just because I don't understand the use case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It avoids linking against shared objects on platforms where they don't provide any of the symbols used by the program. For example, clock_gettime was moved from librt.so to libc.so in modern glibc versions but the crate is likely to still specify -lrt if it needs it. I can't think of a valid reason to override it. It really only needs to be a flag for backwards compatibility with broken build systems not linking in the right order.

}

// The names of the extern libraries
let used_libs = cstore::get_used_libraries(cstore);
for l in used_libs.iter() { args.push(~"-l" + *l); }
Expand All @@ -1091,6 +1098,12 @@ pub fn link_args(sess: Session,
// On linux librt and libdl are an indirect dependencies via rustrt,
// and binutils 2.22+ won't add them automatically
if sess.targ_cfg.os == abi::OsLinux {
// GNU-style linkers supports optimization with -O. --gc-sections removes metadata and
// potentially other useful things, so don't include it.
if sess.opts.optimize == session::Default || sess.opts.optimize == session::Aggressive {
args.push(~"-Wl,-O");
}

args.push_all([~"-lrt", ~"-ldl"]);

// LLVM implements the `frem` instruction as a call to `fmod`,
Expand Down