Skip to content

Commit b059a80

Browse files
committed
Support --emit=foo,metadata
1 parent 9c89166 commit b059a80

File tree

3 files changed

+66
-26
lines changed

3 files changed

+66
-26
lines changed

src/librustc/middle/dependency_format.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub fn calculate(sess: &session::Session) {
103103

104104
fn calculate_type(sess: &session::Session,
105105
ty: config::CrateType) -> DependencyList {
106-
if sess.opts.output_types.contains_key(&config::OutputType::Metadata) {
106+
if !sess.opts.output_types.should_trans() {
107107
return Vec::new();
108108
}
109109

src/librustc/session/config.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,19 @@ impl OutputTypes {
156156
pub fn values<'a>(&'a self) -> BTreeMapValuesIter<'a, OutputType, Option<PathBuf>> {
157157
self.0.values()
158158
}
159+
160+
// True if any of the output types require codegen or linking.
161+
pub fn should_trans(&self) -> bool {
162+
self.0.keys().any(|k| match *k {
163+
OutputType::Bitcode |
164+
OutputType::Assembly |
165+
OutputType::LlvmAssembly |
166+
OutputType::Object |
167+
OutputType::Exe => true,
168+
OutputType::Metadata |
169+
OutputType::DepInfo => false,
170+
})
171+
}
159172
}
160173

161174

src/librustc_trans/back/link.rs

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ pub fn link_binary(sess: &Session,
192192
for &crate_type in sess.crate_types.borrow().iter() {
193193
// Ignore executable crates if we have -Z no-trans, as they will error.
194194
if (sess.opts.debugging_opts.no_trans ||
195-
sess.opts.output_types.contains_key(&OutputType::Metadata)) &&
195+
!sess.opts.output_types.should_trans()) &&
196196
crate_type == config::CrateTypeExecutable {
197197
continue;
198198
}
@@ -201,13 +201,13 @@ pub fn link_binary(sess: &Session,
201201
bug!("invalid output type `{:?}` for target os `{}`",
202202
crate_type, sess.opts.target_triple);
203203
}
204-
let out_file = link_binary_output(sess, trans, crate_type, outputs, crate_name);
205-
out_filenames.push(out_file);
204+
let mut out_files = link_binary_output(sess, trans, crate_type, outputs, crate_name);
205+
out_filenames.append(&mut out_files);
206206
}
207207

208208
// Remove the temporary object file and metadata if we aren't saving temps
209209
if !sess.opts.cg.save_temps {
210-
if !sess.opts.output_types.contains_key(&OutputType::Metadata) {
210+
if sess.opts.output_types.should_trans() {
211211
for obj in object_filenames(trans, outputs) {
212212
remove(sess, &obj);
213213
}
@@ -256,16 +256,21 @@ fn is_writeable(p: &Path) -> bool {
256256
}
257257
}
258258

259+
fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilenames) -> PathBuf {
260+
let out_filename = outputs.single_output_file.clone()
261+
.unwrap_or(outputs
262+
.out_directory
263+
.join(&format!("lib{}{}.rmeta", crate_name, sess.opts.cg.extra_filename)));
264+
check_file_is_writeable(&out_filename, sess);
265+
out_filename
266+
}
267+
259268
pub fn filename_for_input(sess: &Session,
260269
crate_type: config::CrateType,
261270
crate_name: &str,
262271
outputs: &OutputFilenames) -> PathBuf {
263272
let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename);
264273

265-
if outputs.outputs.contains_key(&OutputType::Metadata) {
266-
return outputs.out_directory.join(&format!("lib{}.rmeta", libname));
267-
}
268-
269274
match crate_type {
270275
config::CrateTypeRlib => {
271276
outputs.out_directory.join(&format!("lib{}.rlib", libname))
@@ -327,37 +332,58 @@ pub fn each_linked_rlib(sess: &Session,
327332
}
328333
}
329334

335+
fn out_filename(sess: &Session,
336+
crate_type: config::CrateType,
337+
outputs: &OutputFilenames,
338+
crate_name: &str)
339+
-> PathBuf {
340+
let default_filename = filename_for_input(sess, crate_type, crate_name, outputs);
341+
let out_filename = outputs.outputs.get(&OutputType::Exe)
342+
.and_then(|s| s.to_owned())
343+
.or_else(|| outputs.single_output_file.clone())
344+
.unwrap_or(default_filename);
345+
346+
check_file_is_writeable(&out_filename, sess);
347+
348+
out_filename
349+
}
350+
351+
// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers
352+
// check this already -- however, the Linux linker will happily overwrite a
353+
// read-only file. We should be consistent.
354+
fn check_file_is_writeable(file: &Path, sess: &Session) {
355+
if !is_writeable(file) {
356+
sess.fatal(&format!("output file {} is not writeable -- check its \
357+
permissions", file.display()));
358+
}
359+
}
360+
330361
fn link_binary_output(sess: &Session,
331362
trans: &CrateTranslation,
332363
crate_type: config::CrateType,
333364
outputs: &OutputFilenames,
334-
crate_name: &str) -> PathBuf {
365+
crate_name: &str) -> Vec<PathBuf> {
335366
let objects = object_filenames(trans, outputs);
336-
let default_filename = filename_for_input(sess, crate_type, crate_name,
337-
outputs);
338-
let out_filename = outputs.outputs.get(&OutputType::Exe)
339-
.and_then(|s| s.to_owned())
340-
.or_else(|| outputs.single_output_file.clone())
341-
.unwrap_or(default_filename);
342367

343-
// Make sure files are writeable. Mac, FreeBSD, and Windows system linkers
344-
// check this already -- however, the Linux linker will happily overwrite a
345-
// read-only file. We should be consistent.
346-
for file in objects.iter().chain(Some(&out_filename)) {
347-
if !is_writeable(file) {
348-
sess.fatal(&format!("output file {} is not writeable -- check its \
349-
permissions", file.display()));
350-
}
368+
for file in &objects {
369+
check_file_is_writeable(file, sess);
351370
}
352371

353372
let tmpdir = match TempDir::new("rustc") {
354373
Ok(tmpdir) => tmpdir,
355374
Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
356375
};
357376

377+
let mut out_filenames = vec![];
378+
358379
if outputs.outputs.contains_key(&OutputType::Metadata) {
380+
let out_filename = filename_for_metadata(sess, crate_name, outputs);
359381
emit_metadata(sess, trans, &out_filename);
360-
} else {
382+
out_filenames.push(out_filename);
383+
}
384+
385+
if outputs.outputs.should_trans() {
386+
let out_filename = out_filename(sess, crate_type, outputs, crate_name);
361387
match crate_type {
362388
config::CrateTypeRlib => {
363389
link_rlib(sess, Some(trans), &objects, &out_filename,
@@ -371,9 +397,10 @@ fn link_binary_output(sess: &Session,
371397
outputs, tmpdir.path());
372398
}
373399
}
400+
out_filenames.push(out_filename);
374401
}
375402

376-
out_filename
403+
out_filenames
377404
}
378405

379406
fn object_filenames(trans: &CrateTranslation,

0 commit comments

Comments
 (0)