Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc: --emit=rlibmeta outputs an rlib with only metadata, works with -Z no-trans. #26234

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,10 @@ fn encode_symbol(ecx: &EncodeContext,
rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
}
None => {
ecx.diag.handler().bug(
&format!("encode_symbol: id not found {}", id));
if !ecx.tcx.sess.opts.no_trans {
ecx.diag.handler().bug(
&format!("encode_symbol: id not found {}", id));
}
}
}
}
Expand Down
48 changes: 27 additions & 21 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ pub enum OutputType {
OutputTypeObject,
OutputTypeExe,
OutputTypeDepInfo,
OutputTypeRlibMeta,
}

#[derive(Clone)]
Expand Down Expand Up @@ -183,6 +184,7 @@ impl OutputFilenames {
OutputTypeLlvmAssembly => base.with_extension("ll"),
OutputTypeObject => base.with_extension("o"),
OutputTypeDepInfo => base.with_extension("d"),
OutputTypeRlibMeta => base.with_extension("rmeta"),
OutputTypeExe => base,
}
}
Expand Down Expand Up @@ -785,7 +787,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
"NAME"),
opt::multi("", "emit", "Comma separated list of types of output for \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

manpage must be updated too.

the compiler to emit",
"[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
"[asm|llvm-bc|llvm-ir|obj|link|dep-info|rlibmeta]"),
opt::multi("", "print", "Comma separated list of compiler information to \
print on stdout",
"[crate-name|file-names|sysroot]"),
Expand Down Expand Up @@ -886,29 +888,33 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}

let mut output_types = Vec::new();
if !debugging_opts.parse_only && !no_trans {
let unparsed_output_types = matches.opt_strs("emit");
for unparsed_output_type in &unparsed_output_types {
for part in unparsed_output_type.split(',') {
let output_type = match part {
"asm" => OutputTypeAssembly,
"llvm-ir" => OutputTypeLlvmAssembly,
"llvm-bc" => OutputTypeBitcode,
"obj" => OutputTypeObject,
"link" => OutputTypeExe,
"dep-info" => OutputTypeDepInfo,
_ => {
early_error(&format!("unknown emission type: `{}`",
part))
}
};
output_types.push(output_type)
}
let unparsed_output_types = matches.opt_strs("emit");
for unparsed_output_type in &unparsed_output_types {
for part in unparsed_output_type.split(',') {
let output_type = match part {
"asm" => OutputTypeAssembly,
"llvm-ir" => OutputTypeLlvmAssembly,
"llvm-bc" => OutputTypeBitcode,
"obj" => OutputTypeObject,
"link" => OutputTypeExe,
"dep-info" => OutputTypeDepInfo,
"rlibmeta" => OutputTypeRlibMeta,
_ => {
early_error(&format!("unknown emission type: `{}`",
part))
}
};
output_types.push(output_type)
}
};
}
output_types.sort();
output_types.dedup();
if output_types.is_empty() {

if debugging_opts.parse_only {
output_types = vec![];
} else if no_trans {
output_types.retain(|&x| x == OutputTypeRlibMeta);
} else if output_types.is_empty() {
output_types.push(OutputTypeExe);
}

Expand Down
23 changes: 18 additions & 5 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ pub fn compile_input(sess: Session,
CompileState::state_after_expand(input,
&sess,
outdir,
&outputs,
&expanded_crate,
&id[..]));

Expand All @@ -115,6 +116,7 @@ pub fn compile_input(sess: Session,
CompileState::state_after_write_deps(input,
&sess,
outdir,
&outputs,
&ast_map,
&ast_map.krate(),
&id[..]));
Expand All @@ -130,6 +132,7 @@ pub fn compile_input(sess: Session,
CompileState::state_after_analysis(input,
&analysis.ty_cx.sess,
outdir,
&outputs,
analysis.ty_cx.map.krate(),
&analysis,
&analysis.ty_cx));
Expand Down Expand Up @@ -157,6 +160,7 @@ pub fn compile_input(sess: Session,
CompileState::state_after_llvm(input,
&sess,
outdir,
&outputs,
&trans));

phase_6_link_output(&sess, &trans, &outputs);
Expand Down Expand Up @@ -280,19 +284,22 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
fn state_after_expand(input: &'a Input,
session: &'a Session,
out_dir: &'a Option<PathBuf>,
outputs: &'a OutputFilenames,
expanded_crate: &'a ast::Crate,
crate_name: &'a str)
-> CompileState<'a, 'ast, 'tcx> {
CompileState {
crate_name: Some(crate_name),
expanded_crate: Some(expanded_crate),
output_filenames: Some(outputs),
.. CompileState::empty(input, session, out_dir)
}
}

fn state_after_write_deps(input: &'a Input,
session: &'a Session,
out_dir: &'a Option<PathBuf>,
outputs: &'a OutputFilenames,
ast_map: &'a ast_map::Map<'ast>,
expanded_crate: &'a ast::Crate,
crate_name: &'a str)
Expand All @@ -301,13 +308,15 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
crate_name: Some(crate_name),
ast_map: Some(ast_map),
expanded_crate: Some(expanded_crate),
output_filenames: Some(outputs),
.. CompileState::empty(input, session, out_dir)
}
}

fn state_after_analysis(input: &'a Input,
session: &'a Session,
out_dir: &'a Option<PathBuf>,
outputs: &'a OutputFilenames,
expanded_crate: &'a ast::Crate,
analysis: &'a ty::CrateAnalysis<'tcx>,
tcx: &'a ty::ctxt<'tcx>)
Expand All @@ -316,6 +325,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
analysis: Some(analysis),
tcx: Some(tcx),
expanded_crate: Some(expanded_crate),
output_filenames: Some(outputs),
.. CompileState::empty(input, session, out_dir)
}
}
Expand All @@ -324,10 +334,12 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
fn state_after_llvm(input: &'a Input,
session: &'a Session,
out_dir: &'a Option<PathBuf>,
outputs: &'a OutputFilenames,
trans: &'a trans::CrateTranslation)
-> CompileState<'a, 'ast, 'tcx> {
CompileState {
trans: Some(trans),
output_filenames: Some(outputs),
.. CompileState::empty(input, session, out_dir)
}
}
Expand Down Expand Up @@ -788,12 +800,13 @@ fn write_out_deps(sess: &Session,
id: &str) {

let mut out_filenames = Vec::new();
for output_type in &sess.opts.output_types {
let file = outputs.path(*output_type);
match *output_type {
for &output_type in &sess.opts.output_types {
let file = outputs.path(output_type);
match output_type {
config::OutputTypeExe => {
for output in sess.crate_types.borrow().iter() {
let p = link::filename_for_input(sess, *output,
for &output in sess.crate_types.borrow().iter() {
let p = link::filename_for_input(sess, output,
output_type,
id, &file);
out_filenames.push(p);
}
Expand Down
16 changes: 15 additions & 1 deletion src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,22 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {

if sess.opts.no_trans {
control.after_analysis.stop = Compilation::Stop;
if sess.opts.output_types.contains(&config::OutputTypeRlibMeta) {
control.after_analysis.callback = box |state| {
use rustc_trans::trans;

let tcx = state.tcx.unwrap();
let name = state.analysis.unwrap().name.clone();
let trans = trans::trans_only_metadata(tcx, name);
let outputs = state.output_filenames.unwrap();
driver::phase_6_link_output(&tcx.sess, &trans, outputs);
};
}
}

if !sess.opts.output_types.iter().any(|&i| i == config::OutputTypeExe) {
if !sess.opts.output_types.iter().any(|&i|
i == config::OutputTypeExe ||
i == config::OutputTypeRlibMeta) {
control.after_llvm.stop = Compilation::Stop;
}

Expand Down Expand Up @@ -456,6 +469,7 @@ impl RustcDefaultCalls {
for &style in &crate_types {
let fname = link::filename_for_input(sess,
style,
config::OutputTypeExe,
&id,
&t_outputs.with_extension(""));
println!("{}", fname.file_name().unwrap()
Expand Down
75 changes: 55 additions & 20 deletions src/librustc_trans/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,25 +389,39 @@ pub fn link_binary(sess: &Session,
outputs: &OutputFilenames,
crate_name: &str) -> Vec<PathBuf> {
let mut out_filenames = Vec::new();
for &crate_type in sess.crate_types.borrow().iter() {
if sess.opts.output_types.contains(&config::OutputTypeExe) {
for &crate_type in sess.crate_types.borrow().iter() {
if invalid_output_for_target(sess, crate_type) {
sess.bug(&format!("invalid output type `{:?}` for target os `{}`",
crate_type, sess.opts.target_triple));
}
let out_file = link_binary_output(sess, trans, crate_type, outputs,
crate_name, None);
out_filenames.push(out_file);
}

// Remove the temporary object file and metadata if we aren't saving temps
if !sess.opts.cg.save_temps {
let obj_filename = outputs.temp_path(OutputTypeObject);
if !sess.opts.output_types.contains(&OutputTypeObject) {
remove(sess, &obj_filename);
}
remove(sess, &obj_filename.with_extension("metadata.o"));
}
}

// Attempt to output an rlib with just metadata, if that was requested.
if sess.opts.output_types.contains(&config::OutputTypeRlibMeta) {
let crate_type = config::CrateTypeRlib;
if invalid_output_for_target(sess, crate_type) {
sess.bug(&format!("invalid output type `{:?}` for target os `{}`",
crate_type, sess.opts.target_triple));
crate_type, sess.opts.target_triple));
}
let out_file = link_binary_output(sess, trans, crate_type, outputs,
crate_name);
crate_name, Some(config::OutputTypeRlibMeta));
out_filenames.push(out_file);
}

// Remove the temporary object file and metadata if we aren't saving temps
if !sess.opts.cg.save_temps {
let obj_filename = outputs.temp_path(OutputTypeObject);
if !sess.opts.output_types.contains(&OutputTypeObject) {
remove(sess, &obj_filename);
}
remove(sess, &obj_filename.with_extension("metadata.o"));
}

out_filenames
}

Expand Down Expand Up @@ -449,12 +463,18 @@ fn is_writeable(p: &Path) -> bool {

pub fn filename_for_input(sess: &Session,
crate_type: config::CrateType,
output_type: config::OutputType,
name: &str,
out_filename: &Path) -> PathBuf {
let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
match crate_type {
config::CrateTypeRlib => {
out_filename.with_file_name(&format!("lib{}.rlib", libname))
let suffix = if output_type == config::OutputTypeRlibMeta {
".rmeta"
} else {
""
};
out_filename.with_file_name(&format!("lib{}{}.rlib", libname, suffix))
}
config::CrateTypeDylib => {
let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
Expand Down Expand Up @@ -482,13 +502,16 @@ fn link_binary_output(sess: &Session,
trans: &CrateTranslation,
crate_type: config::CrateType,
outputs: &OutputFilenames,
crate_name: &str) -> PathBuf {
crate_name: &str,
custom_rlib_emission: Option<config::OutputType>)
-> PathBuf {
let obj_filename = outputs.temp_path(OutputTypeObject);
let out_filename = match outputs.single_output_file {
Some(ref file) => file.clone(),
None => {
let out_filename = outputs.path(OutputTypeExe);
filename_for_input(sess, crate_type, crate_name, &out_filename)
let output_type = custom_rlib_emission.unwrap_or(OutputTypeExe);
let out_filename = outputs.path(output_type);
filename_for_input(sess, crate_type, output_type, crate_name, &out_filename)
}
};

Expand All @@ -511,7 +534,12 @@ fn link_binary_output(sess: &Session,

match crate_type {
config::CrateTypeRlib => {
link_rlib(sess, Some(trans), &obj_filename, &out_filename).build();
let obj_filename = if custom_rlib_emission.is_some() {
None
} else {
Some(&*obj_filename)
};
link_rlib(sess, Some(trans), obj_filename, &out_filename).build();
}
config::CrateTypeStaticlib => {
link_staticlib(sess, &obj_filename, &out_filename);
Expand Down Expand Up @@ -544,7 +572,7 @@ fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
// native libraries and inserting all of the contents into this archive.
fn link_rlib<'a>(sess: &'a Session,
trans: Option<&CrateTranslation>, // None == no metadata/bytecode
obj_filename: &Path,
obj_filename: Option<&Path>,
out_filename: &Path) -> ArchiveBuilder<'a> {
info!("preparing rlib from {:?} to {:?}", obj_filename, out_filename);
let handler = &sess.diagnostic().handler;
Expand All @@ -557,7 +585,7 @@ fn link_rlib<'a>(sess: &'a Session,
ar_prog: get_ar_prog(sess),
};
let mut ab = ArchiveBuilder::create(config);
ab.add_file(obj_filename).unwrap();
obj_filename.map(|file| ab.add_file(file).unwrap());

for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
match kind {
Expand Down Expand Up @@ -619,6 +647,13 @@ fn link_rlib<'a>(sess: &'a Session,
ab.add_file(&metadata).unwrap();
remove(sess, &metadata);

// Nothing else to add if we have no code.
let obj_filename = if let Some(file) = obj_filename {
file
} else {
return ab;
};

// For LTO purposes, the bytecode of this library is also inserted
// into the archive. If codegen_units > 1, we insert each of the
// bitcode files.
Expand Down Expand Up @@ -734,7 +769,7 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write,
// link in the metadata object file (and also don't prepare the archive with a
// metadata file).
fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
let ab = link_rlib(sess, None, obj_filename, out_filename);
let ab = link_rlib(sess, None, Some(obj_filename), out_filename);
let mut ab = match sess.target.target.options.is_like_osx {
true => ab.build().extend(),
false => ab,
Expand Down
Loading