// Adds the static "rlib" versions of all crates to the command line.
// There's a bit of magic which happens here specifically related to LTO and
// dynamic libraries. Specifically:
//
// * For LTO, we remove upstream object files.
// * For dylibs we remove metadata and bytecode from upstream rlibs
//
// When performing LTO, all of the bytecode from the upstream libraries has
// already been included in our object file output. As a result we need to
// remove the object files in the upstream libraries so the linker doesn't
// try to include them twice (or whine about duplicate symbols). We must
// continue to include the rest of the rlib, however, as it may contain
// static native libraries which must be linked in.
//
// When making a dynamic library, linkers by default don't include any
// object files in an archive if they're not necessary to resolve the link.
// We basically want to convert the archive (rlib) to a dylib, though, so we
// *do* want everything included in the output, regardless of whether the
// linker thinks it's needed or not. As a result we must use the
// --whole-archive option (or the platform equivalent). When using this
// option the linker will fail if there are non-objects in the archive (such
// as our own metadata and/or bytecode). All in all, for rlibs to be
// entirely included in dylibs, we need to remove all non-object files.
//
// Note, however, that if we're not doing LTO or we're not producing a dylib
// (aka we're making an executable), we can just pass the rlib blindly to
// the linker (fast) because it's fine if it's not actually included as
// we're at the end of the dependency chain.
Adds the static "rlib" versions of all crates to the command line.
There's a bit of magic which happens here specifically related to LTO and
dynamic libraries. Specifically.

For LTO, we remove upstream object files.
For dylibs we remove metadata and bytecode from upstream rlibs

When performing LTO, all of the bytecode from the upstream libraries has
already been included in our object file output. As a result we need to
remove the object files in the upstream libraries so the linker doesn't
try to include them twice (or whine about duplicate symbols). We must
continue to include the rest of the rlib, however, as it may contain
static native libraries which must be linked in.

When making a dynamic library, linkers by default don't include any
object files in an archive if they're not necessary to resolve the link.
We basically want to convert the archive (rlib) to a dylib, though, so we
do* want everything included in the output, regardless of whether the
linker thinks it's needed or not. As a result we must use the
whole-archive option (or the platform equivalent). When using this
option the linker will fail if there are non-objects in the archive (such
as our own metadata and/or bytecode). All in all, for rlibs to be
entirely included in dylibs, we need to remove all non-object files.


Adds the static " rlib " versions of all crates to the command line . There ' s a bit of magic which happens here specifically related to LTO and dynamic libraries . Specifically . For LTO we remove upstream object files . For dylibs we remove metadata and bytecode from upstream rlibs When performing LTO all of the bytecode from the upstream libraries has already been included in our object file output . As a result we need to remove the object files in the upstream libraries so the linker doesn ' t try to include them twice ( or whine about duplicate symbols ) . We must continue to include the rest of the rlib however as it may contain static native libraries which must be linked in . When making a dynamic library linkers by default don ' t include any object files in an archive if they ' re not necessary to resolve the link . We basically want to convert the archive ( rlib ) to a dylib though so we do * want everything included in the output regardless of whether the linker thinks it ' s needed or not . As a result we must use the whole - archive option ( or the platform equivalent ) . When using this option the linker will fail if there are non - objects in the archive ( such as our own metadata and / or bytecode ) . All in all for rlibs to be entirely included in dylibs we need to remove all non - object files .
fn add_static_crate(cmd: &mut Linker, sess: &Session, tmpdir: &Path,
                        dylib: bool, cratepath: &Path) {
        if !sess.lto() && !dylib {
            cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
            return
        }
        let dst = tmpdir.join(cratepath.file_name().unwrap());
        let name = cratepath.file_name().unwrap().to_str().unwrap();
        let name = &name[3..name.len() - 5]; // chop off lib/.rlib
        time(sess.time_passes(), &format!("altering {}.rlib", name), || {
            let cfg = archive_config(sess, &dst, Some(cratepath));
            let mut archive = ArchiveBuilder::new(cfg);
            archive.remove_file(METADATA_FILENAME);
            archive.update_symbols();
            let mut any_objects = false;
            for f in archive.src_files() {
                if f.ends_with("bytecode.deflate") {
                    archive.remove_file(&f);
                    continue
                }
                let canonical = f.replace("-", "_");
                let canonical_name = name.replace("-", "_");
                if sess.lto() && canonical.starts_with(&canonical_name) &&
                   canonical.ends_with(".o") {
                    let num = &f[name.len()..f.len() - 2];
                    if num.len() > 0 && num[1..].parse::<u32>().is_ok() {
                        archive.remove_file(&f);
                        continue
                    }
                }
                any_objects = true;
            }
            if any_objects {
                archive.build();
                cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
            }
        });
    }
fn add_static_crate ( cmd : & mut Linker , sess : & Session , tmpdir : & Path , dylib : bool , cratepath : & Path ) { if ! sess . lto ( ) && ! dylib { cmd . link_rlib ( & fix_windows_verbatim_for_gcc ( cratepath ) ) ; return } let dst = tmpdir . join ( cratepath . file_name ( ) . unwrap ( ) ) ; let name = cratepath . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ; let name = & name [ 3 .. name . len ( ) - 5 ] ; // chop off lib/.rlib time ( sess . time_passes ( ) , & format ! ( " " name ) , | | { let cfg = archive_config ( sess , & dst , Some ( cratepath ) ) ; let mut archive = ArchiveBuilder :: new ( cfg ) ; archive . remove_file ( METADATA_FILENAME ) ; archive . update_symbols ( ) ; let mut any_objects = false ; for f in archive . src_files ( ) { if f . ends_with ( " " ) { archive . remove_file ( & f ) ; continue } let canonical = f . replace ( " " , " " ) ; let canonical_name = name . replace ( " " , " " ) ; if sess . lto ( ) && canonical . starts_with ( & canonical_name ) && canonical . ends_with ( " " ) { let num = & f [ name . len ( ) .. f . len ( ) - 2 ] ; if num . len ( ) > 0 && num [ 1 .. ] . parse :: < u32 > ( ) . is_ok ( ) { archive . remove_file ( & f ) ; continue } } any_objects = true ; } if any_objects { archive . build ( ) ; cmd . link_whole_rlib ( & fix_windows_verbatim_for_gcc ( & dst ) ) ; } } ) ; }
Adds the static "rlib" versions of all crates to the command line.
Adds the static " rlib " versions of all crates to the command line .
cmd
&mut Linker
sess
&Session
tmpdir
&Path
dylib
bool
cratepath
&Path