提交 edd82ee9 编写于 作者: B bors

Auto merge of #42932 - bjorn3:no_llvm_try2, r=eddyb

Support compiling rustc without LLVM (try 2)

Now doesn't change rustc_driver.

Supersedes #42752
......@@ -65,6 +65,11 @@ name = "ansi_term"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ar"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arena"
version = "0.0.0"
......@@ -1333,10 +1338,12 @@ dependencies = [
name = "rustc_driver"
version = "0.0.0"
dependencies = [
"ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"arena 0.0.0",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"graphviz 0.0.0",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_allocator 0.0.0",
"rustc_back 0.0.0",
......@@ -1354,6 +1361,7 @@ dependencies = [
"rustc_resolve 0.0.0",
"rustc_save_analysis 0.0.0",
"rustc_trans 0.0.0",
"rustc_trans_utils 0.0.0",
"rustc_typeck 0.0.0",
"serialize 0.0.0",
"syntax 0.0.0",
......@@ -1545,11 +1553,21 @@ dependencies = [
"rustc_incremental 0.0.0",
"rustc_llvm 0.0.0",
"rustc_platform_intrinsics 0.0.0",
"rustc_trans_utils 0.0.0",
"serialize 0.0.0",
"syntax 0.0.0",
"syntax_pos 0.0.0",
]
[[package]]
name = "rustc_trans_utils"
version = "0.0.0"
dependencies = [
"rustc 0.0.0",
"syntax 0.0.0",
"syntax_pos 0.0.0",
]
[[package]]
name = "rustc_tsan"
version = "0.0.0"
......@@ -2141,6 +2159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum ar 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b24e4eef8e3fa7e2ca75b157e6039cdf8d9d3a68213ddc19d0fd9d576b9717c9"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
"checksum backtrace-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "afccc5772ba333abccdf60d55200fa3406f8c59dcf54d5f7998c9107d3799c7c"
......
......@@ -53,6 +53,7 @@ pub struct Config {
pub profiler: bool,
// llvm codegen options
pub llvm_enabled: bool,
pub llvm_assertions: bool,
pub llvm_optimize: bool,
pub llvm_release_debuginfo: bool,
......@@ -192,6 +193,7 @@ struct Install {
#[derive(Deserialize, Default)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct Llvm {
enabled: Option<bool>,
ccache: Option<StringOrBool>,
ninja: Option<bool>,
assertions: Option<bool>,
......@@ -265,6 +267,7 @@ struct TomlTarget {
impl Config {
pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
let mut config = Config::default();
config.llvm_enabled = true;
config.llvm_optimize = true;
config.use_jemalloc = true;
config.backtrace = true;
......@@ -345,6 +348,7 @@ pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
Some(StringOrBool::Bool(false)) | None => {}
}
set(&mut config.ninja, llvm.ninja);
set(&mut config.llvm_enabled, llvm.enabled);
set(&mut config.llvm_assertions, llvm.assertions);
set(&mut config.llvm_optimize, llvm.optimize);
set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo);
......
......@@ -14,6 +14,10 @@
# =============================================================================
[llvm]
# Indicates whether rustc will support compilation with LLVM
# note: rustc does not compile without LLVM at the moment
#enabled = true
# Indicates whether the LLVM build is a Release or Debug build
#optimize = true
......
......@@ -429,6 +429,9 @@ fn rustc_features(&self) -> String {
if self.config.use_jemalloc {
features.push_str(" jemalloc");
}
if self.config.llvm_enabled {
features.push_str(" llvm");
}
features
}
......
......@@ -56,6 +56,12 @@ fn make_run(run: RunConfig) {
fn run(self, builder: &Builder) {
let build = builder.build;
let target = self.target;
// If we're not compiling for LLVM bail out here.
if !build.config.llvm_enabled {
return;
}
// If we're using a custom LLVM bail out here, but we can only use a
// custom LLVM for the build triple.
if let Some(config) = build.config.target_config.get(&target) {
......
......@@ -12,6 +12,7 @@ crate-type = ["dylib"]
arena = { path = "../libarena" }
graphviz = { path = "../libgraphviz" }
log = { version = "0.3", features = ["release_max_level_info"] }
owning_ref = "0.3.3"
env_logger = { version = "0.4", default-features = false }
rustc = { path = "../librustc" }
rustc_allocator = { path = "../librustc_allocator" }
......@@ -29,9 +30,15 @@ rustc_plugin = { path = "../librustc_plugin" }
rustc_privacy = { path = "../librustc_privacy" }
rustc_resolve = { path = "../librustc_resolve" }
rustc_save_analysis = { path = "../librustc_save_analysis" }
rustc_trans = { path = "../librustc_trans" }
rustc_trans = { path = "../librustc_trans", optional = true }
rustc_trans_utils = { path = "../librustc_trans_utils" }
rustc_typeck = { path = "../librustc_typeck" }
serialize = { path = "../libserialize" }
syntax = { path = "../libsyntax" }
syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" }
ar = "0.3.0"
[features]
llvm = ["rustc_trans"]
......@@ -18,7 +18,9 @@
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
use rustc::session::search_paths::PathKind;
use rustc::lint;
use rustc::middle::{self, dependency_format, stability, reachable};
use rustc::middle::{self, stability, reachable};
#[cfg(feature="llvm")]
use rustc::middle::dependency_format;
use rustc::middle::privacy::AccessLevels;
use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED, Passes};
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
......@@ -31,7 +33,9 @@
use rustc_resolve::{MakeGlobMap, Resolver};
use rustc_metadata::creader::CrateLoader;
use rustc_metadata::cstore::{self, CStore};
#[cfg(feature="llvm")]
use rustc_trans::back::{link, write};
#[cfg(feature="llvm")]
use rustc_trans as trans;
use rustc_typeck as typeck;
use rustc_privacy;
......@@ -69,6 +73,11 @@ pub fn compile_input(sess: &Session,
output: &Option<PathBuf>,
addl_plugins: Option<Vec<String>>,
control: &CompileController) -> CompileResult {
#[cfg(feature="llvm")]
use rustc_trans::back::write::OngoingCrateTranslation;
#[cfg(not(feature="llvm"))]
type OngoingCrateTranslation = ();
macro_rules! controller_entry_point {
($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{
let state = &mut $make_state;
......@@ -88,7 +97,7 @@ pub fn compile_input(sess: &Session,
// We need nested scopes here, because the intermediate results can keep
// large chunks of memory alive and we want to free them as soon as
// possible to keep the peak memory usage low
let (outputs, trans) = {
let (outputs, trans): (OutputFilenames, OngoingCrateTranslation) = {
let krate = match phase_1_parse_input(control, sess, input) {
Ok(krate) => krate,
Err(mut parse_error) => {
......@@ -113,7 +122,8 @@ pub fn compile_input(sess: &Session,
};
let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess);
let crate_name = link::find_crate_name(Some(sess), &krate.attrs, input);
let crate_name =
::rustc_trans_utils::link::find_crate_name(Some(sess), &krate.attrs, input);
let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
phase_2_configure_and_expand(
sess, &cstore, krate, registry, &crate_name, addl_plugins, control.make_glob_map,
......@@ -206,6 +216,8 @@ pub fn compile_input(sess: &Session,
println!("Pre-trans");
tcx.print_debug_stats();
}
#[cfg(feature="llvm")]
let trans = phase_4_translate_to_llvm(tcx, analysis, incremental_hashes_map,
&outputs);
......@@ -221,38 +233,59 @@ pub fn compile_input(sess: &Session,
}
}
#[cfg(not(feature="llvm"))]
{
let _ = incremental_hashes_map;
sess.err(&format!("LLVM is not supported by this rustc"));
sess.abort_if_errors();
unreachable!();
}
#[cfg(feature="llvm")]
Ok((outputs, trans))
})??
};
if sess.opts.debugging_opts.print_type_sizes {
sess.code_stats.borrow().print_type_sizes();
#[cfg(not(feature="llvm"))]
{
let _ = outputs;
let _ = trans;
unreachable!();
}
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans);
#[cfg(feature="llvm")]
{
if sess.opts.debugging_opts.print_type_sizes {
sess.code_stats.borrow().print_type_sizes();
}
controller_entry_point!(after_llvm,
sess,
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
phase5_result);
phase5_result?;
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans);
phase_6_link_output(sess, &trans, &outputs);
controller_entry_point!(after_llvm,
sess,
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
phase5_result);
phase5_result?;
// Now that we won't touch anything in the incremental compilation directory
// any more, we can finalize it (which involves renaming it)
rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash);
phase_6_link_output(sess, &trans, &outputs);
if sess.opts.debugging_opts.perf_stats {
sess.print_perf_stats();
}
// Now that we won't touch anything in the incremental compilation directory
// any more, we can finalize it (which involves renaming it)
rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash);
controller_entry_point!(compilation_done,
sess,
CompileState::state_when_compilation_done(input, sess, outdir, output),
Ok(()));
if sess.opts.debugging_opts.perf_stats {
sess.print_perf_stats();
}
controller_entry_point!(
compilation_done,
sess,
CompileState::state_when_compilation_done(input, sess, outdir, output),
Ok(())
);
Ok(())
Ok(())
}
}
fn keep_hygiene_data(sess: &Session) -> bool {
......@@ -360,6 +393,7 @@ pub struct CompileState<'a, 'tcx: 'a> {
pub resolutions: Option<&'a Resolutions>,
pub analysis: Option<&'a ty::CrateAnalysis>,
pub tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
#[cfg(feature="llvm")]
pub trans: Option<&'a trans::CrateTranslation>,
}
......@@ -386,6 +420,7 @@ fn empty(input: &'a Input,
resolutions: None,
analysis: None,
tcx: None,
#[cfg(feature="llvm")]
trans: None,
}
}
......@@ -474,7 +509,7 @@ fn state_after_analysis(input: &'a Input,
}
}
#[cfg(feature="llvm")]
fn state_after_llvm(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
......@@ -488,6 +523,7 @@ fn state_after_llvm(input: &'a Input,
}
}
#[cfg(feature="llvm")]
fn state_when_compilation_done(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
......@@ -906,6 +942,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
mir::provide(&mut local_providers);
reachable::provide(&mut local_providers);
rustc_privacy::provide(&mut local_providers);
#[cfg(feature="llvm")]
trans::provide(&mut local_providers);
typeck::provide(&mut local_providers);
ty::provide(&mut local_providers);
......@@ -918,6 +955,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
let mut extern_providers = ty::maps::Providers::default();
cstore::provide(&mut extern_providers);
#[cfg(feature="llvm")]
trans::provide(&mut extern_providers);
ty::provide_extern(&mut extern_providers);
traits::provide_extern(&mut extern_providers);
......@@ -1064,6 +1102,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
/// Run the translation phase to LLVM, after which the AST and analysis can
/// be discarded.
#[cfg(feature="llvm")]
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
analysis: ty::CrateAnalysis,
incremental_hashes_map: IncrementalHashesMap,
......@@ -1085,6 +1124,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
/// Run LLVM itself, producing a bitcode file, assembly file or object file
/// as a side effect.
#[cfg(feature="llvm")]
pub fn phase_5_run_llvm_passes(sess: &Session,
trans: write::OngoingCrateTranslation)
-> (CompileResult, trans::CrateTranslation) {
......@@ -1103,6 +1143,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
/// Run the linker on any artifacts that resulted from the LLVM run.
/// This should produce either a finished executable or library.
#[cfg(feature="llvm")]
pub fn phase_6_link_output(sess: &Session,
trans: &trans::CrateTranslation,
outputs: &OutputFilenames) {
......@@ -1124,7 +1165,12 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) {
match *output_type {
OutputType::Exe => {
for output in sess.crate_types.borrow().iter() {
let p = link::filename_for_input(sess, *output, crate_name, outputs);
let p = ::rustc_trans_utils::link::filename_for_input(
sess,
*output,
crate_name,
outputs
);
out_filenames.push(p);
}
}
......@@ -1234,7 +1280,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
if base.is_empty() {
base.extend(attr_types);
if base.is_empty() {
base.push(link::default_output_for_target(session));
base.push(::rustc_trans_utils::link::default_output_for_target(session));
}
base.sort();
base.dedup();
......@@ -1242,7 +1288,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
base.into_iter()
.filter(|crate_type| {
let res = !link::invalid_output_for_target(session, *crate_type);
let res = !::rustc_trans_utils::link::invalid_output_for_target(session, *crate_type);
if !res {
session.warn(&format!("dropping unsupported crate type `{}` for target `{}`",
......
......@@ -28,10 +28,15 @@
#![feature(rustc_diagnostic_macros)]
#![feature(set_stdio)]
#[cfg(not(feature="llvm"))]
extern crate ar;
extern crate arena;
extern crate getopts;
extern crate graphviz;
extern crate env_logger;
#[cfg(not(feature="llvm"))]
extern crate owning_ref;
extern crate libc;
extern crate rustc;
extern crate rustc_allocator;
......@@ -49,7 +54,9 @@
extern crate rustc_mir;
extern crate rustc_resolve;
extern crate rustc_save_analysis;
#[cfg(feature="llvm")]
extern crate rustc_trans;
extern crate rustc_trans_utils;
extern crate rustc_typeck;
extern crate serialize;
#[macro_use]
......@@ -64,7 +71,7 @@
use rustc_resolve as resolve;
use rustc_save_analysis as save;
use rustc_save_analysis::DumpHandler;
use rustc_trans::back::link;
#[cfg(feature="llvm")]
use rustc_trans::back::write::{RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config, Session, build_session, CompileResult};
......@@ -74,9 +81,13 @@
use rustc::session::{early_error, early_warn};
use rustc::lint::Lint;
use rustc::lint;
#[cfg(not(feature="llvm"))]
use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait;
use rustc_metadata::locator;
use rustc_metadata::cstore::CStore;
use rustc::util::common::{time, ErrorReported};
#[cfg(not(feature="llvm"))]
use rustc_back::target::Target;
use serialize::json::ToJson;
......@@ -89,6 +100,8 @@
use std::io::{self, Read, Write};
use std::iter::repeat;
use std::path::PathBuf;
#[cfg(not(feature="llvm"))]
use std::path::Path;
use std::process::{self, Command, Stdio};
use std::rc::Rc;
use std::str;
......@@ -101,11 +114,15 @@
use syntax::parse::{self, PResult};
use syntax_pos::{DUMMY_SP, MultiSpan};
#[cfg(not(feature="llvm"))]
use owning_ref::{OwningRef, ErasedBoxRef};
#[cfg(test)]
pub mod test;
pub mod driver;
pub mod pretty;
#[cfg(feature="llvm")]
pub mod target_features;
mod derive_registrar;
......@@ -151,9 +168,49 @@ pub fn run<F>(run_compiler: F) -> isize
0
}
#[cfg(not(feature="llvm"))]
pub struct NoLLvmMetadataLoader;
#[cfg(not(feature="llvm"))]
pub use NoLLvmMetadataLoader as MetadataLoader;
#[cfg(feature="llvm")]
pub use rustc_trans::LlvmMetadataLoader as MetadataLoader;
#[cfg(not(feature="llvm"))]
impl MetadataLoaderTrait for NoLLvmMetadataLoader {
fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> {
use std::fs::File;
use std::io;
use self::ar::Archive;
let file = File::open(filename).map_err(|e|format!("metadata file open err: {:?}", e))?;
let mut archive = Archive::new(file);
while let Some(entry_result) = archive.next_entry() {
let mut entry = entry_result.map_err(|e|format!("metadata section read err: {:?}", e))?;
if entry.header().identifier() == "rust.metadata.bin" {
let mut buf = Vec::new();
io::copy(&mut entry, &mut buf).unwrap();
let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf).into();
return Ok(buf.map_owner_box().erase_owner());
}
}
Err("Couldnt find metadata section".to_string())
}
fn get_dylib_metadata(&self,
_target: &Target,
_filename: &Path)
-> Result<ErasedBoxRef<[u8]>, String> {
panic!("Dylib metadata loading not supported without LLVM")
}
}
// Parse args and run the compiler. This is the primary entry point for rustc.
// See comments on CompilerCalls below for details about the callbacks argument.
// The FileLoader provides a way to load files from sources other than the file system.
#[cfg_attr(not(feature="llvm"), allow(unused_mut))]
pub fn run_compiler<'a>(args: &[String],
callbacks: &mut CompilerCalls<'a>,
file_loader: Option<Box<FileLoader + 'static>>,
......@@ -175,6 +232,7 @@ pub fn run_compiler<'a>(args: &[String],
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
if sopts.debugging_opts.debug_llvm {
#[cfg(feature="llvm")]
rustc_trans::enable_llvm_debug();
}
......@@ -197,17 +255,19 @@ pub fn run_compiler<'a>(args: &[String],
};
let dep_graph = DepGraph::new(sopts.build_dep_graph());
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader));
let loader = file_loader.unwrap_or(box RealFileLoader);
let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));
let mut sess = session::build_session_with_codemap(
sopts, &dep_graph, input_file_path, descriptions, cstore.clone(), codemap, emitter_dest,
);
#[cfg(feature="llvm")]
rustc_trans::init(&sess);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let mut cfg = config::build_configuration(&sess, cfg);
#[cfg(feature="llvm")]
target_features::add_configuration(&mut cfg, &sess);
sess.parse_sess.config = cfg;
......@@ -460,6 +520,7 @@ fn early_callback(&mut self,
Compilation::Continue
}
#[cfg_attr(not(feature="llvm"), allow(unused_mut))]
fn no_input(&mut self,
matches: &getopts::Matches,
sopts: &config::Options,
......@@ -477,15 +538,17 @@ fn no_input(&mut self,
return None;
}
let dep_graph = DepGraph::new(sopts.build_dep_graph());
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader));
let mut sess = build_session(sopts.clone(),
&dep_graph,
None,
descriptions.clone(),
cstore.clone());
#[cfg(feature="llvm")]
rustc_trans::init(&sess);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let mut cfg = config::build_configuration(&sess, cfg.clone());
#[cfg(feature="llvm")]
target_features::add_configuration(&mut cfg, &sess);
sess.parse_sess.config = cfg;
let should_stop =
......@@ -678,14 +741,19 @@ fn print_crate_info(sess: &Session,
};
let attrs = attrs.as_ref().unwrap();
let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess);
let id = link::find_crate_name(Some(sess), attrs, input);
let id = rustc_trans_utils::link::find_crate_name(Some(sess), attrs, input);
if *req == PrintRequest::CrateName {
println!("{}", id);
continue;
}
let crate_types = driver::collect_crate_types(sess, attrs);
for &style in &crate_types {
let fname = link::filename_for_input(sess, style, &id, &t_outputs);
let fname = rustc_trans_utils::link::filename_for_input(
sess,
style,
&id,
&t_outputs
);
println!("{}",
fname.file_name()
.unwrap()
......@@ -734,6 +802,7 @@ fn print_crate_info(sess: &Session,
}
PrintRequest::RelocationModels => {
println!("Available relocation models:");
#[cfg(feature="llvm")]
for &(name, _) in RELOC_MODEL_ARGS.iter() {
println!(" {}", name);
}
......@@ -741,13 +810,17 @@ fn print_crate_info(sess: &Session,
}
PrintRequest::CodeModels => {
println!("Available code models:");
#[cfg(feature="llvm")]
for &(name, _) in CODE_GEN_MODEL_ARGS.iter(){
println!(" {}", name);
}
println!("");
}
PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => {
#[cfg(feature="llvm")]
rustc_trans::print(*req, sess);
#[cfg(not(feature="llvm"))]
panic!("LLVM not supported by this rustc")
}
}
}
......@@ -786,6 +859,7 @@ fn unw(x: Option<&str>) -> &str {
println!("commit-date: {}", unw(commit_date_str()));
println!("host: {}", config::host_triple());
println!("release: {}", unw(release_str()));
#[cfg(feature="llvm")]
rustc_trans::print_version();
}
}
......@@ -1083,6 +1157,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
}
if cg_flags.contains(&"passes=list".to_string()) {
#[cfg(feature="llvm")]
rustc_trans::print_passes();
return None;
}
......@@ -1210,6 +1285,7 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
all_errors.extend_from_slice(&rustc_borrowck::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_resolve::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS);
#[cfg(feature="llvm")]
all_errors.extend_from_slice(&rustc_trans::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_const_eval::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_metadata::DIAGNOSTICS);
......
......@@ -14,6 +14,7 @@
use rustc::dep_graph::DepGraph;
use rustc_lint;
use rustc_resolve::MakeGlobMap;
#[cfg(feature="llvm")]
use rustc_trans;
use rustc::middle::lang_items;
use rustc::middle::free_region::FreeRegionMap;
......@@ -106,13 +107,14 @@ fn test_env<F>(source_string: &str,
let dep_graph = DepGraph::new(false);
let _ignore = dep_graph.in_ignore();
let cstore = Rc::new(CStore::new(&dep_graph, box rustc_trans::LlvmMetadataLoader));
let cstore = Rc::new(CStore::new(&dep_graph, box ::MetadataLoader));
let sess = session::build_session_(options,
&dep_graph,
None,
diagnostic_handler,
Rc::new(CodeMap::new(FilePathMapping::empty())),
cstore.clone());
#[cfg(feature="llvm")]
rustc_trans::init(&sess);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let input = config::Input::Str {
......
......@@ -26,6 +26,7 @@ rustc_errors = { path = "../librustc_errors" }
rustc_incremental = { path = "../librustc_incremental" }
rustc_llvm = { path = "../librustc_llvm" }
rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
rustc_trans_utils = { path = "../librustc_trans_utils" }
serialize = { path = "../libserialize" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
......
......@@ -8,16 +8,18 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern crate rustc_trans_utils;
use super::archive::{ArchiveBuilder, ArchiveConfig};
use super::linker::Linker;
use super::rpath::RPathConfig;
use super::rpath;
use metadata::METADATA_FILENAME;
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, Input, OutputType};
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType};
use rustc::session::filesearch;
use rustc::session::search_paths::PathKind;
use rustc::session::Session;
use rustc::middle::cstore::{self, LinkMeta, NativeLibrary, LibSource, LinkagePreference,
use rustc::middle::cstore::{LinkMeta, NativeLibrary, LibSource, LinkagePreference,
NativeLibraryKind};
use rustc::middle::dependency_format::Linkage;
use CrateTranslation;
......@@ -44,9 +46,7 @@
use std::str;
use flate2::Compression;
use flate2::write::DeflateEncoder;
use syntax::ast;
use syntax::attr;
use syntax_pos::Span;
/// The LLVM module name containing crate-metadata. This includes a `.` on
/// purpose, so it cannot clash with the name of a user-defined module.
......@@ -88,55 +88,8 @@
pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: usize =
RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET + 8;
pub fn find_crate_name(sess: Option<&Session>,
attrs: &[ast::Attribute],
input: &Input) -> String {
let validate = |s: String, span: Option<Span>| {
cstore::validate_crate_name(sess, &s, span);
s
};
// Look in attributes 100% of the time to make sure the attribute is marked
// as used. After doing this, however, we still prioritize a crate name from
// the command line over one found in the #[crate_name] attribute. If we
// find both we ensure that they're the same later on as well.
let attr_crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
.and_then(|at| at.value_str().map(|s| (at, s)));
if let Some(sess) = sess {
if let Some(ref s) = sess.opts.crate_name {
if let Some((attr, name)) = attr_crate_name {
if name != &**s {
let msg = format!("--crate-name and #[crate_name] are \
required to match, but `{}` != `{}`",
s, name);
sess.span_err(attr.span, &msg);
}
}
return validate(s.clone(), None);
}
}
if let Some((attr, s)) = attr_crate_name {
return validate(s.to_string(), Some(attr.span));
}
if let Input::File(ref path) = *input {
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
if s.starts_with("-") {
let msg = format!("crate names cannot start with a `-`, but \
`{}` has a leading hyphen", s);
if let Some(sess) = sess {
sess.err(&msg);
}
} else {
return validate(s.replace("-", "_"), None);
}
}
}
"rust_out".to_string()
}
pub use self::rustc_trans_utils::link::{find_crate_name, filename_for_input,
default_output_for_target, invalid_output_for_target};
pub fn build_link_meta(incremental_hashes_map: &IncrementalHashesMap) -> LinkMeta {
let krate_dep_node = &DepNode::new_no_params(DepKind::Krate);
......@@ -252,37 +205,6 @@ pub fn link_binary(sess: &Session,
out_filenames
}
/// Returns default crate type for target
///
/// Default crate type is used when crate type isn't provided neither
/// through cmd line arguments nor through crate attributes
///
/// It is CrateTypeExecutable for all platforms but iOS as there is no
/// way to run iOS binaries anyway without jailbreaking and
/// interaction with Rust code through static library is the only
/// option for now
pub fn default_output_for_target(sess: &Session) -> config::CrateType {
if !sess.target.target.options.executables {
config::CrateTypeStaticlib
} else {
config::CrateTypeExecutable
}
}
/// Checks if target supports crate_type as output
pub fn invalid_output_for_target(sess: &Session,
crate_type: config::CrateType) -> bool {
match (sess.target.target.options.dynamic_linking,
sess.target.target.options.executables, crate_type) {
(false, _, config::CrateTypeCdylib) |
(false, _, config::CrateTypeProcMacro) |
(false, _, config::CrateTypeDylib) => true,
(_, false, config::CrateTypeExecutable) => true,
_ => false
}
}
fn is_writeable(p: &Path) -> bool {
match p.metadata() {
Err(..) => true,
......@@ -299,42 +221,6 @@ fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilen
out_filename
}
pub fn filename_for_input(sess: &Session,
crate_type: config::CrateType,
crate_name: &str,
outputs: &OutputFilenames) -> PathBuf {
let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename);
match crate_type {
config::CrateTypeRlib => {
outputs.out_directory.join(&format!("lib{}.rlib", libname))
}
config::CrateTypeCdylib |
config::CrateTypeProcMacro |
config::CrateTypeDylib => {
let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
&sess.target.target.options.dll_suffix);
outputs.out_directory.join(&format!("{}{}{}", prefix, libname,
suffix))
}
config::CrateTypeStaticlib => {
let (prefix, suffix) = (&sess.target.target.options.staticlib_prefix,
&sess.target.target.options.staticlib_suffix);
outputs.out_directory.join(&format!("{}{}{}", prefix, libname,
suffix))
}
config::CrateTypeExecutable => {
let suffix = &sess.target.target.options.exe_suffix;
let out_filename = outputs.path(OutputType::Exe);
if suffix.is_empty() {
out_filename.to_path_buf()
} else {
out_filename.with_extension(&suffix[1..])
}
}
}
}
pub fn each_linked_rlib(sess: &Session,
f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> {
let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic).into_iter();
......
[package]
authors = ["The Rust Project Developers"]
name = "rustc_trans_utils"
version = "0.0.0"
[lib]
name = "rustc_trans_utils"
path = "lib.rs"
crate-type = ["dylib"]
test = false
[dependencies]
rustc = { path = "../librustc" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! # Note
//!
//! This API is completely unstable and subject to change.
#![crate_name = "rustc_trans_utils"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(warnings)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(custom_attribute)]
#![allow(unused_attributes)]
#![feature(i128_type)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)]
#![feature(conservative_impl_trait)]
extern crate rustc;
extern crate syntax;
extern crate syntax_pos;
pub mod link;
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::session::config::{self, /*NoDebugInfo,*/ OutputFilenames, Input, OutputType};
/*use rustc::session::filesearch;
use rustc::session::search_paths::PathKind;
*/use rustc::session::Session;
use rustc::middle::cstore;/*::{self, LinkMeta, NativeLibrary, LibSource, LinkagePreference,
NativeLibraryKind};*/
/*use rustc::middle::dependency_format::Linkage;
use rustc::util::common::time;
use rustc::util::fs::fix_windows_verbatim_for_gcc;
use rustc::dep_graph::{DepKind, DepNode};
use rustc::hir::def_id::CrateNum;
use rustc::hir::svh::Svh;
use rustc_back::tempdir::TempDir;
use rustc_back::{PanicStrategy, RelroLevel};
use rustc_incremental::IncrementalHashesMap;*/
/*use std::ascii;
use std::char;
use std::env;
use std::ffi::OsString;
use std::fs;
use std::io::{self, Read, Write};
use std::mem;
*/use std::path::PathBuf;/*{Path, PathBuf};
use std::process::Command;
use std::str;*/
use syntax::ast;
//use syntax::attr;
use syntax_pos::Span;
pub fn find_crate_name(sess: Option<&Session>,
attrs: &[ast::Attribute],
input: &Input) -> String {
let validate = |s: String, span: Option<Span>| {
cstore::validate_crate_name(sess, &s, span);
s
};
// Look in attributes 100% of the time to make sure the attribute is marked
// as used. After doing this, however, we still prioritize a crate name from
// the command line over one found in the #[crate_name] attribute. If we
// find both we ensure that they're the same later on as well.
let attr_crate_name = attrs.iter().find(|at| at.check_name("crate_name"))
.and_then(|at| at.value_str().map(|s| (at, s)));
if let Some(sess) = sess {
if let Some(ref s) = sess.opts.crate_name {
if let Some((attr, name)) = attr_crate_name {
if name != &**s {
let msg = format!("--crate-name and #[crate_name] are \
required to match, but `{}` != `{}`",
s, name);
sess.span_err(attr.span, &msg);
}
}
return validate(s.clone(), None);
}
}
if let Some((attr, s)) = attr_crate_name {
return validate(s.to_string(), Some(attr.span));
}
if let Input::File(ref path) = *input {
if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
if s.starts_with("-") {
let msg = format!("crate names cannot start with a `-`, but \
`{}` has a leading hyphen", s);
if let Some(sess) = sess {
sess.err(&msg);
}
} else {
return validate(s.replace("-", "_"), None);
}
}
}
"rust_out".to_string()
}
pub fn filename_for_input(sess: &Session,
crate_type: config::CrateType,
crate_name: &str,
outputs: &OutputFilenames) -> PathBuf {
let libname = format!("{}{}", crate_name, sess.opts.cg.extra_filename);
match crate_type {
config::CrateTypeRlib => {
outputs.out_directory.join(&format!("lib{}.rlib", libname))
}
config::CrateTypeCdylib |
config::CrateTypeProcMacro |
config::CrateTypeDylib => {
let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
&sess.target.target.options.dll_suffix);
outputs.out_directory.join(&format!("{}{}{}", prefix, libname,
suffix))
}
config::CrateTypeStaticlib => {
let (prefix, suffix) = (&sess.target.target.options.staticlib_prefix,
&sess.target.target.options.staticlib_suffix);
outputs.out_directory.join(&format!("{}{}{}", prefix, libname,
suffix))
}
config::CrateTypeExecutable => {
let suffix = &sess.target.target.options.exe_suffix;
let out_filename = outputs.path(OutputType::Exe);
if suffix.is_empty() {
out_filename.to_path_buf()
} else {
out_filename.with_extension(&suffix[1..])
}
}
}
}
/// Returns default crate type for target
///
/// Default crate type is used when crate type isn't provided neither
/// through cmd line arguments nor through crate attributes
///
/// It is CrateTypeExecutable for all platforms but iOS as there is no
/// way to run iOS binaries anyway without jailbreaking and
/// interaction with Rust code through static library is the only
/// option for now
pub fn default_output_for_target(sess: &Session) -> config::CrateType {
if !sess.target.target.options.executables {
config::CrateTypeStaticlib
} else {
config::CrateTypeExecutable
}
}
/// Checks if target supports crate_type as output
pub fn invalid_output_for_target(sess: &Session,
crate_type: config::CrateType) -> bool {
match (sess.target.target.options.dynamic_linking,
sess.target.target.options.executables, crate_type) {
(false, _, config::CrateTypeCdylib) |
(false, _, config::CrateTypeProcMacro) |
(false, _, config::CrateTypeDylib) => true,
(_, false, config::CrateTypeExecutable) => true,
_ => false
}
}
......@@ -15,3 +15,4 @@ rustc_driver = { path = "../librustc_driver" }
[features]
jemalloc = ["rustc_back/jemalloc"]
llvm = ["rustc_driver/llvm"]
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册