StableHashingContextProvider};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use session::config::OutputType;
use std::cell::{Ref, RefCell};
use std::env;
use std::hash::Hash;
pub struct WorkProduct {
pub cgu_name: String,
/// Saved files associated with this CGU
- pub saved_files: Vec<(OutputType, String)>,
+ pub saved_files: Vec<(WorkProductFileKind, String)>,
+}
+
+#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable)]
+pub enum WorkProductFileKind {
+ Object,
+ Bytecode,
+ BytecodeCompressed,
}
pub(super) struct CurrentDepGraph {
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, label_strs};
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor};
+pub use self::graph::WorkProductFileKind;
pub use self::prev::PreviousDepGraph;
pub use self::query::DepGraphQuery;
pub use self::safe::AssertDepGraphSafe;
//! This module contains files for saving intermediate work-products.
use persist::fs::*;
-use rustc::dep_graph::{WorkProduct, WorkProductId, DepGraph};
+use rustc::dep_graph::{WorkProduct, WorkProductId, DepGraph, WorkProductFileKind};
use rustc::session::Session;
-use rustc::session::config::OutputType;
use rustc::util::fs::link_or_copy;
use std::path::PathBuf;
use std::fs as std_fs;
pub fn save_trans_partition(sess: &Session,
dep_graph: &DepGraph,
cgu_name: &str,
- files: &[(OutputType, PathBuf)]) {
+ files: &[(WorkProductFileKind, PathBuf)]) {
debug!("save_trans_partition({:?},{:?})",
cgu_name,
files);
if sess.opts.incremental.is_none() {
- return;
+ return
}
let work_product_id = WorkProductId::from_cgu_name(cgu_name);
let saved_files: Option<Vec<_>> =
files.iter()
.map(|&(kind, ref path)| {
- let file_name = format!("cgu-{}.{}", cgu_name, kind.extension());
+ let extension = match kind {
+ WorkProductFileKind::Object => "o",
+ WorkProductFileKind::Bytecode => "bc",
+ WorkProductFileKind::BytecodeCompressed => "bc-compressed",
+ };
+ let file_name = format!("cgu-{}.{}", cgu_name, extension);
let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name);
match link_or_copy(path, &path_in_incr_dir) {
Ok(_) => Some((kind, file_name)),
// except according to those terms.
use super::archive::{ArchiveBuilder, ArchiveConfig};
-use super::bytecode::{self, RLIB_BYTECODE_EXTENSION};
+use super::bytecode::RLIB_BYTECODE_EXTENSION;
use super::linker::Linker;
use super::command::Command;
use super::rpath::RPathConfig;
use std::ffi::OsString;
use std::fmt;
use std::fs::{self, File};
-use std::io::{self, Read, Write, BufWriter};
+use std::io::{self, Write, BufWriter};
use std::path::{Path, PathBuf};
use std::process::{Output, Stdio};
use std::str;
env::join_paths(new_path).unwrap()
}
-fn metadata_obj(outputs: &OutputFilenames) -> PathBuf {
- outputs.temp_path(OutputType::Object, Some(METADATA_MODULE_NAME))
-}
-
-fn allocator_obj(outputs: &OutputFilenames) -> PathBuf {
- outputs.temp_path(OutputType::Object, Some(ALLOCATOR_MODULE_NAME))
-}
-
pub fn remove(sess: &Session, path: &Path) {
match fs::remove_file(path) {
Ok(..) => {}
// Remove the temporary object file and metadata if we aren't saving temps
if !sess.opts.cg.save_temps {
if sess.opts.output_types.should_trans() {
- for obj in trans.modules.iter() {
- remove(sess, &obj.object);
+ for obj in trans.modules.iter().filter_map(|m| m.object.as_ref()) {
+ remove(sess, obj);
}
}
- remove(sess, &metadata_obj(outputs));
- if trans.allocator_module.is_some() {
- remove(sess, &allocator_obj(outputs));
+ for obj in trans.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref()) {
+ remove(sess, obj);
+ }
+ if let Some(ref obj) = trans.metadata_module.object {
+ remove(sess, obj);
+ }
+ if let Some(ref allocator) = trans.allocator_module {
+ if let Some(ref obj) = allocator.object {
+ remove(sess, obj);
+ }
+ if let Some(ref bc) = allocator.bytecode_compressed {
+ remove(sess, bc);
+ }
}
}
crate_type: config::CrateType,
outputs: &OutputFilenames,
crate_name: &str) -> Vec<PathBuf> {
- for module in trans.modules.iter() {
- check_file_is_writeable(&module.object, sess);
+ for obj in trans.modules.iter().filter_map(|m| m.object.as_ref()) {
+ check_file_is_writeable(obj, sess);
}
let tmpdir = match TempDir::new("rustc") {
link_rlib(sess,
trans,
RlibFlavor::Normal,
- outputs,
&out_filename,
tmpdir.path()).build();
}
config::CrateTypeStaticlib => {
- link_staticlib(sess,
- trans,
- outputs,
- &out_filename,
- tmpdir.path());
+ link_staticlib(sess, trans, &out_filename, tmpdir.path());
}
_ => {
- link_natively(sess, crate_type, &out_filename,
- trans, outputs, tmpdir.path());
+ link_natively(sess, crate_type, &out_filename, trans, tmpdir.path());
}
}
out_filenames.push(out_filename);
fn link_rlib<'a>(sess: &'a Session,
trans: &CrateTranslation,
flavor: RlibFlavor,
- outputs: &OutputFilenames,
out_filename: &Path,
tmpdir: &Path) -> ArchiveBuilder<'a> {
info!("preparing rlib to {:?}", out_filename);
let mut ab = ArchiveBuilder::new(archive_config(sess, out_filename, None));
- for module in trans.modules.iter() {
- ab.add_file(&module.object);
+ for obj in trans.modules.iter().filter_map(|m| m.object.as_ref()) {
+ ab.add_file(obj);
}
// Note that in this loop we are ignoring the value of `lib.cfg`. That is,
ab.add_file(&metadata);
// 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.
- for module in trans.modules.iter() {
- // Note that we make sure that the bytecode filename in the
- // archive is never exactly 16 bytes long by adding a 16 byte
- // extension to it. This is to work around a bug in LLDB that
- // would cause it to crash if the name of a file in an archive
- // was exactly 16 bytes.
- let bc_filename = module.object.with_extension("bc");
- let bc_encoded_filename = tmpdir.join({
- module.object.with_extension(RLIB_BYTECODE_EXTENSION).file_name().unwrap()
- });
-
- let mut bc_data = Vec::new();
- match fs::File::open(&bc_filename).and_then(|mut f| {
- f.read_to_end(&mut bc_data)
- }) {
- Ok(..) => {}
- Err(e) => sess.fatal(&format!("failed to read bytecode: {}",
- e))
- }
-
- let encoded = bytecode::encode(&module.llmod_id, &bc_data);
-
- let mut bc_file_deflated = match fs::File::create(&bc_encoded_filename) {
- Ok(file) => file,
- Err(e) => {
- sess.fatal(&format!("failed to create compressed \
- bytecode file: {}", e))
- }
- };
-
- match bc_file_deflated.write_all(&encoded) {
- Ok(()) => {}
- Err(e) => {
- sess.fatal(&format!("failed to write compressed \
- bytecode: {}", e));
- }
- };
-
- ab.add_file(&bc_encoded_filename);
-
- // See the bottom of back::write::run_passes for an explanation
- // of when we do and don't keep .#module-name#.bc files around.
- let user_wants_numbered_bitcode =
- sess.opts.output_types.contains_key(&OutputType::Bitcode) &&
- sess.codegen_units() > 1;
- if !sess.opts.cg.save_temps && !user_wants_numbered_bitcode {
- remove(sess, &bc_filename);
- }
+ // into the archive.
+ for bytecode in trans.modules.iter().filter_map(|m| m.bytecode_compressed.as_ref()) {
+ ab.add_file(bytecode);
}
// After adding all files to the archive, we need to update the
}
RlibFlavor::StaticlibBase => {
- if trans.allocator_module.is_some() {
- ab.add_file(&allocator_obj(outputs));
+ let obj = trans.allocator_module
+ .as_ref()
+ .and_then(|m| m.object.as_ref());
+ if let Some(obj) = obj {
+ ab.add_file(obj);
}
}
}
// metadata file).
fn link_staticlib(sess: &Session,
trans: &CrateTranslation,
- outputs: &OutputFilenames,
out_filename: &Path,
tempdir: &Path) {
let mut ab = link_rlib(sess,
trans,
RlibFlavor::StaticlibBase,
- outputs,
out_filename,
tempdir);
let mut all_native_libs = vec![];
crate_type: config::CrateType,
out_filename: &Path,
trans: &CrateTranslation,
- outputs: &OutputFilenames,
tmpdir: &Path) {
info!("preparing {:?} to {:?}", crate_type, out_filename);
let flavor = sess.linker_flavor();
{
let mut linker = trans.linker_info.to_linker(cmd, &sess);
link_args(&mut *linker, sess, crate_type, tmpdir,
- out_filename, outputs, trans);
+ out_filename, trans);
cmd = linker.finalize();
}
if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) {
crate_type: config::CrateType,
tmpdir: &Path,
out_filename: &Path,
- outputs: &OutputFilenames,
trans: &CrateTranslation) {
// The default library location, we need this to find the runtime.
let t = &sess.target.target;
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
- for module in trans.modules.iter() {
- cmd.add_object(&module.object);
+ for obj in trans.modules.iter().filter_map(|m| m.object.as_ref()) {
+ cmd.add_object(obj);
}
cmd.output_filename(out_filename);
// object file, so we link that in here.
if crate_type == config::CrateTypeDylib ||
crate_type == config::CrateTypeProcMacro {
- cmd.add_object(&metadata_obj(outputs));
+ if let Some(obj) = trans.metadata_module.object.as_ref() {
+ cmd.add_object(obj);
+ }
}
- if trans.allocator_module.is_some() {
- cmd.add_object(&allocator_obj(outputs));
+ let obj = trans.allocator_module
+ .as_ref()
+ .and_then(|m| m.object.as_ref());
+ if let Some(obj) = obj {
+ cmd.add_object(obj);
}
// Try to strip as much out of the generated object by removing unused
for f in archive.src_files() {
if f.ends_with(RLIB_BYTECODE_EXTENSION) || f == METADATA_FILENAME {
- archive.remove_file(&f);
- continue
- }
+ archive.remove_file(&f);
+ continue
+ }
}
archive.build();
info!("local module: {} - {}", i, module.llmod_id);
let llvm = module.llvm().expect("can't lto pretranslated module");
let name = CString::new(module.llmod_id.clone()).unwrap();
- let buffer = llvm::LLVMRustThinLTOBufferCreate(llvm.llmod);
- let buffer = ThinBuffer(buffer);
+ let buffer = ThinBuffer::new(llvm.llmod);
thin_modules.push(llvm::ThinLTOModule {
identifier: name.as_ptr(),
data: buffer.data().as_ptr(),
unsafe impl Sync for ModuleBuffer {}
impl ModuleBuffer {
- fn new(m: ModuleRef) -> ModuleBuffer {
+ pub fn new(m: ModuleRef) -> ModuleBuffer {
ModuleBuffer(unsafe {
llvm::LLVMRustModuleBufferCreate(m)
})
}
- fn data(&self) -> &[u8] {
+ pub fn data(&self) -> &[u8] {
unsafe {
let ptr = llvm::LLVMRustModuleBufferPtr(self.0);
let len = llvm::LLVMRustModuleBufferLen(self.0);
}
}
-struct ThinBuffer(*mut llvm::ThinLTOBuffer);
+pub struct ThinBuffer(*mut llvm::ThinLTOBuffer);
unsafe impl Send for ThinBuffer {}
unsafe impl Sync for ThinBuffer {}
impl ThinBuffer {
- fn data(&self) -> &[u8] {
+ pub fn new(m: ModuleRef) -> ThinBuffer {
+ unsafe {
+ let buffer = llvm::LLVMRustThinLTOBufferCreate(m);
+ ThinBuffer(buffer)
+ }
+ }
+
+ pub fn data(&self) -> &[u8] {
unsafe {
let ptr = llvm::LLVMRustThinLTOBufferPtr(self.0) as *const _;
let len = llvm::LLVMRustThinLTOBufferLen(self.0);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use back::lto;
+use back::bytecode::{self, RLIB_BYTECODE_EXTENSION};
+use back::lto::{self, ModuleBuffer, ThinBuffer};
use back::link::{self, get_linker, remove};
use back::linker::LinkerInfo;
use back::symbol_export::ExportedSymbols;
use base;
use consts;
use rustc_incremental::{save_trans_partition, in_incr_comp_dir};
-use rustc::dep_graph::DepGraph;
+use rustc::dep_graph::{DepGraph, WorkProductFileKind};
use rustc::middle::cstore::{LinkMeta, EncodedMetadata};
use rustc::session::config::{self, OutputFilenames, OutputType, OutputTypes, Passes, SomePasses,
AllPasses, Sanitizer};
use std::any::Any;
use std::ffi::{CString, CStr};
-use std::fs;
+use std::fs::{self, File};
use std::io;
use std::io::Write;
use std::mem;
// Flags indicating which outputs to produce.
emit_no_opt_bc: bool,
emit_bc: bool,
+ emit_bc_compressed: bool,
emit_lto_bc: bool,
emit_ir: bool,
emit_asm: bool,
emit_no_opt_bc: false,
emit_bc: false,
+ emit_bc_compressed: false,
emit_lto_bc: false,
emit_ir: false,
emit_asm: false,
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
- if write_bc {
- let bc_out_c = path2cstr(&bc_out);
- if llvm::LLVMRustThinLTOAvailable() {
- with_codegen(tm, llmod, config.no_builtins, |cpm| {
- llvm::LLVMRustWriteThinBitcodeToFile(
- cpm,
- llmod,
- bc_out_c.as_ptr(),
- )
- });
+
+ if write_bc || config.emit_bc_compressed {
+ let thin;
+ let old;
+ let data = if llvm::LLVMRustThinLTOAvailable() {
+ thin = ThinBuffer::new(llmod);
+ thin.data()
} else {
- llvm::LLVMWriteBitcodeToFile(llmod, bc_out_c.as_ptr());
+ old = ModuleBuffer::new(llmod);
+ old.data()
+ };
+ timeline.record("make-bc");
+
+ if write_bc {
+ if let Err(e) = File::create(&bc_out).and_then(|mut f| f.write_all(data)) {
+ diag_handler.err(&format!("failed to write bytecode: {}", e));
+ }
+ timeline.record("write-bc");
+ }
+
+ if config.emit_bc_compressed {
+ let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
+ let data = bytecode::encode(&mtrans.llmod_id, data);
+ if let Err(e) = File::create(&dst).and_then(|mut f| f.write_all(&data)) {
+ diag_handler.err(&format!("failed to write bytecode: {}", e));
+ }
+ timeline.record("compress-bc");
}
- timeline.record("bc");
}
time(config.time_passes, &format!("codegen passes [{}]", module_name.unwrap()),
drop(handlers);
Ok(mtrans.into_compiled_module(config.emit_obj,
config.emit_bc,
+ config.emit_bc_compressed,
&cgcx.output_filenames))
}
allocator_config.emit_bc = true;
}
- // Emit bitcode files for the crate if we're emitting an rlib.
- // Whenever an rlib is created, the bitcode is inserted into the
- // archive in order to allow LTO against it.
+ // Emit compressed bitcode files for the crate if we're emitting an rlib.
+ // Whenever an rlib is created, the bitcode is inserted into the archive in
+ // order to allow LTO against it.
if need_crate_bitcode_for_rlib(sess) {
- modules_config.emit_bc = true;
+ modules_config.emit_bc_compressed = true;
+ allocator_config.emit_bc_compressed = true;
}
for output_type in output_types_override.keys() {
fn copy_module_artifacts_into_incr_comp_cache(sess: &Session,
dep_graph: &DepGraph,
- compiled_modules: &CompiledModules,
- crate_output: &OutputFilenames) {
+ compiled_modules: &CompiledModules) {
if sess.opts.incremental.is_none() {
return;
}
for module in compiled_modules.modules.iter() {
let mut files = vec![];
- if module.emit_obj {
- let path = crate_output.temp_path(OutputType::Object, Some(&module.name));
- files.push((OutputType::Object, path));
+ if let Some(ref path) = module.object {
+ files.push((WorkProductFileKind::Object, path.clone()));
}
-
- if module.emit_bc {
- let path = crate_output.temp_path(OutputType::Bitcode, Some(&module.name));
- files.push((OutputType::Bitcode, path));
+ if let Some(ref path) = module.bytecode {
+ files.push((WorkProductFileKind::Bytecode, path.clone()));
+ }
+ if let Some(ref path) = module.bytecode_compressed {
+ files.push((WorkProductFileKind::BytecodeCompressed, path.clone()));
}
- save_trans_partition(sess,
- dep_graph,
- &module.name,
- &files);
+ save_trans_partition(sess, dep_graph, &module.name, &files);
}
}
// well.
// Specific rules for keeping .#module-name#.bc:
- // - If we're building an rlib (`needs_crate_bitcode`), then keep
- // it.
// - If the user requested bitcode (`user_wants_bitcode`), and
// codegen_units > 1, then keep it.
// - If the user requested bitcode but codegen_units == 1, then we
// If you change how this works, also update back::link::link_rlib,
// where .#module-name#.bc files are (maybe) deleted after making an
// rlib.
- let needs_crate_bitcode = need_crate_bitcode_for_rlib(sess);
let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe);
- let keep_numbered_bitcode = needs_crate_bitcode ||
- (user_wants_bitcode && sess.codegen_units() > 1);
+ let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units() > 1;
let keep_numbered_objects = needs_crate_object ||
(user_wants_objects && sess.codegen_units() > 1);
for module in compiled_modules.modules.iter() {
- let module_name = Some(&module.name[..]);
-
- if module.emit_obj && !keep_numbered_objects {
- let path = crate_output.temp_path(OutputType::Object, module_name);
- remove(sess, &path);
+ if let Some(ref path) = module.object {
+ if !keep_numbered_objects {
+ remove(sess, path);
+ }
}
- if module.emit_bc && !keep_numbered_bitcode {
- let path = crate_output.temp_path(OutputType::Bitcode, module_name);
- remove(sess, &path);
+ if let Some(ref path) = module.bytecode {
+ if !keep_numbered_bitcode {
+ remove(sess, path);
+ }
}
}
- if compiled_modules.metadata_module.emit_bc && !user_wants_bitcode {
- let path = crate_output.temp_path(OutputType::Bitcode,
- Some(&compiled_modules.metadata_module.name));
- remove(sess, &path);
- }
-
- if let Some(ref allocator_module) = compiled_modules.allocator_module {
- if allocator_module.emit_bc && !user_wants_bitcode {
- let path = crate_output.temp_path(OutputType::Bitcode,
- Some(&allocator_module.name));
+ if !user_wants_bitcode {
+ if let Some(ref path) = compiled_modules.metadata_module.bytecode {
remove(sess, &path);
}
+
+ if let Some(ref allocator_module) = compiled_modules.allocator_module {
+ if let Some(ref path) = allocator_module.bytecode {
+ remove(sess, path);
+ }
+ }
}
}
.as_ref()
.unwrap();
let name = &mtrans.name;
+ let mut object = None;
+ let mut bytecode = None;
+ let mut bytecode_compressed = None;
for (kind, saved_file) in wp.saved_files {
- let obj_out = cgcx.output_filenames.temp_path(kind, Some(name));
+ let obj_out = match kind {
+ WorkProductFileKind::Object => {
+ let path = cgcx.output_filenames.temp_path(OutputType::Object, Some(name));
+ object = Some(path.clone());
+ path
+ }
+ WorkProductFileKind::Bytecode => {
+ let path = cgcx.output_filenames.temp_path(OutputType::Bitcode, Some(name));
+ bytecode = Some(path.clone());
+ path
+ }
+ WorkProductFileKind::BytecodeCompressed => {
+ let path = cgcx.output_filenames.temp_path(OutputType::Bitcode, Some(name))
+ .with_extension(RLIB_BYTECODE_EXTENSION);
+ bytecode_compressed = Some(path.clone());
+ path
+ }
+ };
let source_file = in_incr_comp_dir(&incr_comp_session_dir,
&saved_file);
debug!("copying pre-existing module `{}` from {:?} to {}",
}
}
}
- let object = cgcx.output_filenames.temp_path(OutputType::Object, Some(name));
+ assert_eq!(object.is_some(), config.emit_obj);
+ assert_eq!(bytecode.is_some(), config.emit_bc);
+ assert_eq!(bytecode_compressed.is_some(), config.emit_bc_compressed);
Ok(WorkItemResult::Compiled(CompiledModule {
- object,
llmod_id: mtrans.llmod_id.clone(),
name: module_name,
kind: ModuleKind::Regular,
pre_existing: true,
- emit_bc: config.emit_bc,
- emit_obj: config.emit_obj,
+ object,
+ bytecode,
+ bytecode_compressed,
}))
} else {
debug!("llvm-optimizing {:?}", module_name);
copy_module_artifacts_into_incr_comp_cache(sess,
dep_graph,
- &compiled_modules,
- &self.output_filenames);
+ &compiled_modules);
produce_final_output_artifacts(sess,
&compiled_modules,
&self.output_filenames);
modules: compiled_modules.modules,
allocator_module: compiled_modules.allocator_module,
+ metadata_module: compiled_modules.metadata_module,
};
if self.no_integrated_as {
extern crate cc; // Used to locate MSVC
pub use base::trans_crate;
+use back::bytecode::RLIB_BYTECODE_EXTENSION;
pub use metadata::LlvmMetadataLoader;
pub use llvm_util::{init, target_features, print_version, print_passes, print, enable_llvm_debug};
pub mod back {
mod archive;
- mod bytecode;
+ pub mod bytecode;
mod command;
pub(crate) mod linker;
pub mod link;
pub fn into_compiled_module(self,
emit_obj: bool,
emit_bc: bool,
+ emit_bc_compressed: bool,
outputs: &OutputFilenames) -> CompiledModule {
let pre_existing = match self.source {
ModuleSource::Preexisting(_) => true,
ModuleSource::Translated(_) => false,
};
- let object = outputs.temp_path(OutputType::Object, Some(&self.name));
+ let object = if emit_obj {
+ Some(outputs.temp_path(OutputType::Object, Some(&self.name)))
+ } else {
+ None
+ };
+ let bytecode = if emit_bc {
+ Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name)))
+ } else {
+ None
+ };
+ let bytecode_compressed = if emit_bc_compressed {
+ Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name))
+ .with_extension(RLIB_BYTECODE_EXTENSION))
+ } else {
+ None
+ };
CompiledModule {
llmod_id: self.llmod_id,
name: self.name.clone(),
kind: self.kind,
pre_existing,
- emit_obj,
- emit_bc,
object,
+ bytecode,
+ bytecode_compressed,
}
}
}
pub struct CompiledModule {
pub name: String,
pub llmod_id: String,
- pub object: PathBuf,
pub kind: ModuleKind,
pub pre_existing: bool,
- pub emit_obj: bool,
- pub emit_bc: bool,
+ pub object: Option<PathBuf>,
+ pub bytecode: Option<PathBuf>,
+ pub bytecode_compressed: Option<PathBuf>,
}
pub enum ModuleSource {
pub crate_name: Symbol,
pub modules: Vec<CompiledModule>,
allocator_module: Option<CompiledModule>,
+ metadata_module: CompiledModule,
pub link: rustc::middle::cstore::LinkMeta,
pub metadata: rustc::middle::cstore::EncodedMetadata,
windows_subsystem: Option<String>,