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