Skip to content

Commit e571f2d

Browse files
committed
Auto merge of #38571 - nrc:emit-metadata-change, r=alexcrichton
Change --crate-type metadata to --emit=metadata WIP
2 parents ebc293b + b059a80 commit e571f2d

File tree

19 files changed

+154
-77
lines changed

19 files changed

+154
-77
lines changed

src/librustc/middle/dependency_format.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ 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.should_trans() {
107+
return Vec::new();
108+
}
109+
106110
match ty {
107111
// If the global prefer_dynamic switch is turned off, first attempt
108112
// static linkage (this can fail).
@@ -114,7 +118,7 @@ fn calculate_type(sess: &session::Session,
114118

115119
// No linkage happens with rlibs, we just needed the metadata (which we
116120
// got long ago), so don't bother with anything.
117-
config::CrateTypeRlib | config::CrateTypeMetadata => return Vec::new(),
121+
config::CrateTypeRlib => return Vec::new(),
118122

119123
// Staticlibs and cdylibs must have all static dependencies. If any fail
120124
// to be found, we generate some nice pretty errors.

src/librustc/middle/reachable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
139139
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ReachableContext<'a, 'tcx> {
140140
let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
141141
*ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib ||
142-
*ty == config::CrateTypeProcMacro || *ty == config::CrateTypeMetadata
142+
*ty == config::CrateTypeProcMacro
143143
});
144144
ReachableContext {
145145
tcx: tcx,

src/librustc/middle/weak_lang_items.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
7575
config::CrateTypeCdylib |
7676
config::CrateTypeExecutable |
7777
config::CrateTypeStaticlib => true,
78-
config::CrateTypeRlib |
79-
config::CrateTypeMetadata => false,
78+
config::CrateTypeRlib => false,
8079
}
8180
});
8281
if !needs_check {

src/librustc/session/config.rs

+36-10
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ pub enum OutputType {
7373
Bitcode,
7474
Assembly,
7575
LlvmAssembly,
76+
Metadata,
7677
Object,
7778
Exe,
7879
DepInfo,
@@ -86,7 +87,8 @@ impl OutputType {
8687
OutputType::Bitcode |
8788
OutputType::Assembly |
8889
OutputType::LlvmAssembly |
89-
OutputType::Object => false,
90+
OutputType::Object |
91+
OutputType::Metadata => false,
9092
}
9193
}
9294

@@ -96,6 +98,7 @@ impl OutputType {
9698
OutputType::Assembly => "asm",
9799
OutputType::LlvmAssembly => "llvm-ir",
98100
OutputType::Object => "obj",
101+
OutputType::Metadata => "metadata",
99102
OutputType::Exe => "link",
100103
OutputType::DepInfo => "dep-info",
101104
}
@@ -107,6 +110,7 @@ impl OutputType {
107110
OutputType::Assembly => "s",
108111
OutputType::LlvmAssembly => "ll",
109112
OutputType::Object => "o",
113+
OutputType::Metadata => "rmeta",
110114
OutputType::DepInfo => "d",
111115
OutputType::Exe => "",
112116
}
@@ -152,6 +156,19 @@ impl OutputTypes {
152156
pub fn values<'a>(&'a self) -> BTreeMapValuesIter<'a, OutputType, Option<PathBuf>> {
153157
self.0.values()
154158
}
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+
}
155172
}
156173

157174

@@ -482,7 +499,6 @@ pub enum CrateType {
482499
CrateTypeStaticlib,
483500
CrateTypeCdylib,
484501
CrateTypeProcMacro,
485-
CrateTypeMetadata,
486502
}
487503

488504
#[derive(Clone, Hash)]
@@ -1159,12 +1175,12 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
11591175
assumed.", "[KIND=]NAME"),
11601176
opt::multi_s("", "crate-type", "Comma separated list of types of crates
11611177
for the compiler to emit",
1162-
"[bin|lib|rlib|dylib|cdylib|staticlib|metadata]"),
1178+
"[bin|lib|rlib|dylib|cdylib|staticlib]"),
11631179
opt::opt_s("", "crate-name", "Specify the name of the crate being built",
11641180
"NAME"),
11651181
opt::multi_s("", "emit", "Comma separated list of types of output for \
11661182
the compiler to emit",
1167-
"[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
1183+
"[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info]"),
11681184
opt::multi_s("", "print", "Comma separated list of compiler information to \
11691185
print on stdout", &print_opts.join("|")),
11701186
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
@@ -1293,7 +1309,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
12931309
};
12941310

12951311
let unparsed_crate_types = matches.opt_strs("crate-type");
1296-
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
1312+
let (crate_types, emit_metadata) = parse_crate_types_from_list(unparsed_crate_types)
12971313
.unwrap_or_else(|e| early_error(error_format, &e[..]));
12981314

12991315
let mut lint_opts = vec![];
@@ -1327,6 +1343,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
13271343
"llvm-ir" => OutputType::LlvmAssembly,
13281344
"llvm-bc" => OutputType::Bitcode,
13291345
"obj" => OutputType::Object,
1346+
"metadata" => OutputType::Metadata,
13301347
"link" => OutputType::Exe,
13311348
"dep-info" => OutputType::DepInfo,
13321349
part => {
@@ -1339,7 +1356,9 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
13391356
}
13401357
}
13411358
};
1342-
if output_types.is_empty() {
1359+
if emit_metadata {
1360+
output_types.insert(OutputType::Metadata, None);
1361+
} else if output_types.is_empty() {
13431362
output_types.insert(OutputType::Exe, None);
13441363
}
13451364

@@ -1541,8 +1560,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
15411560
cfg)
15421561
}
15431562

1544-
pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
1563+
pub fn parse_crate_types_from_list(list_list: Vec<String>)
1564+
-> Result<(Vec<CrateType>, bool), String> {
15451565
let mut crate_types: Vec<CrateType> = Vec::new();
1566+
let mut emit_metadata = false;
15461567
for unparsed_crate_type in &list_list {
15471568
for part in unparsed_crate_type.split(',') {
15481569
let new_part = match part {
@@ -1553,7 +1574,13 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
15531574
"cdylib" => CrateTypeCdylib,
15541575
"bin" => CrateTypeExecutable,
15551576
"proc-macro" => CrateTypeProcMacro,
1556-
"metadata" => CrateTypeMetadata,
1577+
// FIXME(#38640) remove this when Cargo is fixed.
1578+
"metadata" => {
1579+
early_warn(ErrorOutputType::default(), "--crate-type=metadata is deprecated, \
1580+
prefer --emit=metadata");
1581+
emit_metadata = true;
1582+
CrateTypeRlib
1583+
}
15571584
_ => {
15581585
return Err(format!("unknown crate type: `{}`",
15591586
part));
@@ -1565,7 +1592,7 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
15651592
}
15661593
}
15671594

1568-
return Ok(crate_types);
1595+
return Ok((crate_types, emit_metadata));
15691596
}
15701597

15711598
pub mod nightly_options {
@@ -1638,7 +1665,6 @@ impl fmt::Display for CrateType {
16381665
CrateTypeStaticlib => "staticlib".fmt(f),
16391666
CrateTypeCdylib => "cdylib".fmt(f),
16401667
CrateTypeProcMacro => "proc-macro".fmt(f),
1641-
CrateTypeMetadata => "metadata".fmt(f),
16421668
}
16431669
}
16441670
}

src/librustc_driver/driver.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1182,9 +1182,6 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
11821182
Some(ref n) if *n == "rlib" => {
11831183
Some(config::CrateTypeRlib)
11841184
}
1185-
Some(ref n) if *n == "metadata" => {
1186-
Some(config::CrateTypeMetadata)
1187-
}
11881185
Some(ref n) if *n == "dylib" => {
11891186
Some(config::CrateTypeDylib)
11901187
}

src/librustc_driver/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
493493
control.after_hir_lowering.stop = Compilation::Stop;
494494
}
495495

496-
if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe) {
496+
if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe ||
497+
i == OutputType::Metadata) {
497498
control.after_llvm.stop = Compilation::Stop;
498499
}
499500

src/librustc_metadata/creader.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -799,8 +799,7 @@ impl<'a> CrateLoader<'a> {
799799
config::CrateTypeProcMacro |
800800
config::CrateTypeCdylib |
801801
config::CrateTypeStaticlib => need_lib_alloc = true,
802-
config::CrateTypeRlib |
803-
config::CrateTypeMetadata => {}
802+
config::CrateTypeRlib => {}
804803
}
805804
}
806805
if !need_lib_alloc && !need_exe_alloc { return }

src/librustc_trans/back/link.rs

+71-39
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ pub fn link_binary(sess: &Session,
191191
let mut out_filenames = Vec::new();
192192
for &crate_type in sess.crate_types.borrow().iter() {
193193
// Ignore executable crates if we have -Z no-trans, as they will error.
194-
if sess.opts.debugging_opts.no_trans &&
194+
if (sess.opts.debugging_opts.no_trans ||
195+
!sess.opts.output_types.should_trans()) &&
195196
crate_type == config::CrateTypeExecutable {
196197
continue;
197198
}
@@ -200,15 +201,16 @@ pub fn link_binary(sess: &Session,
200201
bug!("invalid output type `{:?}` for target os `{}`",
201202
crate_type, sess.opts.target_triple);
202203
}
203-
let out_file = link_binary_output(sess, trans, crate_type, outputs,
204-
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-
for obj in object_filenames(trans, outputs) {
211-
remove(sess, &obj);
210+
if sess.opts.output_types.should_trans() {
211+
for obj in object_filenames(trans, outputs) {
212+
remove(sess, &obj);
213+
}
212214
}
213215
remove(sess, &outputs.with_extension("metadata.o"));
214216
}
@@ -254,18 +256,25 @@ fn is_writeable(p: &Path) -> bool {
254256
}
255257
}
256258

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+
257268
pub fn filename_for_input(sess: &Session,
258269
crate_type: config::CrateType,
259270
crate_name: &str,
260271
outputs: &OutputFilenames) -> PathBuf {
261272
let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename);
273+
262274
match crate_type {
263275
config::CrateTypeRlib => {
264276
outputs.out_directory.join(&format!("lib{}.rlib", libname))
265277
}
266-
config::CrateTypeMetadata => {
267-
outputs.out_directory.join(&format!("lib{}.rmeta", libname))
268-
}
269278
config::CrateTypeCdylib |
270279
config::CrateTypeProcMacro |
271280
config::CrateTypeDylib => {
@@ -323,52 +332,75 @@ pub fn each_linked_rlib(sess: &Session,
323332
}
324333
}
325334

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+
326361
fn link_binary_output(sess: &Session,
327362
trans: &CrateTranslation,
328363
crate_type: config::CrateType,
329364
outputs: &OutputFilenames,
330-
crate_name: &str) -> PathBuf {
365+
crate_name: &str) -> Vec<PathBuf> {
331366
let objects = object_filenames(trans, outputs);
332-
let default_filename = filename_for_input(sess, crate_type, crate_name,
333-
outputs);
334-
let out_filename = outputs.outputs.get(&OutputType::Exe)
335-
.and_then(|s| s.to_owned())
336-
.or_else(|| outputs.single_output_file.clone())
337-
.unwrap_or(default_filename);
338367

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

349372
let tmpdir = match TempDir::new("rustc") {
350373
Ok(tmpdir) => tmpdir,
351374
Err(err) => sess.fatal(&format!("couldn't create a temp dir: {}", err)),
352375
};
353376

354-
match crate_type {
355-
config::CrateTypeRlib => {
356-
link_rlib(sess, Some(trans), &objects, &out_filename,
357-
tmpdir.path()).build();
358-
}
359-
config::CrateTypeStaticlib => {
360-
link_staticlib(sess, &objects, &out_filename, tmpdir.path());
361-
}
362-
config::CrateTypeMetadata => {
363-
emit_metadata(sess, trans, &out_filename);
364-
}
365-
_ => {
366-
link_natively(sess, crate_type, &objects, &out_filename, trans,
367-
outputs, tmpdir.path());
377+
let mut out_filenames = vec![];
378+
379+
if outputs.outputs.contains_key(&OutputType::Metadata) {
380+
let out_filename = filename_for_metadata(sess, crate_name, outputs);
381+
emit_metadata(sess, trans, &out_filename);
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);
387+
match crate_type {
388+
config::CrateTypeRlib => {
389+
link_rlib(sess, Some(trans), &objects, &out_filename,
390+
tmpdir.path()).build();
391+
}
392+
config::CrateTypeStaticlib => {
393+
link_staticlib(sess, &objects, &out_filename, tmpdir.path());
394+
}
395+
_ => {
396+
link_natively(sess, crate_type, &objects, &out_filename, trans,
397+
outputs, tmpdir.path());
398+
}
368399
}
400+
out_filenames.push(out_filename);
369401
}
370402

371-
out_filename
403+
out_filenames
372404
}
373405

374406
fn object_filenames(trans: &CrateTranslation,

src/librustc_trans/back/lto.rs

-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
3434

3535
config::CrateTypeDylib |
3636
config::CrateTypeRlib |
37-
config::CrateTypeMetadata |
3837
config::CrateTypeProcMacro => false,
3938
}
4039
}

0 commit comments

Comments
 (0)