"rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_allocator 0.0.0",
"rustc_borrowck 0.0.0",
+ "rustc_codegen_ssa 0.0.0",
"rustc_codegen_utils 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"syntax 0.0.0",
"syntax_ext 0.0.0",
"syntax_pos 0.0.0",
+ "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
};
use rustc::session::search_paths::PathKind;
use rustc::middle::dependency_format::Linkage;
-use rustc::middle::cstore::{LibSource, NativeLibrary, NativeLibraryKind};
+use rustc::middle::cstore::{EncodedMetadata, LibSource, NativeLibrary, NativeLibraryKind};
use rustc::util::common::{time, time_ext};
use rustc::hir::def_id::CrateNum;
use rustc_data_structures::fx::FxHashSet;
outputs: &OutputFilenames,
crate_name: &str,
target_cpu: &str) {
+ let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
for &crate_type in sess.crate_types.borrow().iter() {
// Ignore executable crates if we have -Z no-codegen, as they will error.
- let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
if (sess.opts.debugging_opts.no_codegen || !sess.opts.output_types.should_codegen()) &&
!output_metadata &&
crate_type == config::CrateType::Executable {
check_file_is_writeable(obj, sess);
}
- if outputs.outputs.contains_key(&OutputType::Metadata) {
- let out_filename = filename_for_metadata(sess, crate_name, outputs);
- // To avoid races with another rustc process scanning the output directory,
- // we need to write the file somewhere else and atomically move it to its
- // final destination, with a `fs::rename` call. In order for the rename to
- // always succeed, the temporary file needs to be on the same filesystem,
- // which is why we create it inside the output directory specifically.
- let metadata_tmpdir = TempFileBuilder::new()
- .prefix("rmeta")
- .tempdir_in(out_filename.parent().unwrap())
- .unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err)));
- let metadata = emit_metadata(sess, codegen_results, &metadata_tmpdir);
- match fs::rename(&metadata, &out_filename) {
- Ok(_) => {
- if sess.opts.debugging_opts.emit_directives {
- sess.parse_sess.span_diagnostic.maybe_emit_json_directive(
- format!("metadata file written: {}", out_filename.display()));
- }
- }
- Err(e) => sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)),
- }
- }
-
let tmpdir = TempFileBuilder::new().prefix("rustc").tempdir().unwrap_or_else(|err|
sess.fatal(&format!("couldn't create a temp dir: {}", err)));
/// building an `.rlib` (stomping over one another), or writing an `.rmeta` into a
/// directory being searched for `extern crate` (observing an incomplete file).
/// The returned path is the temporary file containing the complete metadata.
-fn emit_metadata<'a>(
+pub fn emit_metadata<'a>(
sess: &'a Session,
- codegen_results: &CodegenResults,
+ metadata: &EncodedMetadata,
tmpdir: &TempDir
) -> PathBuf {
let out_filename = tmpdir.path().join(METADATA_FILENAME);
- let result = fs::write(&out_filename, &codegen_results.metadata.raw_data);
+ let result = fs::write(&out_filename, &metadata.raw_data);
if let Err(e) = result {
sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
RlibFlavor::Normal => {
// Instead of putting the metadata in an object file section, rlibs
// contain the metadata in a separate file.
- ab.add_file(&emit_metadata(sess, codegen_results, tmpdir));
+ ab.add_file(&emit_metadata(sess, &codegen_results.metadata, tmpdir));
// For LTO purposes, the bytecode of this library is also inserted
// into the archive.
rustc_incremental = { path = "../librustc_incremental" }
rustc_traits = { path = "../librustc_traits" }
rustc_data_structures = { path = "../librustc_data_structures" }
+rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
rustc_metadata = { path = "../librustc_metadata" }
rustc_mir = { path = "../librustc_mir" }
rustc_plugin = { path = "../librustc_plugin" }
rustc_privacy = { path = "../librustc_privacy" }
rustc_resolve = { path = "../librustc_resolve" }
+tempfile = "3.0.5"
use rustc::session::search_paths::PathKind;
use rustc_allocator as allocator;
use rustc_borrowck as borrowck;
+use rustc_codegen_ssa::back::link::emit_metadata;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
+use rustc_codegen_utils::link::filename_for_metadata;
use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::StableHasher;
use syntax_ext;
use serialize::json;
+use tempfile::Builder as TempFileBuilder;
use std::any::Any;
use std::env;
Ok(())
}
-fn encode_metadata<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> (middle::cstore::EncodedMetadata, bool) {
+fn encode_and_write_metadata<'tcx>(
+ tcx: TyCtxt<'_, 'tcx, 'tcx>,
+ outputs: &OutputFilenames,
+) -> (middle::cstore::EncodedMetadata, bool) {
#[derive(PartialEq, Eq, PartialOrd, Ord)]
enum MetadataKind {
None,
}
}).max().unwrap_or(MetadataKind::None);
- let need_metadata_module = metadata_kind == MetadataKind::Compressed;
-
let metadata = match metadata_kind {
MetadataKind::None => middle::cstore::EncodedMetadata::new(),
MetadataKind::Uncompressed |
MetadataKind::Compressed => tcx.encode_metadata(),
};
+ let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
+ if need_metadata_file {
+ let crate_name = &tcx.crate_name(LOCAL_CRATE).as_str();
+ let out_filename = filename_for_metadata(tcx.sess, crate_name, outputs);
+ // To avoid races with another rustc process scanning the output directory,
+ // we need to write the file somewhere else and atomically move it to its
+ // final destination, with an `fs::rename` call. In order for the rename to
+ // always succeed, the temporary file needs to be on the same filesystem,
+ // which is why we create it inside the output directory specifically.
+ let metadata_tmpdir = TempFileBuilder::new()
+ .prefix("rmeta")
+ .tempdir_in(out_filename.parent().unwrap())
+ .unwrap_or_else(|err| {
+ tcx.sess.fatal(&format!("couldn't create a temp dir: {}", err))
+ });
+ let metadata_filename = emit_metadata(tcx.sess, &metadata, &metadata_tmpdir);
+ match std::fs::rename(&metadata_filename, &out_filename) {
+ Ok(_) => {
+ if tcx.sess.opts.debugging_opts.emit_directives {
+ tcx.sess.parse_sess.span_diagnostic.maybe_emit_json_directive(
+ format!("metadata file written: {}", out_filename.display()));
+ }
+ }
+ Err(e) => tcx.sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e)),
+ }
+ }
+
+ let need_metadata_module = metadata_kind == MetadataKind::Compressed;
+
(metadata, need_metadata_module)
}
middle::dependency_format::calculate(tcx)
});
- let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding", || {
- encode_metadata(tcx)
+ let (metadata, need_metadata_module) = time(tcx.sess, "metadata encoding and writing", || {
+ encode_and_write_metadata(tcx, outputs)
});
tcx.sess.profiler(|p| p.start_activity("codegen crate"));