Skip to content

Commit 344f8d9

Browse files
authored
Rollup merge of rust-lang#68487 - 0dvictor:nolink, r=tmandry
[experiment] Support linking from a .rlink file Flag `-Z no-link` was previously introduced, which allows creating an `.rlink` file to perform compilation without linking. This change enables linking from an `.rlink` file. Part of Issue rust-lang#64191
2 parents b6a9aa9 + a47fdb9 commit 344f8d9

File tree

7 files changed

+57
-8
lines changed

7 files changed

+57
-8
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3552,6 +3552,7 @@ dependencies = [
35523552
"log",
35533553
"rustc",
35543554
"rustc_ast_pretty",
3555+
"rustc_codegen_ssa",
35553556
"rustc_codegen_utils",
35563557
"rustc_data_structures",
35573558
"rustc_error_codes",

src/librustc_codegen_llvm/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use syntax::expand::allocator::AllocatorKind;
3232

3333
use rustc::dep_graph::DepGraph;
3434
use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
35-
use rustc::session::config::{OptLevel, OutputFilenames, PrintRequest};
35+
use rustc::session::config::{self, OptLevel, OutputFilenames, PrintRequest};
3636
use rustc::session::Session;
3737
use rustc::ty::{self, TyCtxt};
3838
use rustc::util::common::ErrorReported;
@@ -301,7 +301,7 @@ impl CodegenBackend for LlvmCodegenBackend {
301301
let rlink_data = json::encode(&codegen_results).map_err(|err| {
302302
sess.fatal(&format!("failed to encode rlink: {}", err));
303303
})?;
304-
let rlink_file = outputs.with_extension("rlink");
304+
let rlink_file = outputs.with_extension(config::RLINK_EXT);
305305
fs::write(&rlink_file, rlink_data).map_err(|err| {
306306
sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
307307
})?;

src/librustc_driver/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ rustc_mir = { path = "../librustc_mir" }
2626
rustc_parse = { path = "../librustc_parse" }
2727
rustc_plugin_impl = { path = "../librustc_plugin_impl" }
2828
rustc_save_analysis = { path = "../librustc_save_analysis" }
29+
rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
2930
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
3031
rustc_error_codes = { path = "../librustc_error_codes" }
3132
rustc_interface = { path = "../librustc_interface" }

src/librustc_driver/lib.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,27 @@ use rustc::session::{config, DiagnosticOutput, Session};
2626
use rustc::session::{early_error, early_warn};
2727
use rustc::ty::TyCtxt;
2828
use rustc::util::common::ErrorReported;
29+
use rustc_codegen_ssa::CodegenResults;
2930
use rustc_codegen_utils::codegen_backend::CodegenBackend;
3031
use rustc_data_structures::profiling::print_time_passes_entry;
3132
use rustc_data_structures::sync::SeqCst;
3233
use rustc_errors::{registry::Registry, PResult};
3334
use rustc_feature::{find_gated_cfg, UnstableFeatures};
3435
use rustc_hir::def_id::LOCAL_CRATE;
35-
use rustc_interface::util::get_builtin_codegen_backend;
36+
use rustc_interface::util::{collect_crate_types, get_builtin_codegen_backend};
3637
use rustc_interface::{interface, Queries};
3738
use rustc_lint::LintStore;
3839
use rustc_metadata::locator;
3940
use rustc_save_analysis as save;
4041
use rustc_save_analysis::DumpHandler;
41-
use rustc_serialize::json::ToJson;
42+
use rustc_serialize::json::{self, ToJson};
4243

4344
use std::borrow::Cow;
4445
use std::cmp::max;
4546
use std::default::Default;
4647
use std::env;
4748
use std::ffi::OsString;
49+
use std::fs;
4850
use std::io::{self, Read, Write};
4951
use std::mem;
5052
use std::panic::{self, catch_unwind};
@@ -281,7 +283,8 @@ pub fn run_compiler(
281283
&matches,
282284
compiler.input(),
283285
)
284-
});
286+
})
287+
.and_then(|| RustcDefaultCalls::try_process_rlink(sess, compiler));
285288

286289
if should_stop == Compilation::Stop {
287290
return sess.compile_status();
@@ -588,6 +591,34 @@ fn show_content_with_pager(content: &String) {
588591
}
589592

590593
impl RustcDefaultCalls {
594+
fn process_rlink(sess: &Session, compiler: &interface::Compiler) -> Result<(), ErrorReported> {
595+
if let Input::File(file) = compiler.input() {
596+
// FIXME: #![crate_type] and #![crate_name] support not implemented yet
597+
let attrs = vec![];
598+
sess.crate_types.set(collect_crate_types(sess, &attrs));
599+
let outputs = compiler.build_output_filenames(&sess, &attrs);
600+
let rlink_data = fs::read_to_string(file).unwrap_or_else(|err| {
601+
sess.fatal(&format!("failed to read rlink file: {}", err));
602+
});
603+
let codegen_results: CodegenResults = json::decode(&rlink_data).unwrap_or_else(|err| {
604+
sess.fatal(&format!("failed to decode rlink: {}", err));
605+
});
606+
compiler.codegen_backend().link(&sess, Box::new(codegen_results), &outputs)
607+
} else {
608+
sess.fatal(&format!("rlink must be a file"))
609+
}
610+
}
611+
612+
pub fn try_process_rlink(sess: &Session, compiler: &interface::Compiler) -> Compilation {
613+
if sess.opts.debugging_opts.link_only {
614+
let result = RustcDefaultCalls::process_rlink(sess, compiler);
615+
abort_on_err(result, sess);
616+
Compilation::Stop
617+
} else {
618+
Compilation::Continue
619+
}
620+
}
621+
591622
pub fn list_metadata(
592623
sess: &Session,
593624
metadata_loader: &dyn MetadataLoader,
@@ -663,7 +694,7 @@ impl RustcDefaultCalls {
663694
println!("{}", id);
664695
continue;
665696
}
666-
let crate_types = rustc_interface::util::collect_crate_types(sess, attrs);
697+
let crate_types = collect_crate_types(sess, attrs);
667698
for &style in &crate_types {
668699
let fname = rustc_codegen_utils::link::filename_for_input(
669700
sess, style, &id, &t_outputs,

src/librustc_interface/interface.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ pub use crate::passes::BoxedResolver;
22
use crate::util;
33

44
use rustc::lint;
5-
use rustc::session::config::{self, ErrorOutputType, Input};
5+
use rustc::session::config::{self, ErrorOutputType, Input, OutputFilenames};
66
use rustc::session::early_error;
77
use rustc::session::{DiagnosticOutput, Session};
88
use rustc::ty;
@@ -20,7 +20,7 @@ use rustc_span::source_map::{FileLoader, FileName, SourceMap};
2020
use std::path::PathBuf;
2121
use std::result;
2222
use std::sync::{Arc, Mutex};
23-
use syntax::ast::MetaItemKind;
23+
use syntax::ast::{self, MetaItemKind};
2424
use syntax::token;
2525

2626
pub type Result<T> = result::Result<T, ErrorReported>;
@@ -61,6 +61,19 @@ impl Compiler {
6161
pub fn output_file(&self) -> &Option<PathBuf> {
6262
&self.output_file
6363
}
64+
pub fn build_output_filenames(
65+
&self,
66+
sess: &Session,
67+
attrs: &[ast::Attribute],
68+
) -> OutputFilenames {
69+
util::build_output_filenames(
70+
&self.input,
71+
&self.output_dir,
72+
&self.output_file,
73+
&attrs,
74+
&sess,
75+
)
76+
}
6477
}
6578

6679
/// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.

src/librustc_session/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ pub struct OutputFilenames {
465465

466466
impl_stable_hash_via_hash!(OutputFilenames);
467467

468+
pub const RLINK_EXT: &str = "rlink";
468469
pub const RUST_CGU_EXT: &str = "rcgu";
469470

470471
impl OutputFilenames {

src/librustc_session/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,4 +966,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
966966
"use Windows Control Flow Guard (`disabled`, `nochecks` or `checks`)"),
967967
no_link: bool = (false, parse_bool, [TRACKED],
968968
"compile without linking"),
969+
link_only: bool = (false, parse_bool, [TRACKED],
970+
"link the `.rlink` file generated by `-Z no-link`"),
969971
}

0 commit comments

Comments
 (0)