| 28 | use std::sync::Arc; |
| 29 | |
| 30 | pub fn link( |
| 31 | sess: &Session, |
| 32 | codegen_results: &CodegenResults, |
| 33 | outputs: &OutputFilenames, |
| 34 | crate_name: &str, |
| 35 | ) { |
| 36 | let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); |
| 37 | for &crate_type in sess.crate_types().iter() { |
| 38 | if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen()) |
| 39 | && !output_metadata |
| 40 | && crate_type == CrateType::Executable |
| 41 | { |
| 42 | continue; |
| 43 | } |
| 44 | |
| 45 | if invalid_output_for_target(sess, crate_type) { |
| 46 | bug!( |
| 47 | "invalid output type `{:?}` for target os `{}`", |
| 48 | crate_type, |
| 49 | sess.opts.target_triple |
| 50 | ); |
| 51 | } |
| 52 | |
| 53 | for obj in codegen_results |
| 54 | .modules |
| 55 | .iter() |
| 56 | .filter_map(|m| m.object.as_ref()) |
| 57 | { |
| 58 | check_file_is_writeable(obj, sess); |
| 59 | } |
| 60 | |
| 61 | if outputs.outputs.should_codegen() { |
| 62 | let out_filename = out_filename(sess, crate_type, outputs, Symbol::intern(crate_name)); |
| 63 | match crate_type { |
| 64 | CrateType::Rlib => { |
| 65 | link_rlib(sess, codegen_results, &out_filename); |
| 66 | } |
| 67 | CrateType::Executable | CrateType::Cdylib | CrateType::Dylib => { |
| 68 | // HACK(eddyb) there's no way way to access `outputs.filestem`, |
| 69 | // so we pay the cost of building a whole `PathBuf` instead. |
| 70 | let disambiguated_crate_name_for_dumps = outputs |
| 71 | .with_extension("") |
| 72 | .file_name() |
| 73 | .unwrap() |
| 74 | .to_os_string(); |
| 75 | |
| 76 | link_exe( |
| 77 | sess, |
| 78 | crate_type, |
| 79 | &out_filename, |
| 80 | codegen_results, |
| 81 | outputs, |
| 82 | &disambiguated_crate_name_for_dumps, |
| 83 | ); |
| 84 | } |
| 85 | other => { |
| 86 | sess.err(format!("CrateType {other:?} not supported yet")); |
| 87 | } |