]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/back/link.rs
rustc_trans: Clean up some style in back::link
[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::linker::{Linker, GnuLinker};
13 use super::rpath::RPathConfig;
14 use super::rpath;
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 util::fs::fix_windows_verbatim_for_gcc;
30 use rustc_back::tempdir::TempDir;
31
32 use std::fs::{self, PathExt};
33 use std::io::{self, Read, Write};
34 use std::mem;
35 use std::path::{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 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 get_ar_prog(sess: &Session) -> String {
369     sess.opts.cg.ar.clone().unwrap_or_else(|| {
370         sess.target.target.options.ar.clone()
371     })
372 }
373
374 pub fn remove(sess: &Session, path: &Path) {
375     match fs::remove_file(path) {
376         Ok(..) => {}
377         Err(e) => {
378             sess.err(&format!("failed to remove {}: {}",
379                              path.display(),
380                              e));
381         }
382     }
383 }
384
385 /// Perform the linkage portion of the compilation phase. This will generate all
386 /// of the requested outputs for this compilation session.
387 pub fn link_binary(sess: &Session,
388                    trans: &CrateTranslation,
389                    outputs: &OutputFilenames,
390                    crate_name: &str) -> Vec<PathBuf> {
391     let mut out_filenames = Vec::new();
392     for &crate_type in &*sess.crate_types.borrow() {
393         if invalid_output_for_target(sess, crate_type) {
394             sess.bug(&format!("invalid output type `{:?}` for target os `{}`",
395                              crate_type, sess.opts.target_triple));
396         }
397         let out_file = link_binary_output(sess, trans, crate_type, outputs,
398                                           crate_name);
399         out_filenames.push(out_file);
400     }
401
402     // Remove the temporary object file and metadata if we aren't saving temps
403     if !sess.opts.cg.save_temps {
404         let obj_filename = outputs.temp_path(OutputTypeObject);
405         if !sess.opts.output_types.contains(&OutputTypeObject) {
406             remove(sess, &obj_filename);
407         }
408         remove(sess, &obj_filename.with_extension("metadata.o"));
409     }
410
411     out_filenames
412 }
413
414
415 /// Returns default crate type for target
416 ///
417 /// Default crate type is used when crate type isn't provided neither
418 /// through cmd line arguments nor through crate attributes
419 ///
420 /// It is CrateTypeExecutable for all platforms but iOS as there is no
421 /// way to run iOS binaries anyway without jailbreaking and
422 /// interaction with Rust code through static library is the only
423 /// option for now
424 pub fn default_output_for_target(sess: &Session) -> config::CrateType {
425     if !sess.target.target.options.executables {
426         config::CrateTypeStaticlib
427     } else {
428         config::CrateTypeExecutable
429     }
430 }
431
432 /// Checks if target supports crate_type as output
433 pub fn invalid_output_for_target(sess: &Session,
434                                  crate_type: config::CrateType) -> bool {
435     match (sess.target.target.options.dynamic_linking,
436            sess.target.target.options.executables, crate_type) {
437         (false, _, config::CrateTypeDylib) => true,
438         (_, false, config::CrateTypeExecutable) => true,
439         _ => false
440     }
441 }
442
443 fn is_writeable(p: &Path) -> bool {
444     match p.metadata() {
445         Err(..) => true,
446         Ok(m) => !m.permissions().readonly()
447     }
448 }
449
450 pub fn filename_for_input(sess: &Session,
451                           crate_type: config::CrateType,
452                           name: &str,
453                           out_filename: &Path) -> PathBuf {
454     let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
455     match crate_type {
456         config::CrateTypeRlib => {
457             out_filename.with_file_name(&format!("lib{}.rlib", libname))
458         }
459         config::CrateTypeDylib => {
460             let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
461                                     &sess.target.target.options.dll_suffix);
462             out_filename.with_file_name(&format!("{}{}{}",
463                                                   prefix,
464                                                  libname,
465                                                  suffix))
466         }
467         config::CrateTypeStaticlib => {
468             out_filename.with_file_name(&format!("lib{}.a", libname))
469         }
470         config::CrateTypeExecutable => {
471             let suffix = &sess.target.target.options.exe_suffix;
472             if suffix.is_empty() {
473                 out_filename.to_path_buf()
474             } else {
475                 out_filename.with_extension(&suffix[1..])
476             }
477         }
478     }
479 }
480
481 fn link_binary_output(sess: &Session,
482                       trans: &CrateTranslation,
483                       crate_type: config::CrateType,
484                       outputs: &OutputFilenames,
485                       crate_name: &str) -> PathBuf {
486     let obj_filename = outputs.temp_path(OutputTypeObject);
487     let out_filename = match outputs.single_output_file {
488         Some(ref file) => file.clone(),
489         None => {
490             let out_filename = outputs.path(OutputTypeExe);
491             filename_for_input(sess, crate_type, crate_name, &out_filename)
492         }
493     };
494
495     // Make sure the output and obj_filename are both writeable.
496     // Mac, FreeBSD, and Windows system linkers check this already --
497     // however, the Linux linker will happily overwrite a read-only file.
498     // We should be consistent.
499     let obj_is_writeable = is_writeable(&obj_filename);
500     let out_is_writeable = is_writeable(&out_filename);
501     if !out_is_writeable {
502         sess.fatal(&format!("output file {} is not writeable -- check its \
503                             permissions.",
504                            out_filename.display()));
505     }
506     else if !obj_is_writeable {
507         sess.fatal(&format!("object file {} is not writeable -- check its \
508                             permissions.",
509                            obj_filename.display()));
510     }
511
512     match crate_type {
513         config::CrateTypeRlib => {
514             link_rlib(sess, Some(trans), &obj_filename, &out_filename).build();
515         }
516         config::CrateTypeStaticlib => {
517             link_staticlib(sess, &obj_filename, &out_filename);
518         }
519         config::CrateTypeExecutable => {
520             link_natively(sess, trans, false, &obj_filename, &out_filename);
521         }
522         config::CrateTypeDylib => {
523             link_natively(sess, trans, true, &obj_filename, &out_filename);
524         }
525     }
526
527     out_filename
528 }
529
530 fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
531     let mut search = Vec::new();
532     sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
533         search.push(path.to_path_buf());
534         FileDoesntMatch
535     });
536     return search;
537 }
538
539 // Create an 'rlib'
540 //
541 // An rlib in its current incarnation is essentially a renamed .a file. The
542 // rlib primarily contains the object file of the crate, but it also contains
543 // all of the object files from native libraries. This is done by unzipping
544 // native libraries and inserting all of the contents into this archive.
545 fn link_rlib<'a>(sess: &'a Session,
546                  trans: Option<&CrateTranslation>, // None == no metadata/bytecode
547                  obj_filename: &Path,
548                  out_filename: &Path) -> ArchiveBuilder<'a> {
549     info!("preparing rlib from {:?} to {:?}", obj_filename, out_filename);
550     let handler = &sess.diagnostic().handler;
551     let config = ArchiveConfig {
552         handler: handler,
553         dst: out_filename.to_path_buf(),
554         lib_search_paths: archive_search_paths(sess),
555         slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
556         slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
557         ar_prog: get_ar_prog(sess),
558     };
559     let mut ab = ArchiveBuilder::create(config);
560     ab.add_file(obj_filename).unwrap();
561
562     for &(ref l, kind) in &*sess.cstore.get_used_libraries().borrow() {
563         match kind {
564             cstore::NativeStatic => ab.add_native_library(&l).unwrap(),
565             cstore::NativeFramework | cstore::NativeUnknown => {}
566         }
567     }
568
569     // After adding all files to the archive, we need to update the
570     // symbol table of the archive.
571     ab.update_symbols();
572
573     let mut ab = match sess.target.target.options.is_like_osx {
574         // For OSX/iOS, we must be careful to update symbols only when adding
575         // object files.  We're about to start adding non-object files, so run
576         // `ar` now to process the object files.
577         true => ab.build().extend(),
578         false => ab,
579     };
580
581     // Note that it is important that we add all of our non-object "magical
582     // files" *after* all of the object files in the archive. The reason for
583     // this is as follows:
584     //
585     // * When performing LTO, this archive will be modified to remove
586     //   obj_filename from above. The reason for this is described below.
587     //
588     // * When the system linker looks at an archive, it will attempt to
589     //   determine the architecture of the archive in order to see whether its
590     //   linkable.
591     //
592     //   The algorithm for this detection is: iterate over the files in the
593     //   archive. Skip magical SYMDEF names. Interpret the first file as an
594     //   object file. Read architecture from the object file.
595     //
596     // * As one can probably see, if "metadata" and "foo.bc" were placed
597     //   before all of the objects, then the architecture of this archive would
598     //   not be correctly inferred once 'foo.o' is removed.
599     //
600     // Basically, all this means is that this code should not move above the
601     // code above.
602     match trans {
603         Some(trans) => {
604             // Instead of putting the metadata in an object file section, rlibs
605             // contain the metadata in a separate file. We use a temp directory
606             // here so concurrent builds in the same directory don't try to use
607             // the same filename for metadata (stomping over one another)
608             let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
609             let metadata = tmpdir.path().join(METADATA_FILENAME);
610             match fs::File::create(&metadata).and_then(|mut f| {
611                 f.write_all(&trans.metadata)
612             }) {
613                 Ok(..) => {}
614                 Err(e) => {
615                     sess.fatal(&format!("failed to write {}: {}",
616                                         metadata.display(), e));
617                 }
618             }
619             ab.add_file(&metadata).unwrap();
620             remove(sess, &metadata);
621
622             // For LTO purposes, the bytecode of this library is also inserted
623             // into the archive.  If codegen_units > 1, we insert each of the
624             // bitcode files.
625             for i in 0..sess.opts.cg.codegen_units {
626                 // Note that we make sure that the bytecode filename in the
627                 // archive is never exactly 16 bytes long by adding a 16 byte
628                 // extension to it. This is to work around a bug in LLDB that
629                 // would cause it to crash if the name of a file in an archive
630                 // was exactly 16 bytes.
631                 let bc_filename = obj_filename.with_extension(&format!("{}.bc", i));
632                 let bc_deflated_filename = obj_filename.with_extension(
633                     &format!("{}.bytecode.deflate", i));
634
635                 let mut bc_data = Vec::new();
636                 match fs::File::open(&bc_filename).and_then(|mut f| {
637                     f.read_to_end(&mut bc_data)
638                 }) {
639                     Ok(..) => {}
640                     Err(e) => sess.fatal(&format!("failed to read bytecode: {}",
641                                                  e))
642                 }
643
644                 let bc_data_deflated = flate::deflate_bytes(&bc_data[..]);
645
646                 let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
647                     Ok(file) => file,
648                     Err(e) => {
649                         sess.fatal(&format!("failed to create compressed \
650                                              bytecode file: {}", e))
651                     }
652                 };
653
654                 match write_rlib_bytecode_object_v1(&mut bc_file_deflated,
655                                                     &bc_data_deflated) {
656                     Ok(()) => {}
657                     Err(e) => {
658                         sess.fatal(&format!("failed to write compressed \
659                                              bytecode: {}", e));
660                     }
661                 };
662
663                 ab.add_file(&bc_deflated_filename).unwrap();
664                 remove(sess, &bc_deflated_filename);
665
666                 // See the bottom of back::write::run_passes for an explanation
667                 // of when we do and don't keep .0.bc files around.
668                 let user_wants_numbered_bitcode =
669                         sess.opts.output_types.contains(&OutputTypeBitcode) &&
670                         sess.opts.cg.codegen_units > 1;
671                 if !sess.opts.cg.save_temps && !user_wants_numbered_bitcode {
672                     remove(sess, &bc_filename);
673                 }
674             }
675
676             // After adding all files to the archive, we need to update the
677             // symbol table of the archive. This currently dies on OSX (see
678             // #11162), and isn't necessary there anyway
679             if !sess.target.target.options.is_like_osx {
680                 ab.update_symbols();
681             }
682         }
683
684         None => {}
685     }
686
687     ab
688 }
689
690 fn write_rlib_bytecode_object_v1(writer: &mut Write,
691                                  bc_data_deflated: &[u8]) -> io::Result<()> {
692     let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64;
693
694     try!(writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC));
695     try!(writer.write_all(&[1, 0, 0, 0]));
696     try!(writer.write_all(&[
697         (bc_data_deflated_size >>  0) as u8,
698         (bc_data_deflated_size >>  8) as u8,
699         (bc_data_deflated_size >> 16) as u8,
700         (bc_data_deflated_size >> 24) as u8,
701         (bc_data_deflated_size >> 32) as u8,
702         (bc_data_deflated_size >> 40) as u8,
703         (bc_data_deflated_size >> 48) as u8,
704         (bc_data_deflated_size >> 56) as u8,
705     ]));
706     try!(writer.write_all(&bc_data_deflated));
707
708     let number_of_bytes_written_so_far =
709         RLIB_BYTECODE_OBJECT_MAGIC.len() +                // magic id
710         mem::size_of_val(&RLIB_BYTECODE_OBJECT_VERSION) + // version
711         mem::size_of_val(&bc_data_deflated_size) +        // data size field
712         bc_data_deflated_size as usize;                    // actual data
713
714     // If the number of bytes written to the object so far is odd, add a
715     // padding byte to make it even. This works around a crash bug in LLDB
716     // (see issue #15950)
717     if number_of_bytes_written_so_far % 2 == 1 {
718         try!(writer.write_all(&[0]));
719     }
720
721     return Ok(());
722 }
723
724 // Create a static archive
725 //
726 // This is essentially the same thing as an rlib, but it also involves adding
727 // all of the upstream crates' objects into the archive. This will slurp in
728 // all of the native libraries of upstream dependencies as well.
729 //
730 // Additionally, there's no way for us to link dynamic libraries, so we warn
731 // about all dynamic library dependencies that they're not linked in.
732 //
733 // There's no need to include metadata in a static archive, so ensure to not
734 // link in the metadata object file (and also don't prepare the archive with a
735 // metadata file).
736 fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
737     let ab = link_rlib(sess, None, obj_filename, out_filename);
738     let mut ab = match sess.target.target.options.is_like_osx {
739         true => ab.build().extend(),
740         false => ab,
741     };
742     if sess.target.target.options.morestack {
743         ab.add_native_library("morestack").unwrap();
744     }
745     if !sess.target.target.options.no_compiler_rt {
746         ab.add_native_library("compiler-rt").unwrap();
747     }
748
749     let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
750     let mut all_native_libs = vec![];
751
752     for &(cnum, ref path) in &crates {
753         let ref name = sess.cstore.get_crate_data(cnum).name;
754         let p = match *path {
755             Some(ref p) => p.clone(), None => {
756                 sess.err(&format!("could not find rlib for: `{}`",
757                                  name));
758                 continue
759             }
760         };
761         ab.add_rlib(&p, &name[..], sess.lto()).unwrap();
762
763         let native_libs = csearch::get_native_libraries(&sess.cstore, cnum);
764         all_native_libs.extend(native_libs.into_iter());
765     }
766
767     ab.update_symbols();
768     let _ = ab.build();
769
770     if !all_native_libs.is_empty() {
771         sess.note("link against the following native artifacts when linking against \
772                   this static library");
773         sess.note("the order and any duplication can be significant on some platforms, \
774                   and so may need to be preserved");
775     }
776
777     for &(kind, ref lib) in &all_native_libs {
778         let name = match kind {
779             cstore::NativeStatic => "static library",
780             cstore::NativeUnknown => "library",
781             cstore::NativeFramework => "framework",
782         };
783         sess.note(&format!("{}: {}", name, *lib));
784     }
785 }
786
787 // Create a dynamic library or executable
788 //
789 // This will invoke the system linker/cc to create the resulting file. This
790 // links to all upstream files as well.
791 fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
792                  obj_filename: &Path, out_filename: &Path) {
793     info!("preparing dylib? ({}) from {:?} to {:?}", dylib, obj_filename,
794           out_filename);
795     let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
796
797     // The invocations of cc share some flags across platforms
798     let pname = get_cc_prog(sess);
799     let mut cmd = Command::new(&pname[..]);
800
801     let root = sess.target_filesearch(PathKind::Native).get_lib_path();
802     cmd.args(&sess.target.target.options.pre_link_args);
803     for obj in &sess.target.target.options.pre_link_objects {
804         cmd.arg(root.join(obj));
805     }
806
807     {
808         let mut linker = GnuLinker { cmd: &mut cmd, sess: &sess };
809         link_args(&mut linker, sess, dylib, tmpdir.path(),
810                   trans, obj_filename, out_filename);
811         if !sess.target.target.options.no_compiler_rt {
812             linker.link_staticlib("compiler-rt");
813         }
814     }
815     for obj in &sess.target.target.options.post_link_objects {
816         cmd.arg(root.join(obj));
817     }
818     cmd.args(&sess.target.target.options.post_link_args);
819
820     if sess.opts.debugging_opts.print_link_args {
821         println!("{:?}", &cmd);
822     }
823
824     // May have not found libraries in the right formats.
825     sess.abort_if_errors();
826
827     // Invoke the system linker
828     info!("{:?}", &cmd);
829     let prog = time(sess.time_passes(), "running linker", (), |()| cmd.output());
830     match prog {
831         Ok(prog) => {
832             if !prog.status.success() {
833                 sess.err(&format!("linking with `{}` failed: {}",
834                                  pname,
835                                  prog.status));
836                 sess.note(&format!("{:?}", &cmd));
837                 let mut output = prog.stderr.clone();
838                 output.push_all(&prog.stdout);
839                 sess.note(str::from_utf8(&output[..]).unwrap());
840                 sess.abort_if_errors();
841             }
842             info!("linker stderr:\n{}", String::from_utf8(prog.stderr).unwrap());
843             info!("linker stdout:\n{}", String::from_utf8(prog.stdout).unwrap());
844         },
845         Err(e) => {
846             sess.fatal(&format!("could not exec the linker `{}`: {}", pname, e));
847         }
848     }
849
850
851     // On OSX, debuggers need this utility to get run to do some munging of
852     // the symbols
853     if sess.target.target.options.is_like_osx && sess.opts.debuginfo != NoDebugInfo {
854         match Command::new("dsymutil").arg(out_filename).output() {
855             Ok(..) => {}
856             Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)),
857         }
858     }
859 }
860
861 fn link_args(cmd: &mut Linker,
862              sess: &Session,
863              dylib: bool,
864              tmpdir: &Path,
865              trans: &CrateTranslation,
866              obj_filename: &Path,
867              out_filename: &Path) {
868
869     // The default library location, we need this to find the runtime.
870     // The location of crates will be determined as needed.
871     let lib_path = sess.target_filesearch(PathKind::All).get_lib_path();
872
873     // target descriptor
874     let t = &sess.target.target;
875
876     cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
877
878     cmd.output_filename(out_filename);
879     cmd.add_object(obj_filename);
880
881     // Stack growth requires statically linking a __morestack function. Note
882     // that this is listed *before* all other libraries. Due to the usage of the
883     // --as-needed flag below, the standard library may only be useful for its
884     // rust_stack_exhausted function. In this case, we must ensure that the
885     // libmorestack.a file appears *before* the standard library (so we put it
886     // at the very front).
887     //
888     // Most of the time this is sufficient, except for when LLVM gets super
889     // clever. If, for example, we have a main function `fn main() {}`, LLVM
890     // will optimize out calls to `__morestack` entirely because the function
891     // doesn't need any stack at all!
892     //
893     // To get around this snag, we specially tell the linker to always include
894     // all contents of this library. This way we're guaranteed that the linker
895     // will include the __morestack symbol 100% of the time, always resolving
896     // references to it even if the object above didn't use it.
897     if t.options.morestack {
898         cmd.link_whole_staticlib("morestack", &[lib_path]);
899     }
900
901     // When linking a dynamic library, we put the metadata into a section of the
902     // executable. This metadata is in a separate object file from the main
903     // object file, so we link that in here.
904     if dylib {
905         cmd.add_object(&obj_filename.with_extension("metadata.o"));
906     }
907
908     // Try to strip as much out of the generated object by removing unused
909     // sections if possible. See more comments in linker.rs
910     cmd.gc_sections(dylib);
911
912     let used_link_args = sess.cstore.get_used_link_args().borrow();
913
914     if !dylib && t.options.position_independent_executables {
915         let empty_vec = Vec::new();
916         let empty_str = String::new();
917         let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
918         let mut args = args.iter().chain(used_link_args.iter());
919         let relocation_model = sess.opts.cg.relocation_model.as_ref()
920                                    .unwrap_or(&empty_str);
921         if (t.options.relocation_model == "pic" || *relocation_model == "pic")
922             && !args.any(|x| *x == "-static") {
923             cmd.position_independent_executable();
924         }
925     }
926
927     // Pass optimization flags down to the linker.
928     cmd.optimize();
929
930     // We want to prevent the compiler from accidentally leaking in any system
931     // libraries, so we explicitly ask gcc to not link to any libraries by
932     // default. Note that this does not happen for windows because windows pulls
933     // in some large number of libraries and I couldn't quite figure out which
934     // subset we wanted.
935     cmd.no_default_libraries();
936
937     // Take careful note of the ordering of the arguments we pass to the linker
938     // here. Linkers will assume that things on the left depend on things to the
939     // right. Things on the right cannot depend on things on the left. This is
940     // all formally implemented in terms of resolving symbols (libs on the right
941     // resolve unknown symbols of libs on the left, but not vice versa).
942     //
943     // For this reason, we have organized the arguments we pass to the linker as
944     // such:
945     //
946     //  1. The local object that LLVM just generated
947     //  2. Upstream rust libraries
948     //  3. Local native libraries
949     //  4. Upstream native libraries
950     //
951     // This is generally fairly natural, but some may expect 2 and 3 to be
952     // swapped. The reason that all native libraries are put last is that it's
953     // not recommended for a native library to depend on a symbol from a rust
954     // crate. If this is the case then a staticlib crate is recommended, solving
955     // the problem.
956     //
957     // Additionally, it is occasionally the case that upstream rust libraries
958     // depend on a local native library. In the case of libraries such as
959     // lua/glfw/etc the name of the library isn't the same across all platforms,
960     // so only the consumer crate of a library knows the actual name. This means
961     // that downstream crates will provide the #[link] attribute which upstream
962     // crates will depend on. Hence local native libraries are after out
963     // upstream rust crates.
964     //
965     // In theory this means that a symbol in an upstream native library will be
966     // shadowed by a local native library when it wouldn't have been before, but
967     // this kind of behavior is pretty platform specific and generally not
968     // recommended anyway, so I don't think we're shooting ourself in the foot
969     // much with that.
970     add_upstream_rust_crates(cmd, sess, dylib, tmpdir, trans);
971     add_local_native_libraries(cmd, sess);
972     add_upstream_native_libraries(cmd, sess);
973
974     // # Telling the linker what we're doing
975
976     if dylib {
977         cmd.build_dylib(out_filename);
978     }
979
980     // FIXME (#2397): At some point we want to rpath our guesses as to
981     // where extern libraries might live, based on the
982     // addl_lib_search_paths
983     if sess.opts.cg.rpath {
984         let sysroot = sess.sysroot();
985         let target_triple = &sess.opts.target_triple;
986         let mut get_install_prefix_lib_path = || {
987             let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
988             let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
989             let mut path = PathBuf::from(install_prefix);
990             path.push(&tlib);
991
992             path
993         };
994         let mut rpath_config = RPathConfig {
995             used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
996             out_filename: out_filename.to_path_buf(),
997             has_rpath: sess.target.target.options.has_rpath,
998             is_like_osx: sess.target.target.options.is_like_osx,
999             get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
1000         };
1001         cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
1002     }
1003
1004     // Finally add all the linker arguments provided on the command line along
1005     // with any #[link_args] attributes found inside the crate
1006     if let Some(ref args) = sess.opts.cg.link_args {
1007         cmd.args(args);
1008     }
1009     cmd.args(&used_link_args);
1010 }
1011
1012 // # Native library linking
1013 //
1014 // User-supplied library search paths (-L on the command line). These are
1015 // the same paths used to find Rust crates, so some of them may have been
1016 // added already by the previous crate linking code. This only allows them
1017 // to be found at compile time so it is still entirely up to outside
1018 // forces to make sure that library can be found at runtime.
1019 //
1020 // Also note that the native libraries linked here are only the ones located
1021 // in the current crate. Upstream crates with native library dependencies
1022 // may have their native library pulled in above.
1023 fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
1024     sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
1025         match k {
1026             PathKind::Framework => { cmd.framework_path(path); }
1027             _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(path)); }
1028         }
1029         FileDoesntMatch
1030     });
1031
1032     let libs = sess.cstore.get_used_libraries();
1033     let libs = libs.borrow();
1034
1035     let staticlibs = libs.iter().filter_map(|&(ref l, kind)| {
1036         if kind == cstore::NativeStatic {Some(l)} else {None}
1037     });
1038     let others = libs.iter().filter(|&&(_, kind)| {
1039         kind != cstore::NativeStatic
1040     });
1041
1042     // Some platforms take hints about whether a library is static or dynamic.
1043     // For those that support this, we ensure we pass the option if the library
1044     // was flagged "static" (most defaults are dynamic) to ensure that if
1045     // libfoo.a and libfoo.so both exist that the right one is chosen.
1046     cmd.hint_static();
1047
1048     let search_path = archive_search_paths(sess);
1049     for l in staticlibs {
1050         // Here we explicitly ask that the entire archive is included into the
1051         // result artifact. For more details see #15460, but the gist is that
1052         // the linker will strip away any unused objects in the archive if we
1053         // don't otherwise explicitly reference them. This can occur for
1054         // libraries which are just providing bindings, libraries with generic
1055         // functions, etc.
1056         cmd.link_whole_staticlib(l, &search_path);
1057     }
1058
1059     cmd.hint_dynamic();
1060
1061     for &(ref l, kind) in others {
1062         match kind {
1063             cstore::NativeUnknown => cmd.link_dylib(l),
1064             cstore::NativeFramework => cmd.link_framework(l),
1065             cstore::NativeStatic => unreachable!(),
1066         }
1067     }
1068 }
1069
1070 // # Rust Crate linking
1071 //
1072 // Rust crates are not considered at all when creating an rlib output. All
1073 // dependencies will be linked when producing the final output (instead of
1074 // the intermediate rlib version)
1075 fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
1076                             dylib: bool, tmpdir: &Path,
1077                             trans: &CrateTranslation) {
1078     // All of the heavy lifting has previously been accomplished by the
1079     // dependency_format module of the compiler. This is just crawling the
1080     // output of that module, adding crates as necessary.
1081     //
1082     // Linking to a rlib involves just passing it to the linker (the linker
1083     // will slurp up the object files inside), and linking to a dynamic library
1084     // involves just passing the right -l flag.
1085
1086     let data = if dylib {
1087         trans.crate_formats.get(&config::CrateTypeDylib).unwrap()
1088     } else {
1089         trans.crate_formats.get(&config::CrateTypeExecutable).unwrap()
1090     };
1091
1092     // Invoke get_used_crates to ensure that we get a topological sorting of
1093     // crates.
1094     let deps = sess.cstore.get_used_crates(cstore::RequireDynamic);
1095
1096     for &(cnum, _) in &deps {
1097         // We may not pass all crates through to the linker. Some crates may
1098         // appear statically in an existing dylib, meaning we'll pick up all the
1099         // symbols from the dylib.
1100         let kind = match data[cnum as usize - 1] {
1101             Some(t) => t,
1102             None => continue
1103         };
1104         let src = sess.cstore.get_used_crate_source(cnum).unwrap();
1105         match kind {
1106             cstore::RequireDynamic => {
1107                 add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
1108             }
1109             cstore::RequireStatic => {
1110                 add_static_crate(cmd, sess, tmpdir, &src.rlib.unwrap().0)
1111             }
1112         }
1113
1114     }
1115
1116     // Converts a library file-stem into a cc -l argument
1117     fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
1118         if stem.starts_with("lib") && !config.target.options.is_like_windows {
1119             &stem[3..]
1120         } else {
1121             stem
1122         }
1123     }
1124
1125     // Adds the static "rlib" versions of all crates to the command line.
1126     fn add_static_crate(cmd: &mut Linker, sess: &Session, tmpdir: &Path,
1127                         cratepath: &Path) {
1128         // When performing LTO on an executable output, all of the
1129         // bytecode from the upstream libraries has already been
1130         // included in our object file output. We need to modify all of
1131         // the upstream archives to remove their corresponding object
1132         // file to make sure we don't pull the same code in twice.
1133         //
1134         // We must continue to link to the upstream archives to be sure
1135         // to pull in native static dependencies. As the final caveat,
1136         // on Linux it is apparently illegal to link to a blank archive,
1137         // so if an archive no longer has any object files in it after
1138         // we remove `lib.o`, then don't link against it at all.
1139         //
1140         // If we're not doing LTO, then our job is simply to just link
1141         // against the archive.
1142         if sess.lto() {
1143             let name = cratepath.file_name().unwrap().to_str().unwrap();
1144             let name = &name[3..name.len() - 5]; // chop off lib/.rlib
1145             time(sess.time_passes(),
1146                  &format!("altering {}.rlib", name),
1147                  (), |()| {
1148                 let dst = tmpdir.join(cratepath.file_name().unwrap());
1149                 match fs::copy(&cratepath, &dst) {
1150                     Ok(..) => {}
1151                     Err(e) => {
1152                         sess.fatal(&format!("failed to copy {} to {}: {}",
1153                                             cratepath.display(),
1154                                             dst.display(), e));
1155                     }
1156                 }
1157                 // Fix up permissions of the copy, as fs::copy() preserves
1158                 // permissions, but the original file may have been installed
1159                 // by a package manager and may be read-only.
1160                 match fs::metadata(&dst).and_then(|m| {
1161                     let mut perms = m.permissions();
1162                     perms.set_readonly(false);
1163                     fs::set_permissions(&dst, perms)
1164                 }) {
1165                     Ok(..) => {}
1166                     Err(e) => {
1167                         sess.fatal(&format!("failed to chmod {} when preparing \
1168                                              for LTO: {}", dst.display(), e));
1169                     }
1170                 }
1171                 let handler = &sess.diagnostic().handler;
1172                 let config = ArchiveConfig {
1173                     handler: handler,
1174                     dst: dst.clone(),
1175                     lib_search_paths: archive_search_paths(sess),
1176                     slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
1177                     slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
1178                     ar_prog: get_ar_prog(sess),
1179                 };
1180                 let mut archive = Archive::open(config);
1181                 archive.remove_file(&format!("{}.o", name));
1182                 let files = archive.files();
1183                 if files.iter().any(|s| s.ends_with(".o")) {
1184                     cmd.link_rlib(&dst);
1185                 }
1186             });
1187         } else {
1188             cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
1189         }
1190     }
1191
1192     // Same thing as above, but for dynamic crates instead of static crates.
1193     fn add_dynamic_crate(cmd: &mut Linker, sess: &Session, cratepath: &Path) {
1194         // If we're performing LTO, then it should have been previously required
1195         // that all upstream rust dependencies were available in an rlib format.
1196         assert!(!sess.lto());
1197
1198         // Just need to tell the linker about where the library lives and
1199         // what its name is
1200         if let Some(dir) = cratepath.parent() {
1201             cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
1202         }
1203         let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
1204         cmd.link_dylib(&unlib(&sess.target, filestem));
1205     }
1206 }
1207
1208 // Link in all of our upstream crates' native dependencies. Remember that
1209 // all of these upstream native dependencies are all non-static
1210 // dependencies. We've got two cases then:
1211 //
1212 // 1. The upstream crate is an rlib. In this case we *must* link in the
1213 // native dependency because the rlib is just an archive.
1214 //
1215 // 2. The upstream crate is a dylib. In order to use the dylib, we have to
1216 // have the dependency present on the system somewhere. Thus, we don't
1217 // gain a whole lot from not linking in the dynamic dependency to this
1218 // crate as well.
1219 //
1220 // The use case for this is a little subtle. In theory the native
1221 // dependencies of a crate are purely an implementation detail of the crate
1222 // itself, but the problem arises with generic and inlined functions. If a
1223 // generic function calls a native function, then the generic function must
1224 // be instantiated in the target crate, meaning that the native symbol must
1225 // also be resolved in the target crate.
1226 fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session) {
1227     // Be sure to use a topological sorting of crates because there may be
1228     // interdependencies between native libraries. When passing -nodefaultlibs,
1229     // for example, almost all native libraries depend on libc, so we have to
1230     // make sure that's all the way at the right (liblibc is near the base of
1231     // the dependency chain).
1232     //
1233     // This passes RequireStatic, but the actual requirement doesn't matter,
1234     // we're just getting an ordering of crate numbers, we're not worried about
1235     // the paths.
1236     let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
1237     for (cnum, _) in crates {
1238         let libs = csearch::get_native_libraries(&sess.cstore, cnum);
1239         for &(kind, ref lib) in &libs {
1240             match kind {
1241                 cstore::NativeUnknown => cmd.link_dylib(lib),
1242                 cstore::NativeFramework => cmd.link_framework(lib),
1243                 cstore::NativeStatic => {
1244                     sess.bug("statics shouldn't be propagated");
1245                 }
1246             }
1247         }
1248     }
1249 }