1
Fork 0

Serialize OutputFilenames into rmeta file

This ensures that linking will use the correct crate name even when
`#![crate_name = "..."]` is used to specify the crate name.
This commit is contained in:
bjorn3 2023-11-04 15:49:57 +00:00
parent eacbe65dfe
commit 98a6eaa7f8
5 changed files with 22 additions and 27 deletions

View file

@ -216,6 +216,7 @@ impl CodegenResults {
sess: &Session, sess: &Session,
rlink_file: &Path, rlink_file: &Path,
codegen_results: &CodegenResults, codegen_results: &CodegenResults,
outputs: &OutputFilenames,
) -> Result<usize, io::Error> { ) -> Result<usize, io::Error> {
let mut encoder = FileEncoder::new(rlink_file)?; let mut encoder = FileEncoder::new(rlink_file)?;
encoder.emit_raw_bytes(RLINK_MAGIC); encoder.emit_raw_bytes(RLINK_MAGIC);
@ -224,10 +225,14 @@ impl CodegenResults {
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes()); encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
encoder.emit_str(sess.cfg_version); encoder.emit_str(sess.cfg_version);
Encodable::encode(codegen_results, &mut encoder); Encodable::encode(codegen_results, &mut encoder);
Encodable::encode(outputs, &mut encoder);
encoder.finish().map_err(|(_path, err)| err) encoder.finish().map_err(|(_path, err)| err)
} }
pub fn deserialize_rlink(sess: &Session, data: Vec<u8>) -> Result<Self, CodegenErrors> { pub fn deserialize_rlink(
sess: &Session,
data: Vec<u8>,
) -> Result<(Self, OutputFilenames), CodegenErrors> {
// The Decodable machinery is not used here because it panics if the input data is invalid // The Decodable machinery is not used here because it panics if the input data is invalid
// and because its internal representation may change. // and because its internal representation may change.
if !data.starts_with(RLINK_MAGIC) { if !data.starts_with(RLINK_MAGIC) {
@ -256,6 +261,7 @@ impl CodegenResults {
} }
let codegen_results = CodegenResults::decode(&mut decoder); let codegen_results = CodegenResults::decode(&mut decoder);
Ok(codegen_results) let outputs = OutputFilenames::decode(&mut decoder);
Ok((codegen_results, outputs))
} }
} }

View file

@ -648,12 +648,11 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
fn process_rlink(sess: &Session, compiler: &interface::Compiler) { fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
assert!(sess.opts.unstable_opts.link_only); assert!(sess.opts.unstable_opts.link_only);
if let Input::File(file) = &sess.io.input { if let Input::File(file) = &sess.io.input {
let outputs = compiler.build_output_filenames(sess, &[]);
let rlink_data = fs::read(file).unwrap_or_else(|err| { let rlink_data = fs::read(file).unwrap_or_else(|err| {
sess.emit_fatal(RlinkUnableToRead { err }); sess.emit_fatal(RlinkUnableToRead { err });
}); });
let codegen_results = match CodegenResults::deserialize_rlink(sess, rlink_data) { let (codegen_results, outputs) = match CodegenResults::deserialize_rlink(sess, rlink_data) {
Ok(codegen) => codegen, Ok((codegen, outputs)) => (codegen, outputs),
Err(err) => { Err(err) => {
match err { match err {
CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType), CodegenErrors::WrongFileType => sess.emit_fatal(RLinkWrongFileType),

View file

@ -1,7 +1,7 @@
use crate::util; use crate::util;
use rustc_ast::token; use rustc_ast::token;
use rustc_ast::{self as ast, LitKind, MetaItemKind}; use rustc_ast::{LitKind, MetaItemKind};
use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::defer; use rustc_data_structures::defer;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@ -15,9 +15,7 @@ use rustc_middle::{bug, ty};
use rustc_parse::maybe_new_parser_from_source_str; use rustc_parse::maybe_new_parser_from_source_str;
use rustc_query_impl::QueryCtxt; use rustc_query_impl::QueryCtxt;
use rustc_query_system::query::print_query_stack; use rustc_query_system::query::print_query_stack;
use rustc_session::config::{ use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName, OutputFilenames,
};
use rustc_session::filesearch::sysroot_candidates; use rustc_session::filesearch::sysroot_candidates;
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_session::{lint, CompilerIO, EarlyErrorHandler, Session}; use rustc_session::{lint, CompilerIO, EarlyErrorHandler, Session};
@ -43,19 +41,6 @@ pub struct Compiler {
pub(crate) override_queries: Option<fn(&Session, &mut Providers)>, pub(crate) override_queries: Option<fn(&Session, &mut Providers)>,
} }
impl Compiler {
pub fn build_output_filenames(
&self,
sess: &Session,
attrs: &[ast::Attribute],
) -> OutputFilenames {
util::build_output_filenames(
sess,
rustc_session::output::find_crate_name(sess, attrs).to_string(),
)
}
}
/// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`. /// Converts strings provided as `--cfg [cfgspec]` into a `Cfg`.
pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg { pub(crate) fn parse_cfg(handler: &EarlyErrorHandler, cfgs: Vec<String>) -> Cfg {
cfgs.into_iter() cfgs.into_iter()

View file

@ -273,8 +273,13 @@ impl Linker {
if sess.opts.unstable_opts.no_link { if sess.opts.unstable_opts.no_link {
let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT); let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT);
CodegenResults::serialize_rlink(sess, &rlink_file, &codegen_results) CodegenResults::serialize_rlink(
.map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?; sess,
&rlink_file,
&codegen_results,
&*self.output_filenames,
)
.map_err(|error| sess.emit_fatal(FailedWritingFile { path: &rlink_file, error }))?;
return Ok(()); return Ok(());
} }

View file

@ -580,7 +580,7 @@ pub enum ResolveDocLinks {
/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break /// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
/// dependency tracking for command-line arguments. Also only hash keys, since tracking /// dependency tracking for command-line arguments. Also only hash keys, since tracking
/// should only depend on the output types, not the paths they're written to. /// should only depend on the output types, not the paths they're written to.
#[derive(Clone, Debug, Hash, HashStable_Generic)] #[derive(Clone, Debug, Hash, HashStable_Generic, Encodable, Decodable)]
pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>); pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>);
impl OutputTypes { impl OutputTypes {
@ -818,7 +818,7 @@ impl Input {
} }
} }
#[derive(Clone, Hash, Debug, HashStable_Generic, PartialEq)] #[derive(Clone, Hash, Debug, HashStable_Generic, PartialEq, Encodable, Decodable)]
pub enum OutFileName { pub enum OutFileName {
Real(PathBuf), Real(PathBuf),
Stdout, Stdout,
@ -890,7 +890,7 @@ impl OutFileName {
} }
} }
#[derive(Clone, Hash, Debug, HashStable_Generic)] #[derive(Clone, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
pub struct OutputFilenames { pub struct OutputFilenames {
pub out_directory: PathBuf, pub out_directory: PathBuf,
/// Crate name. Never contains '-'. /// Crate name. Never contains '-'.