1 //! All functions here are copied from https://github.com/rust-lang/rust/blob/942864a000efd74b73e36bda5606b2cdb55ecf39/src/librustc_codegen_llvm/back/link.rs
7 use std::path::{Path, PathBuf};
8 use std::process::{Output, Stdio};
12 use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind};
13 use rustc::middle::dependency_format::Linkage;
14 use rustc::session::config::{self, OutputType, RUST_CGU_EXT};
15 use rustc::session::search_paths::PathKind;
16 use rustc::session::Session;
17 use rustc::util::common::time;
18 use rustc_codegen_ssa::back::command::Command;
19 use rustc_codegen_ssa::back::linker::*;
20 use rustc_codegen_ssa::back::link::*;
21 use rustc_data_structures::fx::FxHashSet;
22 use rustc_fs_util::fix_windows_verbatim_for_gcc;
25 use crate::prelude::*;
27 use crate::archive::{ArchiveBuilder, ArchiveConfig};
28 use crate::metadata::METADATA_FILENAME;
31 // cg_clif doesn't have bytecode, so this is just a dummy
32 const RLIB_BYTECODE_EXTENSION: &str = ".cg_clif_bytecode_dummy";
34 fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
35 sess.target_filesearch(PathKind::Native).search_path_dirs()
38 fn archive_config<'a>(sess: &'a Session,
40 input: Option<&Path>) -> ArchiveConfig<'a> {
43 dst: output.to_path_buf(),
44 src: input.map(|p| p.to_path_buf()),
45 lib_search_paths: archive_search_paths(sess),
49 pub fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: &Path)
52 // When attempting to spawn the linker we run a risk of blowing out the
53 // size limits for spawning a new process with respect to the arguments
54 // we pass on the command line.
56 // Here we attempt to handle errors from the OS saying "your list of
57 // arguments is too big" by reinvoking the linker again with an `@`-file
58 // that contains all the arguments. The theory is that this is then
59 // accepted on all linkers and the linker will read all its options out of
60 // there instead of looking at the command line.
61 if !cmd.very_likely_to_exceed_some_spawn_limit() {
62 match cmd.command().stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() {
64 let output = child.wait_with_output();
65 flush_linked_file(&output, out_filename)?;
68 Err(ref e) if command_line_too_big(e) => {
69 info!("command line to linker was too big: {}", e);
71 Err(e) => return Err(e)
75 info!("falling back to passing arguments to linker via an @-file");
76 let mut cmd2 = cmd.clone();
77 let mut args = String::new();
78 for arg in cmd2.take_args() {
79 args.push_str(&Escape {
80 arg: arg.to_str().unwrap(),
81 is_like_msvc: sess.target.target.options.is_like_msvc,
85 let file = tmpdir.join("linker-arguments");
86 let bytes = if sess.target.target.options.is_like_msvc {
87 let mut out = Vec::with_capacity((1 + args.len()) * 2);
88 // start the stream with a UTF-16 BOM
89 for c in iter::once(0xFEFF).chain(args.encode_utf16()) {
90 // encode in little endian
92 out.push((c >> 8) as u8);
98 fs::write(&file, &bytes)?;
99 cmd2.arg(format!("@{}", file.display()));
100 info!("invoking linker {:?}", cmd2);
101 let output = cmd2.output();
102 flush_linked_file(&output, out_filename)?;
106 fn flush_linked_file(_: &io::Result<Output>, _: &Path) -> io::Result<()> {
111 fn flush_linked_file(command_output: &io::Result<Output>, out_filename: &Path)
114 // On Windows, under high I/O load, output buffers are sometimes not flushed,
115 // even long after process exit, causing nasty, non-reproducible output bugs.
117 // File::sync_all() calls FlushFileBuffers() down the line, which solves the problem.
119 // А full writeup of the original Chrome bug can be found at
120 // randomascii.wordpress.com/2018/02/25/compiler-bug-linker-bug-windows-kernel-bug/amp
122 if let &Ok(ref out) = command_output {
123 if out.status.success() {
124 if let Ok(of) = fs::OpenOptions::new().write(true).open(out_filename) {
134 fn command_line_too_big(err: &io::Error) -> bool {
135 err.raw_os_error() == Some(::libc::E2BIG)
139 fn command_line_too_big(err: &io::Error) -> bool {
140 const ERROR_FILENAME_EXCED_RANGE: i32 = 206;
141 err.raw_os_error() == Some(ERROR_FILENAME_EXCED_RANGE)
149 impl<'a> fmt::Display for Escape<'a> {
150 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
151 if self.is_like_msvc {
152 // This is "documented" at
153 // https://msdn.microsoft.com/en-us/library/4xdcbak7.aspx
155 // Unfortunately there's not a great specification of the
156 // syntax I could find online (at least) but some local
157 // testing showed that this seemed sufficient-ish to catch
158 // at least a few edge cases.
160 for c in self.arg.chars() {
162 '"' => write!(f, "\\{}", c)?,
163 c => write!(f, "{}", c)?,
168 // This is documented at https://linux.die.net/man/1/ld, namely:
170 // > Options in file are separated by whitespace. A whitespace
171 // > character may be included in an option by surrounding the
172 // > entire option in either single or double quotes. Any
173 // > character (including a backslash) may be included by
174 // > prefixing the character to be included with a backslash.
176 // We put an argument on each line, so all we need to do is
177 // ensure the line is interpreted as one whole argument.
178 for c in self.arg.chars() {
181 ' ' => write!(f, "\\{}", c)?,
182 c => write!(f, "{}", c)?,
191 // # Rust Crate linking
193 // Rust crates are not considered at all when creating an rlib output. All
194 // dependencies will be linked when producing the final output (instead of
195 // the intermediate rlib version)
196 pub fn add_upstream_rust_crates(cmd: &mut dyn Linker,
198 codegen_results: &CodegenResults,
199 crate_type: config::CrateType,
201 // All of the heavy lifting has previously been accomplished by the
202 // dependency_format module of the compiler. This is just crawling the
203 // output of that module, adding crates as necessary.
205 // Linking to a rlib involves just passing it to the linker (the linker
206 // will slurp up the object files inside), and linking to a dynamic library
207 // involves just passing the right -l flag.
209 let formats = sess.dependency_formats.borrow();
210 let data = formats.get(&crate_type).unwrap();
212 // Invoke get_used_crates to ensure that we get a topological sorting of
214 let deps = &codegen_results.crate_info.used_crates_dynamic;
216 // There's a few internal crates in the standard library (aka libcore and
217 // libstd) which actually have a circular dependence upon one another. This
218 // currently arises through "weak lang items" where libcore requires things
219 // like `rust_begin_unwind` but libstd ends up defining it. To get this
220 // circular dependence to work correctly in all situations we'll need to be
221 // sure to correctly apply the `--start-group` and `--end-group` options to
222 // GNU linkers, otherwise if we don't use any other symbol from the standard
223 // library it'll get discarded and the whole application won't link.
225 // In this loop we're calculating the `group_end`, after which crate to
226 // pass `--end-group` and `group_start`, before which crate to pass
227 // `--start-group`. We currently do this by passing `--end-group` after
228 // the first crate (when iterating backwards) that requires a lang item
229 // defined somewhere else. Once that's set then when we've defined all the
230 // necessary lang items we'll pass `--start-group`.
232 // Note that this isn't amazing logic for now but it should do the trick
233 // for the current implementation of the standard library.
234 let mut group_end = None;
235 let mut group_start = None;
236 let mut end_with = FxHashSet::default();
237 let info = &codegen_results.crate_info;
238 for &(cnum, _) in deps.iter().rev() {
239 if let Some(missing) = info.missing_lang_items.get(&cnum) {
240 end_with.extend(missing.iter().cloned());
241 if end_with.len() > 0 && group_end.is_none() {
242 group_end = Some(cnum);
245 end_with.retain(|item| info.lang_item_to_crate.get(item) != Some(&cnum));
246 if end_with.len() == 0 && group_end.is_some() {
247 group_start = Some(cnum);
252 // If we didn't end up filling in all lang items from upstream crates then
253 // we'll be filling it in with our crate. This probably means we're the
254 // standard library itself, so skip this for now.
255 if group_end.is_some() && group_start.is_none() {
259 let mut compiler_builtins = None;
261 for &(cnum, _) in deps.iter() {
262 if group_start == Some(cnum) {
266 // We may not pass all crates through to the linker. Some crates may
267 // appear statically in an existing dylib, meaning we'll pick up all the
268 // symbols from the dylib.
269 let src = &codegen_results.crate_info.used_crate_source[&cnum];
270 match data[cnum.as_usize() - 1] {
271 _ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
272 add_static_crate(cmd, sess, codegen_results, tmpdir, crate_type, cnum);
274 _ if codegen_results.crate_info.sanitizer_runtime == Some(cnum) => {
275 link_sanitizer_runtime(cmd, sess, codegen_results, tmpdir, cnum);
277 // compiler-builtins are always placed last to ensure that they're
279 _ if codegen_results.crate_info.compiler_builtins == Some(cnum) => {
280 assert!(compiler_builtins.is_none());
281 compiler_builtins = Some(cnum);
284 Linkage::IncludedFromDylib => {}
286 add_static_crate(cmd, sess, codegen_results, tmpdir, crate_type, cnum);
288 Linkage::Dynamic => {
289 add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0)
293 if group_end == Some(cnum) {
298 // compiler-builtins are always placed last to ensure that they're
300 // We must always link the `compiler_builtins` crate statically. Even if it
301 // was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic`
303 if let Some(cnum) = compiler_builtins {
304 add_static_crate(cmd, sess, codegen_results, tmpdir, crate_type, cnum);
307 // Converts a library file-stem into a cc -l argument
308 fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
309 if stem.starts_with("lib") && !config.target.options.is_like_windows {
316 // We must link the sanitizer runtime using -Wl,--whole-archive but since
317 // it's packed in a .rlib, it contains stuff that are not objects that will
318 // make the linker error. So we must remove those bits from the .rlib before
320 fn link_sanitizer_runtime(cmd: &mut dyn Linker,
322 codegen_results: &CodegenResults,
325 let src = &codegen_results.crate_info.used_crate_source[&cnum];
326 let cratepath = &src.rlib.as_ref().unwrap().0;
328 if sess.target.target.options.is_like_osx {
329 // On Apple platforms, the sanitizer is always built as a dylib, and
330 // LLVM will link to `@rpath/*.dylib`, so we need to specify an
331 // rpath to the library as well (the rpath should be absolute, see
332 // PR #41352 for details).
334 // FIXME: Remove this logic into librustc_*san once Cargo supports it
335 let rpath = cratepath.parent().unwrap();
336 let rpath = rpath.to_str().expect("non-utf8 component in path");
337 cmd.args(&["-Wl,-rpath".into(), "-Xlinker".into(), rpath.into()]);
340 let dst = tmpdir.join(cratepath.file_name().unwrap());
341 let cfg = archive_config(sess, &dst, Some(cratepath));
342 let mut archive = ArchiveBuilder::new(cfg);
343 archive.update_symbols();
345 for f in archive.src_files() {
346 if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME {
347 archive.remove_file(&f);
354 cmd.link_whole_rlib(&dst);
357 // Adds the static "rlib" versions of all crates to the command line.
358 // There's a bit of magic which happens here specifically related to LTO and
359 // dynamic libraries. Specifically:
361 // * For LTO, we remove upstream object files.
362 // * For dylibs we remove metadata and bytecode from upstream rlibs
364 // When performing LTO, almost(*) all of the bytecode from the upstream
365 // libraries has already been included in our object file output. As a
366 // result we need to remove the object files in the upstream libraries so
367 // the linker doesn't try to include them twice (or whine about duplicate
368 // symbols). We must continue to include the rest of the rlib, however, as
369 // it may contain static native libraries which must be linked in.
371 // (*) Crates marked with `#![no_builtins]` don't participate in LTO and
372 // their bytecode wasn't included. The object files in those libraries must
373 // still be passed to the linker.
375 // When making a dynamic library, linkers by default don't include any
376 // object files in an archive if they're not necessary to resolve the link.
377 // We basically want to convert the archive (rlib) to a dylib, though, so we
378 // *do* want everything included in the output, regardless of whether the
379 // linker thinks it's needed or not. As a result we must use the
380 // --whole-archive option (or the platform equivalent). When using this
381 // option the linker will fail if there are non-objects in the archive (such
382 // as our own metadata and/or bytecode). All in all, for rlibs to be
383 // entirely included in dylibs, we need to remove all non-object files.
385 // Note, however, that if we're not doing LTO or we're not producing a dylib
386 // (aka we're making an executable), we can just pass the rlib blindly to
387 // the linker (fast) because it's fine if it's not actually included as
388 // we're at the end of the dependency chain.
389 fn add_static_crate(cmd: &mut dyn Linker,
391 codegen_results: &CodegenResults,
393 crate_type: config::CrateType,
395 let src = &codegen_results.crate_info.used_crate_source[&cnum];
396 let cratepath = &src.rlib.as_ref().unwrap().0;
398 // See the comment above in `link_staticlib` and `link_rlib` for why if
399 // there's a static library that's not relevant we skip all object
401 let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
402 let skip_native = native_libs.iter().any(|lib| {
403 lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib)
406 if (!are_upstream_rust_objects_already_included(sess) ||
407 ignored_for_lto(sess, &codegen_results.crate_info, cnum)) &&
408 crate_type != config::CrateType::Dylib &&
410 cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
414 let dst = tmpdir.join(cratepath.file_name().unwrap());
415 let name = cratepath.file_name().unwrap().to_str().unwrap();
416 let name = &name[3..name.len() - 5]; // chop off lib/.rlib
418 time(sess, &format!("altering {}.rlib", name), || {
419 let cfg = archive_config(sess, &dst, Some(cratepath));
420 let mut archive = ArchiveBuilder::new(cfg);
421 archive.update_symbols();
423 let mut any_objects = false;
424 for f in archive.src_files() {
425 if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME {
426 archive.remove_file(&f);
430 let canonical = f.replace("-", "_");
431 let canonical_name = name.replace("-", "_");
433 // Look for `.rcgu.o` at the end of the filename to conclude
434 // that this is a Rust-related object file.
435 fn looks_like_rust(s: &str) -> bool {
436 let path = Path::new(s);
437 let ext = path.extension().and_then(|s| s.to_str());
438 if ext != Some(OutputType::Object.extension()) {
441 let ext2 = path.file_stem()
442 .and_then(|s| Path::new(s).extension())
443 .and_then(|s| s.to_str());
444 ext2 == Some(RUST_CGU_EXT)
448 canonical.starts_with(&canonical_name) &&
451 // If we've been requested to skip all native object files
452 // (those not generated by the rust compiler) then we can skip
453 // this file. See above for why we may want to do this.
454 let skip_because_cfg_say_so = skip_native && !is_rust_object;
456 // If we're performing LTO and this is a rust-generated object
457 // file, then we don't need the object file as it's part of the
458 // LTO module. Note that `#![no_builtins]` is excluded from LTO,
459 // though, so we let that object file slide.
460 let skip_because_lto = are_upstream_rust_objects_already_included(sess) &&
462 (sess.target.target.options.no_builtins ||
463 !codegen_results.crate_info.is_no_builtins.contains(&cnum));
465 if skip_because_cfg_say_so || skip_because_lto {
466 archive.remove_file(&f);
477 // If we're creating a dylib, then we need to include the
478 // whole of each object in our archive into that artifact. This is
479 // because a `dylib` can be reused as an intermediate artifact.
481 // Note, though, that we don't want to include the whole of a
482 // compiler-builtins crate (e.g. compiler-rt) because it'll get
483 // repeatedly linked anyway.
484 if crate_type == config::CrateType::Dylib &&
485 codegen_results.crate_info.compiler_builtins != Some(cnum) {
486 cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
488 cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
493 // Same thing as above, but for dynamic crates instead of static crates.
494 fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
495 // If we're performing LTO, then it should have been previously required
496 // that all upstream rust dependencies were available in an rlib format.
497 assert!(!are_upstream_rust_objects_already_included(sess));
499 // Just need to tell the linker about where the library lives and
501 let parent = cratepath.parent();
502 if let Some(dir) = parent {
503 cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
505 let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
506 cmd.link_rust_dylib(&unlib(&sess.target, filestem),
507 parent.unwrap_or(Path::new("")));
511 // # Native library linking
513 // User-supplied library search paths (-L on the command line). These are
514 // the same paths used to find Rust crates, so some of them may have been
515 // added already by the previous crate linking code. This only allows them
516 // to be found at compile time so it is still entirely up to outside
517 // forces to make sure that library can be found at runtime.
519 // Also note that the native libraries linked here are only the ones located
520 // in the current crate. Upstream crates with native library dependencies
521 // may have their native library pulled in above.
522 pub fn add_local_native_libraries(cmd: &mut dyn Linker,
524 codegen_results: &CodegenResults) {
525 let filesearch = sess.target_filesearch(PathKind::All);
526 for search_path in filesearch.search_paths() {
527 match search_path.kind {
528 PathKind::Framework => { cmd.framework_path(&search_path.dir); }
529 _ => { cmd.include_path(&fix_windows_verbatim_for_gcc(&search_path.dir)); }
533 let relevant_libs = codegen_results.crate_info.used_libraries.iter().filter(|l| {
534 relevant_lib(sess, l)
537 let search_path = archive_search_paths(sess);
538 for lib in relevant_libs {
539 let name = match lib.name {
544 NativeLibraryKind::NativeUnknown => cmd.link_dylib(&name.as_str()),
545 NativeLibraryKind::NativeFramework => cmd.link_framework(&name.as_str()),
546 NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(&name.as_str()),
547 NativeLibraryKind::NativeStatic => cmd.link_whole_staticlib(&name.as_str(),
553 // Link in all of our upstream crates' native dependencies. Remember that
554 // all of these upstream native dependencies are all non-static
555 // dependencies. We've got two cases then:
557 // 1. The upstream crate is an rlib. In this case we *must* link in the
558 // native dependency because the rlib is just an archive.
560 // 2. The upstream crate is a dylib. In order to use the dylib, we have to
561 // have the dependency present on the system somewhere. Thus, we don't
562 // gain a whole lot from not linking in the dynamic dependency to this
565 // The use case for this is a little subtle. In theory the native
566 // dependencies of a crate are purely an implementation detail of the crate
567 // itself, but the problem arises with generic and inlined functions. If a
568 // generic function calls a native function, then the generic function must
569 // be instantiated in the target crate, meaning that the native symbol must
570 // also be resolved in the target crate.
571 pub fn add_upstream_native_libraries(cmd: &mut dyn Linker,
573 codegen_results: &CodegenResults,
574 crate_type: config::CrateType) {
575 // Be sure to use a topological sorting of crates because there may be
576 // interdependencies between native libraries. When passing -nodefaultlibs,
577 // for example, almost all native libraries depend on libc, so we have to
578 // make sure that's all the way at the right (liblibc is near the base of
579 // the dependency chain).
581 // This passes RequireStatic, but the actual requirement doesn't matter,
582 // we're just getting an ordering of crate numbers, we're not worried about
584 let formats = sess.dependency_formats.borrow();
585 let data = formats.get(&crate_type).unwrap();
587 let crates = &codegen_results.crate_info.used_crates_static;
588 for &(cnum, _) in crates {
589 for lib in codegen_results.crate_info.native_libraries[&cnum].iter() {
590 let name = match lib.name {
594 if !relevant_lib(sess, &lib) {
598 NativeLibraryKind::NativeUnknown => cmd.link_dylib(&name.as_str()),
599 NativeLibraryKind::NativeFramework => cmd.link_framework(&name.as_str()),
600 NativeLibraryKind::NativeStaticNobundle => {
601 // Link "static-nobundle" native libs only if the crate they originate from
602 // is being linked statically to the current crate. If it's linked dynamically
603 // or is an rlib already included via some other dylib crate, the symbols from
604 // native libs will have already been included in that dylib.
605 if data[cnum.as_usize() - 1] == Linkage::Static {
606 cmd.link_staticlib(&name.as_str())
609 // ignore statically included native libraries here as we've
610 // already included them when we included the rust library
612 NativeLibraryKind::NativeStatic => {}
618 fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool {
620 Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None),
625 fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
629 // If we defer LTO to the linker, we haven't run LTO ourselves, so
630 // any upstream object files have not been copied yet.
631 !sess.opts.debugging_opts.cross_lang_lto.enabled()
634 Lto::ThinLocal => false,