]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/back/link.rs
rollup merge of #24711: alexcrichton/fs2.1
[rust.git] / src / librustc_trans / back / link.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use super::archive::{Archive, ArchiveBuilder, ArchiveConfig, METADATA_FILENAME};
12 use super::archive;
13 use super::rpath;
14 use super::rpath::RPathConfig;
15 use super::svh::Svh;
16 use session::config;
17 use session::config::NoDebugInfo;
18 use session::config::{OutputFilenames, Input, OutputTypeBitcode, OutputTypeExe, OutputTypeObject};
19 use session::search_paths::PathKind;
20 use session::Session;
21 use metadata::common::LinkMeta;
22 use metadata::{encoder, cstore, filesearch, csearch, creader};
23 use metadata::filesearch::FileDoesntMatch;
24 use trans::{CrateContext, CrateTranslation, gensym_name};
25 use middle::ty::{self, Ty};
26 use util::common::time;
27 use util::ppaux;
28 use util::sha2::{Digest, Sha256};
29 use rustc_back::tempdir::TempDir;
30
31 use std::ffi::OsString;
32 use std::fs::{self, PathExt};
33 use std::io::{self, Read, Write};
34 use std::mem;
35 use std::path::{self, Path, PathBuf};
36 use std::process::Command;
37 use std::str;
38 use flate;
39 use serialize::hex::ToHex;
40 use syntax::ast;
41 use syntax::ast_map::{PathElem, PathElems, PathName};
42 use syntax::attr::AttrMetaMethods;
43 use syntax::codemap::Span;
44 use syntax::parse::token;
45
46 // RLIB LLVM-BYTECODE OBJECT LAYOUT
47 // Version 1
48 // Bytes    Data
49 // 0..10    "RUST_OBJECT" encoded in ASCII
50 // 11..14   format version as little-endian u32
51 // 15..22   size in bytes of deflate compressed LLVM bitcode as
52 //          little-endian u64
53 // 23..     compressed LLVM bitcode
54
55 // This is the "magic number" expected at the beginning of a LLVM bytecode
56 // object in an rlib.
57 pub const RLIB_BYTECODE_OBJECT_MAGIC: &'static [u8] = b"RUST_OBJECT";
58
59 // The version number this compiler will write to bytecode objects in rlibs
60 pub const RLIB_BYTECODE_OBJECT_VERSION: u32 = 1;
61
62 // The offset in bytes the bytecode object format version number can be found at
63 pub const RLIB_BYTECODE_OBJECT_VERSION_OFFSET: usize = 11;
64
65 // The offset in bytes the size of the compressed bytecode can be found at in
66 // format version 1
67 pub const RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET: usize =
68     RLIB_BYTECODE_OBJECT_VERSION_OFFSET + 4;
69
70 // The offset in bytes the compressed LLVM bytecode can be found at in format
71 // version 1
72 pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: usize =
73     RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8;
74
75
76 /*
77  * Name mangling and its relationship to metadata. This is complex. Read
78  * carefully.
79  *
80  * The semantic model of Rust linkage is, broadly, that "there's no global
81  * namespace" between crates. Our aim is to preserve the illusion of this
82  * model despite the fact that it's not *quite* possible to implement on
83  * modern linkers. We initially didn't use system linkers at all, but have
84  * been convinced of their utility.
85  *
86  * There are a few issues to handle:
87  *
88  *  - Linkers operate on a flat namespace, so we have to flatten names.
89  *    We do this using the C++ namespace-mangling technique. Foo::bar
90  *    symbols and such.
91  *
92  *  - Symbols with the same name but different types need to get different
93  *    linkage-names. We do this by hashing a string-encoding of the type into
94  *    a fixed-size (currently 16-byte hex) cryptographic hash function (CHF:
95  *    we use SHA256) to "prevent collisions". This is not airtight but 16 hex
96  *    digits on uniform probability means you're going to need 2**32 same-name
97  *    symbols in the same process before you're even hitting birthday-paradox
98  *    collision probability.
99  *
100  *  - Symbols in different crates but with same names "within" the crate need
101  *    to get different linkage-names.
102  *
103  *  - The hash shown in the filename needs to be predictable and stable for
104  *    build tooling integration. It also needs to be using a hash function
105  *    which is easy to use from Python, make, etc.
106  *
107  * So here is what we do:
108  *
109  *  - Consider the package id; every crate has one (specified with crate_id
110  *    attribute).  If a package id isn't provided explicitly, we infer a
111  *    versionless one from the output name. The version will end up being 0.0
112  *    in this case. CNAME and CVERS are taken from this package id. For
113  *    example, github.com/mozilla/CNAME#CVERS.
114  *
115  *  - Define CMH as SHA256(crateid).
116  *
117  *  - Define CMH8 as the first 8 characters of CMH.
118  *
119  *  - Compile our crate to lib CNAME-CMH8-CVERS.so
120  *
121  *  - Define STH(sym) as SHA256(CMH, type_str(sym))
122  *
123  *  - Suffix a mangled sym with ::STH@CVERS, so that it is unique in the
124  *    name, non-name metadata, and type sense, and versioned in the way
125  *    system linkers understand.
126  */
127
128 pub fn find_crate_name(sess: Option<&Session>,
129                        attrs: &[ast::Attribute],
130                        input: &Input) -> String {
131     let validate = |s: String, span: Option<Span>| {
132         creader::validate_crate_name(sess, &s[..], span);
133         s
134     };
135
136     // Look in attributes 100% of the time to make sure the attribute is marked
137     // as used. After doing this, however, we still prioritize a crate name from
138     // the command line over one found in the #[crate_name] attribute. If we
139     // find both we ensure that they're the same later on as well.
140     let attr_crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
141                                .and_then(|at| at.value_str().map(|s| (at, s)));
142
143     if let Some(sess) = sess {
144         if let Some(ref s) = sess.opts.crate_name {
145             if let Some((attr, ref name)) = attr_crate_name {
146                 if *s != &name[..] {
147                     let msg = format!("--crate-name and #[crate_name] are \
148                                        required to match, but `{}` != `{}`",
149                                       s, name);
150                     sess.span_err(attr.span, &msg[..]);
151                 }
152             }
153             return validate(s.clone(), None);
154         }
155     }
156
157     if let Some((attr, s)) = attr_crate_name {
158         return validate(s.to_string(), Some(attr.span));
159     }
160     if let Input::File(ref path) = *input {
161         if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
162             if s.starts_with("-") {
163                 let msg = format!("crate names cannot start with a `-`, but \
164                                    `{}` has a leading hyphen", s);
165                 if let Some(sess) = sess {
166                     sess.err(&msg);
167                 }
168             } else {
169                 return validate(s.replace("-", "_"), None);
170             }
171         }
172     }
173
174     "rust_out".to_string()
175 }
176
177 pub fn build_link_meta(sess: &Session, krate: &ast::Crate,
178                        name: String) -> LinkMeta {
179     let r = LinkMeta {
180         crate_name: name,
181         crate_hash: Svh::calculate(&sess.opts.cg.metadata, krate),
182     };
183     info!("{:?}", r);
184     return r;
185 }
186
187 fn truncated_hash_result(symbol_hasher: &mut Sha256) -> String {
188     let output = symbol_hasher.result_bytes();
189     // 64 bits should be enough to avoid collisions.
190     output[.. 8].to_hex().to_string()
191 }
192
193
194 // This calculates STH for a symbol, as defined above
195 fn symbol_hash<'tcx>(tcx: &ty::ctxt<'tcx>,
196                      symbol_hasher: &mut Sha256,
197                      t: Ty<'tcx>,
198                      link_meta: &LinkMeta)
199                      -> String {
200     // NB: do *not* use abbrevs here as we want the symbol names
201     // to be independent of one another in the crate.
202
203     symbol_hasher.reset();
204     symbol_hasher.input_str(&link_meta.crate_name);
205     symbol_hasher.input_str("-");
206     symbol_hasher.input_str(link_meta.crate_hash.as_str());
207     for meta in &*tcx.sess.crate_metadata.borrow() {
208         symbol_hasher.input_str(&meta[..]);
209     }
210     symbol_hasher.input_str("-");
211     symbol_hasher.input_str(&encoder::encoded_ty(tcx, t));
212     // Prefix with 'h' so that it never blends into adjacent digits
213     let mut hash = String::from_str("h");
214     hash.push_str(&truncated_hash_result(symbol_hasher));
215     hash
216 }
217
218 fn get_symbol_hash<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> String {
219     match ccx.type_hashcodes().borrow().get(&t) {
220         Some(h) => return h.to_string(),
221         None => {}
222     }
223
224     let mut symbol_hasher = ccx.symbol_hasher().borrow_mut();
225     let hash = symbol_hash(ccx.tcx(), &mut *symbol_hasher, t, ccx.link_meta());
226     ccx.type_hashcodes().borrow_mut().insert(t, hash.clone());
227     hash
228 }
229
230
231 // Name sanitation. LLVM will happily accept identifiers with weird names, but
232 // gas doesn't!
233 // gas accepts the following characters in symbols: a-z, A-Z, 0-9, ., _, $
234 pub fn sanitize(s: &str) -> String {
235     let mut result = String::new();
236     for c in s.chars() {
237         match c {
238             // Escape these with $ sequences
239             '@' => result.push_str("$SP$"),
240             '*' => result.push_str("$BP$"),
241             '&' => result.push_str("$RF$"),
242             '<' => result.push_str("$LT$"),
243             '>' => result.push_str("$GT$"),
244             '(' => result.push_str("$LP$"),
245             ')' => result.push_str("$RP$"),
246             ',' => result.push_str("$C$"),
247
248             // '.' doesn't occur in types and functions, so reuse it
249             // for ':' and '-'
250             '-' | ':' => result.push('.'),
251
252             // These are legal symbols
253             'a' ... 'z'
254             | 'A' ... 'Z'
255             | '0' ... '9'
256             | '_' | '.' | '$' => result.push(c),
257
258             _ => {
259                 result.push('$');
260                 for c in c.escape_unicode().skip(1) {
261                     match c {
262                         '{' => {},
263                         '}' => result.push('$'),
264                         c => result.push(c),
265                     }
266                 }
267             }
268         }
269     }
270
271     // Underscore-qualify anything that didn't start as an ident.
272     if !result.is_empty() &&
273         result.as_bytes()[0] != '_' as u8 &&
274         ! (result.as_bytes()[0] as char).is_xid_start() {
275         return format!("_{}", &result[..]);
276     }
277
278     return result;
279 }
280
281 pub fn mangle<PI: Iterator<Item=PathElem>>(path: PI,
282                                       hash: Option<&str>) -> String {
283     // Follow C++ namespace-mangling style, see
284     // http://en.wikipedia.org/wiki/Name_mangling for more info.
285     //
286     // It turns out that on OSX you can actually have arbitrary symbols in
287     // function names (at least when given to LLVM), but this is not possible
288     // when using unix's linker. Perhaps one day when we just use a linker from LLVM
289     // we won't need to do this name mangling. The problem with name mangling is
290     // that it seriously limits the available characters. For example we can't
291     // have things like &T or ~[T] in symbol names when one would theoretically
292     // want them for things like impls of traits on that type.
293     //
294     // To be able to work on all platforms and get *some* reasonable output, we
295     // use C++ name-mangling.
296
297     let mut n = String::from_str("_ZN"); // _Z == Begin name-sequence, N == nested
298
299     fn push(n: &mut String, s: &str) {
300         let sani = sanitize(s);
301         n.push_str(&format!("{}{}", sani.len(), sani));
302     }
303
304     // First, connect each component with <len, name> pairs.
305     for e in path {
306         push(&mut n, &token::get_name(e.name()))
307     }
308
309     match hash {
310         Some(s) => push(&mut n, s),
311         None => {}
312     }
313
314     n.push('E'); // End name-sequence.
315     n
316 }
317
318 pub fn exported_name(path: PathElems, hash: &str) -> String {
319     mangle(path, Some(hash))
320 }
321
322 pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathElems,
323                                       t: Ty<'tcx>, id: ast::NodeId) -> String {
324     let mut hash = get_symbol_hash(ccx, t);
325
326     // Paths can be completely identical for different nodes,
327     // e.g. `fn foo() { { fn a() {} } { fn a() {} } }`, so we
328     // generate unique characters from the node id. For now
329     // hopefully 3 characters is enough to avoid collisions.
330     const EXTRA_CHARS: &'static str =
331         "abcdefghijklmnopqrstuvwxyz\
332          ABCDEFGHIJKLMNOPQRSTUVWXYZ\
333          0123456789";
334     let id = id as usize;
335     let extra1 = id % EXTRA_CHARS.len();
336     let id = id / EXTRA_CHARS.len();
337     let extra2 = id % EXTRA_CHARS.len();
338     let id = id / EXTRA_CHARS.len();
339     let extra3 = id % EXTRA_CHARS.len();
340     hash.push(EXTRA_CHARS.as_bytes()[extra1] as char);
341     hash.push(EXTRA_CHARS.as_bytes()[extra2] as char);
342     hash.push(EXTRA_CHARS.as_bytes()[extra3] as char);
343
344     exported_name(path, &hash[..])
345 }
346
347 pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
348                                                       t: Ty<'tcx>,
349                                                       name: &str) -> String {
350     let s = ppaux::ty_to_string(ccx.tcx(), t);
351     let path = [PathName(token::intern(&s[..])),
352                 gensym_name(name)];
353     let hash = get_symbol_hash(ccx, t);
354     mangle(path.iter().cloned(), Some(&hash[..]))
355 }
356
357 pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
358     mangle(path.chain(Some(gensym_name(flav)).into_iter()), None)
359 }
360
361 pub fn get_cc_prog(sess: &Session) -> String {
362     match sess.opts.cg.linker {
363         Some(ref linker) => return linker.to_string(),
364         None => sess.target.target.options.linker.clone(),
365     }
366 }
367
368 pub fn remove(sess: &Session, path: &Path) {
369     match fs::remove_file(path) {
370         Ok(..) => {}
371         Err(e) => {
372             sess.err(&format!("failed to remove {}: {}",
373                              path.display(),
374                              e));
375         }
376     }
377 }
378
379 /// Perform the linkage portion of the compilation phase. This will generate all
380 /// of the requested outputs for this compilation session.
381 pub fn link_binary(sess: &Session,
382                    trans: &CrateTranslation,
383                    outputs: &OutputFilenames,
384                    crate_name: &str) -> Vec<PathBuf> {
385     let mut out_filenames = Vec::new();
386     for &crate_type in &*sess.crate_types.borrow() {
387         if invalid_output_for_target(sess, crate_type) {
388             sess.bug(&format!("invalid output type `{:?}` for target os `{}`",
389                              crate_type, sess.opts.target_triple));
390         }
391         let out_file = link_binary_output(sess, trans, crate_type, outputs,
392                                           crate_name);
393         out_filenames.push(out_file);
394     }
395
396     // Remove the temporary object file and metadata if we aren't saving temps
397     if !sess.opts.cg.save_temps {
398         let obj_filename = outputs.temp_path(OutputTypeObject);
399         if !sess.opts.output_types.contains(&OutputTypeObject) {
400             remove(sess, &obj_filename);
401         }
402         remove(sess, &obj_filename.with_extension("metadata.o"));
403     }
404
405     out_filenames
406 }
407
408
409 /// Returns default crate type for target
410 ///
411 /// Default crate type is used when crate type isn't provided neither
412 /// through cmd line arguments nor through crate attributes
413 ///
414 /// It is CrateTypeExecutable for all platforms but iOS as there is no
415 /// way to run iOS binaries anyway without jailbreaking and
416 /// interaction with Rust code through static library is the only
417 /// option for now
418 pub fn default_output_for_target(sess: &Session) -> config::CrateType {
419     if !sess.target.target.options.executables {
420         config::CrateTypeStaticlib
421     } else {
422         config::CrateTypeExecutable
423     }
424 }
425
426 /// Checks if target supports crate_type as output
427 pub fn invalid_output_for_target(sess: &Session,
428                                  crate_type: config::CrateType) -> bool {
429     match (sess.target.target.options.dynamic_linking,
430            sess.target.target.options.executables, crate_type) {
431         (false, _, config::CrateTypeDylib) => true,
432         (_, false, config::CrateTypeExecutable) => true,
433         _ => false
434     }
435 }
436
437 fn is_writeable(p: &Path) -> bool {
438     match p.metadata() {
439         Err(..) => true,
440         Ok(m) => !m.permissions().readonly()
441     }
442 }
443
444 pub fn filename_for_input(sess: &Session,
445                           crate_type: config::CrateType,
446                           name: &str,
447                           out_filename: &Path) -> PathBuf {
448     let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
449     match crate_type {
450         config::CrateTypeRlib => {
451             out_filename.with_file_name(&format!("lib{}.rlib", libname))
452         }
453         config::CrateTypeDylib => {
454             let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
455                                     &sess.target.target.options.dll_suffix);
456             out_filename.with_file_name(&format!("{}{}{}",
457                                                   prefix,
458                                                  libname,
459                                                  suffix))
460         }
461         config::CrateTypeStaticlib => {
462             out_filename.with_file_name(&format!("lib{}.a", libname))
463         }
464         config::CrateTypeExecutable => {
465             let suffix = &sess.target.target.options.exe_suffix;
466             if suffix.is_empty() {
467                 out_filename.to_path_buf()
468             } else {
469                 out_filename.with_extension(&suffix[1..])
470             }
471         }
472     }
473 }
474
475 fn link_binary_output(sess: &Session,
476                       trans: &CrateTranslation,
477                       crate_type: config::CrateType,
478                       outputs: &OutputFilenames,
479                       crate_name: &str) -> PathBuf {
480     let obj_filename = outputs.temp_path(OutputTypeObject);
481     let out_filename = match outputs.single_output_file {
482         Some(ref file) => file.clone(),
483         None => {
484             let out_filename = outputs.path(OutputTypeExe);
485             filename_for_input(sess, crate_type, crate_name, &out_filename)
486         }
487     };
488
489     // Make sure the output and obj_filename are both writeable.
490     // Mac, FreeBSD, and Windows system linkers check this already --
491     // however, the Linux linker will happily overwrite a read-only file.
492     // We should be consistent.
493     let obj_is_writeable = is_writeable(&obj_filename);
494     let out_is_writeable = is_writeable(&out_filename);
495     if !out_is_writeable {
496         sess.fatal(&format!("output file {} is not writeable -- check its \
497                             permissions.",
498                            out_filename.display()));
499     }
500     else if !obj_is_writeable {
501         sess.fatal(&format!("object file {} is not writeable -- check its \
502                             permissions.",
503                            obj_filename.display()));
504     }
505
506     match crate_type {
507         config::CrateTypeRlib => {
508             link_rlib(sess, Some(trans), &obj_filename, &out_filename).build();
509         }
510         config::CrateTypeStaticlib => {
511             link_staticlib(sess, &obj_filename, &out_filename);
512         }
513         config::CrateTypeExecutable => {
514             link_natively(sess, trans, false, &obj_filename, &out_filename);
515         }
516         config::CrateTypeDylib => {
517             link_natively(sess, trans, true, &obj_filename, &out_filename);
518         }
519     }
520
521     out_filename
522 }
523
524 fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
525     let mut search = Vec::new();
526     sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
527         search.push(path.to_path_buf());
528         FileDoesntMatch
529     });
530     return search;
531 }
532
533 // Create an 'rlib'
534 //
535 // An rlib in its current incarnation is essentially a renamed .a file. The
536 // rlib primarily contains the object file of the crate, but it also contains
537 // all of the object files from native libraries. This is done by unzipping
538 // native libraries and inserting all of the contents into this archive.
539 fn link_rlib<'a>(sess: &'a Session,
540                  trans: Option<&CrateTranslation>, // None == no metadata/bytecode
541                  obj_filename: &Path,
542                  out_filename: &Path) -> ArchiveBuilder<'a> {
543     let handler = &sess.diagnostic().handler;
544     let config = ArchiveConfig {
545         handler: handler,
546         dst: out_filename.to_path_buf(),
547         lib_search_paths: archive_search_paths(sess),
548         slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
549         slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
550         maybe_ar_prog: sess.opts.cg.ar.clone()
551     };
552     let mut ab = ArchiveBuilder::create(config);
553     ab.add_file(obj_filename).unwrap();
554
555     for &(ref l, kind) in &*sess.cstore.get_used_libraries().borrow() {
556         match kind {
557             cstore::NativeStatic => {
558                 ab.add_native_library(&l[..]).unwrap();
559             }
560             cstore::NativeFramework | cstore::NativeUnknown => {}
561         }
562     }
563
564     // After adding all files to the archive, we need to update the
565     // symbol table of the archive.
566     ab.update_symbols();
567
568     let mut ab = match sess.target.target.options.is_like_osx {
569         // For OSX/iOS, we must be careful to update symbols only when adding
570         // object files.  We're about to start adding non-object files, so run
571         // `ar` now to process the object files.
572         true => ab.build().extend(),
573         false => ab,
574     };
575
576     // Note that it is important that we add all of our non-object "magical
577     // files" *after* all of the object files in the archive. The reason for
578     // this is as follows:
579     //
580     // * When performing LTO, this archive will be modified to remove
581     //   obj_filename from above. The reason for this is described below.
582     //
583     // * When the system linker looks at an archive, it will attempt to
584     //   determine the architecture of the archive in order to see whether its
585     //   linkable.
586     //
587     //   The algorithm for this detection is: iterate over the files in the
588     //   archive. Skip magical SYMDEF names. Interpret the first file as an
589     //   object file. Read architecture from the object file.
590     //
591     // * As one can probably see, if "metadata" and "foo.bc" were placed
592     //   before all of the objects, then the architecture of this archive would
593     //   not be correctly inferred once 'foo.o' is removed.
594     //
595     // Basically, all this means is that this code should not move above the
596     // code above.
597     match trans {
598         Some(trans) => {
599             // Instead of putting the metadata in an object file section, rlibs
600             // contain the metadata in a separate file. We use a temp directory
601             // here so concurrent builds in the same directory don't try to use
602             // the same filename for metadata (stomping over one another)
603             let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
604             let metadata = tmpdir.path().join(METADATA_FILENAME);
605             match fs::File::create(&metadata).and_then(|mut f| {
606                 f.write_all(&trans.metadata)
607             }) {
608                 Ok(..) => {}
609                 Err(e) => {
610                     sess.err(&format!("failed to write {}: {}",
611                                      metadata.display(),
612                                      e));
613                     sess.abort_if_errors();
614                 }
615             }
616             ab.add_file(&metadata).unwrap();
617             remove(sess, &metadata);
618
619             // For LTO purposes, the bytecode of this library is also inserted
620             // into the archive.  If codegen_units > 1, we insert each of the
621             // bitcode files.
622             for i in 0..sess.opts.cg.codegen_units {
623                 // Note that we make sure that the bytecode filename in the
624                 // archive is never exactly 16 bytes long by adding a 16 byte
625                 // extension to it. This is to work around a bug in LLDB that
626                 // would cause it to crash if the name of a file in an archive
627                 // was exactly 16 bytes.
628                 let bc_filename = obj_filename.with_extension(&format!("{}.bc", i));
629                 let bc_deflated_filename = obj_filename.with_extension(
630                     &format!("{}.bytecode.deflate", i));
631
632                 let mut bc_data = Vec::new();
633                 match fs::File::open(&bc_filename).and_then(|mut f| {
634                     f.read_to_end(&mut bc_data)
635                 }) {
636                     Ok(..) => {}
637                     Err(e) => sess.fatal(&format!("failed to read bytecode: {}",
638                                                  e))
639                 }
640
641                 let bc_data_deflated = flate::deflate_bytes(&bc_data[..]);
642
643                 let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
644                     Ok(file) => file,
645                     Err(e) => {
646                         sess.fatal(&format!("failed to create compressed \
647                                              bytecode file: {}", e))
648                     }
649                 };
650
651                 match write_rlib_bytecode_object_v1(&mut bc_file_deflated,
652                                                     &bc_data_deflated) {
653                     Ok(()) => {}
654                     Err(e) => {
655                         sess.err(&format!("failed to write compressed bytecode: \
656                                           {}", e));
657                         sess.abort_if_errors()
658                     }
659                 };
660
661                 ab.add_file(&bc_deflated_filename).unwrap();
662                 remove(sess, &bc_deflated_filename);
663
664                 // See the bottom of back::write::run_passes for an explanation
665                 // of when we do and don't keep .0.bc files around.
666                 let user_wants_numbered_bitcode =
667                         sess.opts.output_types.contains(&OutputTypeBitcode) &&
668                         sess.opts.cg.codegen_units > 1;
669                 if !sess.opts.cg.save_temps && !user_wants_numbered_bitcode {
670                     remove(sess, &bc_filename);
671                 }
672             }
673
674             // After adding all files to the archive, we need to update the
675             // symbol table of the archive. This currently dies on OSX (see
676             // #11162), and isn't necessary there anyway
677             if !sess.target.target.options.is_like_osx {
678                 ab.update_symbols();
679             }
680         }
681
682         None => {}
683     }
684
685     ab
686 }
687
688 fn write_rlib_bytecode_object_v1(writer: &mut Write,
689                                  bc_data_deflated: &[u8]) -> io::Result<()> {
690     let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64;
691
692     try!(writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC));
693     try!(writer.write_all(&[1, 0, 0, 0]));
694     try!(writer.write_all(&[
695         (bc_data_deflated_size >>  0) as u8,
696         (bc_data_deflated_size >>  8) as u8,
697         (bc_data_deflated_size >> 16) as u8,
698         (bc_data_deflated_size >> 24) as u8,
699         (bc_data_deflated_size >> 32) as u8,
700         (bc_data_deflated_size >> 40) as u8,
701         (bc_data_deflated_size >> 48) as u8,
702         (bc_data_deflated_size >> 56) as u8,
703     ]));
704     try!(writer.write_all(&bc_data_deflated));
705
706     let number_of_bytes_written_so_far =
707         RLIB_BYTECODE_OBJECT_MAGIC.len() +                // magic id
708         mem::size_of_val(&RLIB_BYTECODE_OBJECT_VERSION) + // version
709         mem::size_of_val(&bc_data_deflated_size) +        // data size field
710         bc_data_deflated_size as usize;                    // actual data
711
712     // If the number of bytes written to the object so far is odd, add a
713     // padding byte to make it even. This works around a crash bug in LLDB
714     // (see issue #15950)
715     if number_of_bytes_written_so_far % 2 == 1 {
716         try!(writer.write_all(&[0]));
717     }
718
719     return Ok(());
720 }
721
722 // Create a static archive
723 //
724 // This is essentially the same thing as an rlib, but it also involves adding
725 // all of the upstream crates' objects into the archive. This will slurp in
726 // all of the native libraries of upstream dependencies as well.
727 //
728 // Additionally, there's no way for us to link dynamic libraries, so we warn
729 // about all dynamic library dependencies that they're not linked in.
730 //
731 // There's no need to include metadata in a static archive, so ensure to not
732 // link in the metadata object file (and also don't prepare the archive with a
733 // metadata file).
734 fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
735     let ab = link_rlib(sess, None, obj_filename, out_filename);
736     let mut ab = match sess.target.target.options.is_like_osx {
737         true => ab.build().extend(),
738         false => ab,
739     };
740     if sess.target.target.options.morestack {
741         ab.add_native_library("morestack").unwrap();
742     }
743     if !sess.target.target.options.no_compiler_rt {
744         ab.add_native_library("compiler-rt").unwrap();
745     }
746
747     let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
748     let mut all_native_libs = vec![];
749
750     for &(cnum, ref path) in &crates {
751         let ref name = sess.cstore.get_crate_data(cnum).name;
752         let p = match *path {
753             Some(ref p) => p.clone(), None => {
754                 sess.err(&format!("could not find rlib for: `{}`",
755                                  name));
756                 continue
757             }
758         };
759         ab.add_rlib(&p, &name[..], sess.lto()).unwrap();
760
761         let native_libs = csearch::get_native_libraries(&sess.cstore, cnum);
762         all_native_libs.extend(native_libs.into_iter());
763     }
764
765     ab.update_symbols();
766     let _ = ab.build();
767
768     if !all_native_libs.is_empty() {
769         sess.note("link against the following native artifacts when linking against \
770                   this static library");
771         sess.note("the order and any duplication can be significant on some platforms, \
772                   and so may need to be preserved");
773     }
774
775     for &(kind, ref lib) in &all_native_libs {
776         let name = match kind {
777             cstore::NativeStatic => "static library",
778             cstore::NativeUnknown => "library",
779             cstore::NativeFramework => "framework",
780         };
781         sess.note(&format!("{}: {}", name, *lib));
782     }
783 }
784
785 // Create a dynamic library or executable
786 //
787 // This will invoke the system linker/cc to create the resulting file. This
788 // links to all upstream files as well.
789 fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
790                  obj_filename: &Path, out_filename: &Path) {
791     let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
792
793     // The invocations of cc share some flags across platforms
794     let pname = get_cc_prog(sess);
795     let mut cmd = Command::new(&pname[..]);
796
797     let root = sess.target_filesearch(PathKind::Native).get_lib_path();
798     cmd.args(&sess.target.target.options.pre_link_args);
799     for obj in &sess.target.target.options.pre_link_objects {
800         cmd.arg(root.join(obj));
801     }
802
803     link_args(&mut cmd, sess, dylib, tmpdir.path(),
804               trans, obj_filename, out_filename);
805     if !sess.target.target.options.no_compiler_rt {
806         cmd.arg("-lcompiler-rt");
807     }
808     for obj in &sess.target.target.options.post_link_objects {
809         cmd.arg(root.join(obj));
810     }
811     cmd.args(&sess.target.target.options.post_link_args);
812
813     if sess.opts.debugging_opts.print_link_args {
814         println!("{:?}", &cmd);
815     }
816
817     // May have not found libraries in the right formats.
818     sess.abort_if_errors();
819
820     // Invoke the system linker
821     debug!("{:?}", &cmd);
822     let prog = time(sess.time_passes(), "running linker", (), |()| cmd.output());
823     match prog {
824         Ok(prog) => {
825             if !prog.status.success() {
826                 sess.err(&format!("linking with `{}` failed: {}",
827                                  pname,
828                                  prog.status));
829                 sess.note(&format!("{:?}", &cmd));
830                 let mut output = prog.stderr.clone();
831                 output.push_all(&prog.stdout);
832                 sess.note(str::from_utf8(&output[..]).unwrap());
833                 sess.abort_if_errors();
834             }
835             debug!("linker stderr:\n{}", String::from_utf8(prog.stderr).unwrap());
836             debug!("linker stdout:\n{}", String::from_utf8(prog.stdout).unwrap());
837         },
838         Err(e) => {
839             sess.err(&format!("could not exec the linker `{}`: {}",
840                              pname,
841                              e));
842             sess.abort_if_errors();
843         }
844     }
845
846
847     // On OSX, debuggers need this utility to get run to do some munging of
848     // the symbols
849     if sess.target.target.options.is_like_osx && sess.opts.debuginfo != NoDebugInfo {
850         match Command::new("dsymutil").arg(out_filename).output() {
851             Ok(..) => {}
852             Err(e) => {
853                 sess.err(&format!("failed to run dsymutil: {}", e));
854                 sess.abort_if_errors();
855             }
856         }
857     }
858 }
859
860 fn link_args(cmd: &mut Command,
861              sess: &Session,
862              dylib: bool,
863              tmpdir: &Path,
864              trans: &CrateTranslation,
865              obj_filename: &Path,
866              out_filename: &Path) {
867
868     // The default library location, we need this to find the runtime.
869     // The location of crates will be determined as needed.
870     let lib_path = sess.target_filesearch(PathKind::All).get_lib_path();
871
872     // target descriptor
873     let t = &sess.target.target;
874
875     cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(&lib_path));
876
877     cmd.arg("-o").arg(out_filename).arg(obj_filename);
878
879
880     // Stack growth requires statically linking a __morestack function. Note
881     // that this is listed *before* all other libraries. Due to the usage of the
882     // --as-needed flag below, the standard library may only be useful for its
883     // rust_stack_exhausted function. In this case, we must ensure that the
884     // libmorestack.a file appears *before* the standard library (so we put it
885     // at the very front).
886     //
887     // Most of the time this is sufficient, except for when LLVM gets super
888     // clever. If, for example, we have a main function `fn main() {}`, LLVM
889     // will optimize out calls to `__morestack` entirely because the function
890     // doesn't need any stack at all!
891     //
892     // To get around this snag, we specially tell the linker to always include
893     // all contents of this library. This way we're guaranteed that the linker
894     // will include the __morestack symbol 100% of the time, always resolving
895     // references to it even if the object above didn't use it.
896     if t.options.morestack {
897         if t.options.is_like_osx {
898             let morestack = lib_path.join("libmorestack.a");
899
900             let mut v = OsString::from("-Wl,-force_load,");
901             v.push(&morestack);
902             cmd.arg(&v);
903         } else {
904             cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
905         }
906     }
907
908     // When linking a dynamic library, we put the metadata into a section of the
909     // executable. This metadata is in a separate object file from the main
910     // object file, so we link that in here.
911     if dylib {
912         cmd.arg(&obj_filename.with_extension("metadata.o"));
913     }
914
915     if t.options.is_like_osx {
916         // The dead_strip option to the linker specifies that functions and data
917         // unreachable by the entry point will be removed. This is quite useful
918         // with Rust's compilation model of compiling libraries at a time into
919         // one object file. For example, this brings hello world from 1.7MB to
920         // 458K.
921         //
922         // Note that this is done for both executables and dynamic libraries. We
923         // won't get much benefit from dylibs because LLVM will have already
924         // stripped away as much as it could. This has not been seen to impact
925         // link times negatively.
926         //
927         // -dead_strip can't be part of the pre_link_args because it's also used
928         // for partial linking when using multiple codegen units (-r). So we
929         // insert it here.
930         cmd.arg("-Wl,-dead_strip");
931     }
932
933     // If we're building a dylib, we don't use --gc-sections because LLVM has
934     // already done the best it can do, and we also don't want to eliminate the
935     // metadata. If we're building an executable, however, --gc-sections drops
936     // the size of hello world from 1.8MB to 597K, a 67% reduction.
937     if !dylib && !t.options.is_like_osx {
938         cmd.arg("-Wl,--gc-sections");
939     }
940
941     let used_link_args = sess.cstore.get_used_link_args().borrow();
942
943     if t.options.position_independent_executables {
944         let empty_vec = Vec::new();
945         let empty_str = String::new();
946         let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
947         let mut args = args.iter().chain(used_link_args.iter());
948         if !dylib
949             && (t.options.relocation_model == "pic"
950                 || *sess.opts.cg.relocation_model.as_ref()
951                    .unwrap_or(&empty_str) == "pic")
952             && !args.any(|x| *x == "-static") {
953             cmd.arg("-pie");
954         }
955     }
956
957     if t.options.linker_is_gnu {
958         // GNU-style linkers support optimization with -O. GNU ld doesn't need a
959         // numeric argument, but other linkers do.
960         if sess.opts.optimize == config::Default ||
961            sess.opts.optimize == config::Aggressive {
962             cmd.arg("-Wl,-O1");
963         }
964     }
965
966     // We want to prevent the compiler from accidentally leaking in any system
967     // libraries, so we explicitly ask gcc to not link to any libraries by
968     // default. Note that this does not happen for windows because windows pulls
969     // in some large number of libraries and I couldn't quite figure out which
970     // subset we wanted.
971     if !t.options.is_like_windows {
972         cmd.arg("-nodefaultlibs");
973     }
974
975     // Mark all dynamic libraries and executables as compatible with ASLR
976     // FIXME #17098: ASLR breaks gdb
977     if t.options.is_like_windows && sess.opts.debuginfo == NoDebugInfo {
978         // cmd.arg("-Wl,--dynamicbase");
979     }
980
981     // Take careful note of the ordering of the arguments we pass to the linker
982     // here. Linkers will assume that things on the left depend on things to the
983     // right. Things on the right cannot depend on things on the left. This is
984     // all formally implemented in terms of resolving symbols (libs on the right
985     // resolve unknown symbols of libs on the left, but not vice versa).
986     //
987     // For this reason, we have organized the arguments we pass to the linker as
988     // such:
989     //
990     //  1. The local object that LLVM just generated
991     //  2. Upstream rust libraries
992     //  3. Local native libraries
993     //  4. Upstream native libraries
994     //
995     // This is generally fairly natural, but some may expect 2 and 3 to be
996     // swapped. The reason that all native libraries are put last is that it's
997     // not recommended for a native library to depend on a symbol from a rust
998     // crate. If this is the case then a staticlib crate is recommended, solving
999     // the problem.
1000     //
1001     // Additionally, it is occasionally the case that upstream rust libraries
1002     // depend on a local native library. In the case of libraries such as
1003     // lua/glfw/etc the name of the library isn't the same across all platforms,
1004     // so only the consumer crate of a library knows the actual name. This means
1005     // that downstream crates will provide the #[link] attribute which upstream
1006     // crates will depend on. Hence local native libraries are after out
1007     // upstream rust crates.
1008     //
1009     // In theory this means that a symbol in an upstream native library will be
1010     // shadowed by a local native library when it wouldn't have been before, but
1011     // this kind of behavior is pretty platform specific and generally not
1012     // recommended anyway, so I don't think we're shooting ourself in the foot
1013     // much with that.
1014     add_upstream_rust_crates(cmd, sess, dylib, tmpdir, trans);
1015     add_local_native_libraries(cmd, sess);
1016     add_upstream_native_libraries(cmd, sess);
1017
1018     // # Telling the linker what we're doing
1019
1020     if dylib {
1021         // On mac we need to tell the linker to let this library be rpathed
1022         if sess.target.target.options.is_like_osx {
1023             cmd.args(&["-dynamiclib", "-Wl,-dylib"]);
1024
1025             if sess.opts.cg.rpath {
1026                 let mut v = OsString::from("-Wl,-install_name,@rpath/");
1027                 v.push(out_filename.file_name().unwrap());
1028                 cmd.arg(&v);
1029             }
1030         } else {
1031             cmd.arg("-shared");
1032         }
1033     }
1034
1035     // FIXME (#2397): At some point we want to rpath our guesses as to
1036     // where extern libraries might live, based on the
1037     // addl_lib_search_paths
1038     if sess.opts.cg.rpath {
1039         let sysroot = sess.sysroot();
1040         let target_triple = &sess.opts.target_triple;
1041         let mut get_install_prefix_lib_path = || {
1042             let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
1043             let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
1044             let mut path = PathBuf::from(install_prefix);
1045             path.push(&tlib);
1046
1047             path
1048         };
1049         let mut rpath_config = RPathConfig {
1050             used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
1051             out_filename: out_filename.to_path_buf(),
1052             has_rpath: sess.target.target.options.has_rpath,
1053             is_like_osx: sess.target.target.options.is_like_osx,
1054             get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
1055         };
1056         cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
1057     }
1058
1059     // Finally add all the linker arguments provided on the command line along
1060     // with any #[link_args] attributes found inside the crate
1061     let empty = Vec::new();
1062     cmd.args(&sess.opts.cg.link_args.as_ref().unwrap_or(&empty));
1063     cmd.args(&used_link_args[..]);
1064 }
1065
1066 // # Native library linking
1067 //
1068 // User-supplied library search paths (-L on the command line). These are
1069 // the same paths used to find Rust crates, so some of them may have been
1070 // added already by the previous crate linking code. This only allows them
1071 // to be found at compile time so it is still entirely up to outside
1072 // forces to make sure that library can be found at runtime.
1073 //
1074 // Also note that the native libraries linked here are only the ones located
1075 // in the current crate. Upstream crates with native library dependencies
1076 // may have their native library pulled in above.
1077 fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
1078     sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
1079         match k {
1080             PathKind::Framework => { cmd.arg("-F").arg(path); }
1081             _ => { cmd.arg("-L").arg(path); }
1082         }
1083         FileDoesntMatch
1084     });
1085
1086     // Some platforms take hints about whether a library is static or dynamic.
1087     // For those that support this, we ensure we pass the option if the library
1088     // was flagged "static" (most defaults are dynamic) to ensure that if
1089     // libfoo.a and libfoo.so both exist that the right one is chosen.
1090     let takes_hints = !sess.target.target.options.is_like_osx;
1091
1092     let libs = sess.cstore.get_used_libraries();
1093     let libs = libs.borrow();
1094
1095     let staticlibs = libs.iter().filter_map(|&(ref l, kind)| {
1096         if kind == cstore::NativeStatic {Some(l)} else {None}
1097     });
1098     let others = libs.iter().filter(|&&(_, kind)| {
1099         kind != cstore::NativeStatic
1100     });
1101
1102     // Platforms that take hints generally also support the --whole-archive
1103     // flag. We need to pass this flag when linking static native libraries to
1104     // ensure the entire library is included.
1105     //
1106     // For more details see #15460, but the gist is that the linker will strip
1107     // away any unused objects in the archive if we don't otherwise explicitly
1108     // reference them. This can occur for libraries which are just providing
1109     // bindings, libraries with generic functions, etc.
1110     if takes_hints {
1111         cmd.arg("-Wl,--whole-archive").arg("-Wl,-Bstatic");
1112     }
1113     let search_path = archive_search_paths(sess);
1114     for l in staticlibs {
1115         if takes_hints {
1116             cmd.arg(&format!("-l{}", l));
1117         } else {
1118             // -force_load is the OSX equivalent of --whole-archive, but it
1119             // involves passing the full path to the library to link.
1120             let lib = archive::find_library(&l[..],
1121                                             &sess.target.target.options.staticlib_prefix,
1122                                             &sess.target.target.options.staticlib_suffix,
1123                                             &search_path[..],
1124                                             &sess.diagnostic().handler);
1125             let mut v = OsString::from("-Wl,-force_load,");
1126             v.push(&lib);
1127             cmd.arg(&v);
1128         }
1129     }
1130     if takes_hints {
1131         cmd.arg("-Wl,--no-whole-archive").arg("-Wl,-Bdynamic");
1132     }
1133
1134     for &(ref l, kind) in others {
1135         match kind {
1136             cstore::NativeUnknown => {
1137                 cmd.arg(&format!("-l{}", l));
1138             }
1139             cstore::NativeFramework => {
1140                 cmd.arg("-framework").arg(&l[..]);
1141             }
1142             cstore::NativeStatic => unreachable!(),
1143         }
1144     }
1145 }
1146
1147 // # Rust Crate linking
1148 //
1149 // Rust crates are not considered at all when creating an rlib output. All
1150 // dependencies will be linked when producing the final output (instead of
1151 // the intermediate rlib version)
1152 fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
1153                             dylib: bool, tmpdir: &Path,
1154                             trans: &CrateTranslation) {
1155     // All of the heavy lifting has previously been accomplished by the
1156     // dependency_format module of the compiler. This is just crawling the
1157     // output of that module, adding crates as necessary.
1158     //
1159     // Linking to a rlib involves just passing it to the linker (the linker
1160     // will slurp up the object files inside), and linking to a dynamic library
1161     // involves just passing the right -l flag.
1162
1163     let data = if dylib {
1164         trans.crate_formats.get(&config::CrateTypeDylib).unwrap()
1165     } else {
1166         trans.crate_formats.get(&config::CrateTypeExecutable).unwrap()
1167     };
1168
1169     // Invoke get_used_crates to ensure that we get a topological sorting of
1170     // crates.
1171     let deps = sess.cstore.get_used_crates(cstore::RequireDynamic);
1172
1173     for &(cnum, _) in &deps {
1174         // We may not pass all crates through to the linker. Some crates may
1175         // appear statically in an existing dylib, meaning we'll pick up all the
1176         // symbols from the dylib.
1177         let kind = match data[cnum as usize - 1] {
1178             Some(t) => t,
1179             None => continue
1180         };
1181         let src = sess.cstore.get_used_crate_source(cnum).unwrap();
1182         match kind {
1183             cstore::RequireDynamic => {
1184                 add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
1185             }
1186             cstore::RequireStatic => {
1187                 add_static_crate(cmd, sess, tmpdir, &src.rlib.unwrap().0)
1188             }
1189         }
1190
1191     }
1192
1193     // Converts a library file-stem into a cc -l argument
1194     fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
1195         if stem.starts_with("lib") && !config.target.options.is_like_windows {
1196             &stem[3..]
1197         } else {
1198             stem
1199         }
1200     }
1201
1202     // Adds the static "rlib" versions of all crates to the command line.
1203     fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
1204                         cratepath: &Path) {
1205         // When performing LTO on an executable output, all of the
1206         // bytecode from the upstream libraries has already been
1207         // included in our object file output. We need to modify all of
1208         // the upstream archives to remove their corresponding object
1209         // file to make sure we don't pull the same code in twice.
1210         //
1211         // We must continue to link to the upstream archives to be sure
1212         // to pull in native static dependencies. As the final caveat,
1213         // on Linux it is apparently illegal to link to a blank archive,
1214         // so if an archive no longer has any object files in it after
1215         // we remove `lib.o`, then don't link against it at all.
1216         //
1217         // If we're not doing LTO, then our job is simply to just link
1218         // against the archive.
1219         if sess.lto() {
1220             let name = cratepath.file_name().unwrap().to_str().unwrap();
1221             let name = &name[3..name.len() - 5]; // chop off lib/.rlib
1222             time(sess.time_passes(),
1223                  &format!("altering {}.rlib", name),
1224                  (), |()| {
1225                 let dst = tmpdir.join(cratepath.file_name().unwrap());
1226                 match fs::copy(&cratepath, &dst) {
1227                     Ok(..) => {}
1228                     Err(e) => {
1229                         sess.err(&format!("failed to copy {} to {}: {}",
1230                                          cratepath.display(),
1231                                          dst.display(),
1232                                          e));
1233                         sess.abort_if_errors();
1234                     }
1235                 }
1236                 // Fix up permissions of the copy, as fs::copy() preserves
1237                 // permissions, but the original file may have been installed
1238                 // by a package manager and may be read-only.
1239                 match fs::metadata(&dst).and_then(|m| {
1240                     let mut perms = m.permissions();
1241                     perms.set_readonly(false);
1242                     fs::set_permissions(&dst, perms)
1243                 }) {
1244                     Ok(..) => {}
1245                     Err(e) => {
1246                         sess.err(&format!("failed to chmod {} when preparing \
1247                                           for LTO: {}", dst.display(),
1248                                          e));
1249                         sess.abort_if_errors();
1250                     }
1251                 }
1252                 let handler = &sess.diagnostic().handler;
1253                 let config = ArchiveConfig {
1254                     handler: handler,
1255                     dst: dst.clone(),
1256                     lib_search_paths: archive_search_paths(sess),
1257                     slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
1258                     slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
1259                     maybe_ar_prog: sess.opts.cg.ar.clone()
1260                 };
1261                 let mut archive = Archive::open(config);
1262                 archive.remove_file(&format!("{}.o", name));
1263                 let files = archive.files();
1264                 if files.iter().any(|s| s.ends_with(".o")) {
1265                     cmd.arg(&dst);
1266                 }
1267             });
1268         } else {
1269             cmd.arg(&fix_windows_verbatim_for_gcc(cratepath));
1270         }
1271     }
1272
1273     // Same thing as above, but for dynamic crates instead of static crates.
1274     fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: &Path) {
1275         // If we're performing LTO, then it should have been previously required
1276         // that all upstream rust dependencies were available in an rlib format.
1277         assert!(!sess.lto());
1278
1279         // Just need to tell the linker about where the library lives and
1280         // what its name is
1281         if let Some(dir) = cratepath.parent() {
1282             cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(dir));
1283         }
1284         let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
1285         cmd.arg(&format!("-l{}", unlib(&sess.target, filestem)));
1286     }
1287 }
1288
1289 // Link in all of our upstream crates' native dependencies. Remember that
1290 // all of these upstream native dependencies are all non-static
1291 // dependencies. We've got two cases then:
1292 //
1293 // 1. The upstream crate is an rlib. In this case we *must* link in the
1294 // native dependency because the rlib is just an archive.
1295 //
1296 // 2. The upstream crate is a dylib. In order to use the dylib, we have to
1297 // have the dependency present on the system somewhere. Thus, we don't
1298 // gain a whole lot from not linking in the dynamic dependency to this
1299 // crate as well.
1300 //
1301 // The use case for this is a little subtle. In theory the native
1302 // dependencies of a crate are purely an implementation detail of the crate
1303 // itself, but the problem arises with generic and inlined functions. If a
1304 // generic function calls a native function, then the generic function must
1305 // be instantiated in the target crate, meaning that the native symbol must
1306 // also be resolved in the target crate.
1307 fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
1308     // Be sure to use a topological sorting of crates because there may be
1309     // interdependencies between native libraries. When passing -nodefaultlibs,
1310     // for example, almost all native libraries depend on libc, so we have to
1311     // make sure that's all the way at the right (liblibc is near the base of
1312     // the dependency chain).
1313     //
1314     // This passes RequireStatic, but the actual requirement doesn't matter,
1315     // we're just getting an ordering of crate numbers, we're not worried about
1316     // the paths.
1317     let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
1318     for (cnum, _) in crates {
1319         let libs = csearch::get_native_libraries(&sess.cstore, cnum);
1320         for &(kind, ref lib) in &libs {
1321             match kind {
1322                 cstore::NativeUnknown => {
1323                     cmd.arg(&format!("-l{}", *lib));
1324                 }
1325                 cstore::NativeFramework => {
1326                     cmd.arg("-framework");
1327                     cmd.arg(&lib[..]);
1328                 }
1329                 cstore::NativeStatic => {
1330                     sess.bug("statics shouldn't be propagated");
1331                 }
1332             }
1333         }
1334     }
1335 }
1336
1337 // Unfortunately, on windows, gcc cannot accept paths of the form `\\?\C:\...`
1338 // (a verbatim path). This form of path is generally pretty rare, but the
1339 // implementation of `fs::canonicalize` currently generates paths of this form,
1340 // meaning that we're going to be passing quite a few of these down to gcc.
1341 //
1342 // For now we just strip the "verbatim prefix" of `\\?\` from the path. This
1343 // will probably lose information in some cases, but there's not a whole lot
1344 // more we can do with a buggy gcc...
1345 fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
1346     if !cfg!(windows) {
1347         return p.to_path_buf()
1348     }
1349     let mut components = p.components();
1350     let prefix = match components.next() {
1351         Some(path::Component::Prefix(p)) => p,
1352         _ => return p.to_path_buf(),
1353     };
1354     let disk = match prefix.kind() {
1355         path::Prefix::VerbatimDisk(disk) => disk,
1356         _ => return p.to_path_buf(),
1357     };
1358     let mut base = OsString::from(format!("{}:", disk as char));
1359     base.push(components.as_path());
1360     PathBuf::from(base)
1361 }