Actually make rustc_driver compile without llvm
This commit is contained in:
parent
b43c02b0aa
commit
b7314c7caf
10 changed files with 324 additions and 154 deletions
21
src/Cargo.lock
generated
21
src/Cargo.lock
generated
|
@ -1360,6 +1360,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",
|
||||
|
@ -1551,6 +1552,26 @@ 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",
|
||||
"rustc_allocator 0.0.0",
|
||||
"rustc_back 0.0.0",
|
||||
"rustc_bitflags 0.0.0",
|
||||
"rustc_const_math 0.0.0",
|
||||
"rustc_data_structures 0.0.0",
|
||||
"rustc_errors 0.0.0",
|
||||
"rustc_incremental 0.0.0",
|
||||
"rustc_llvm 0.0.0",
|
||||
"rustc_platform_intrinsics 0.0.0",
|
||||
"serialize 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
|
|
|
@ -30,6 +30,7 @@ rustc_privacy = { path = "../librustc_privacy" }
|
|||
rustc_resolve = { path = "../librustc_resolve" }
|
||||
rustc_save_analysis = { path = "../librustc_save_analysis" }
|
||||
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" }
|
||||
|
|
|
@ -31,7 +31,9 @@ use rustc_incremental::{self, IncrementalHashesMap};
|
|||
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;
|
||||
|
@ -113,7 +115,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,8 +209,12 @@ 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);
|
||||
#[cfg(not(feature="llvm"))]
|
||||
let trans = { panic!("LLVM not supported by this rustc."); () };
|
||||
|
||||
if log_enabled!(::log::LogLevel::Info) {
|
||||
println!("Post-trans");
|
||||
|
@ -225,34 +232,42 @@ pub fn compile_input(sess: &Session,
|
|||
})??
|
||||
};
|
||||
|
||||
if sess.opts.debugging_opts.print_type_sizes {
|
||||
sess.code_stats.borrow().print_type_sizes();
|
||||
#[cfg(not(feature="llvm"))]
|
||||
unreachable!();
|
||||
|
||||
#[cfg(feature="llvm")]
|
||||
{
|
||||
if sess.opts.debugging_opts.print_type_sizes {
|
||||
sess.code_stats.borrow().print_type_sizes();
|
||||
}
|
||||
|
||||
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans);
|
||||
|
||||
controller_entry_point!(after_llvm,
|
||||
sess,
|
||||
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
|
||||
phase5_result);
|
||||
phase5_result?;
|
||||
|
||||
phase_6_link_output(sess, &trans, &outputs);
|
||||
|
||||
// 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);
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans);
|
||||
|
||||
controller_entry_point!(after_llvm,
|
||||
sess,
|
||||
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
|
||||
phase5_result);
|
||||
phase5_result?;
|
||||
|
||||
phase_6_link_output(sess, &trans, &outputs);
|
||||
|
||||
// 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);
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
fn keep_hygiene_data(sess: &Session) -> bool {
|
||||
|
@ -360,6 +375,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 +402,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
|
|||
resolutions: None,
|
||||
analysis: None,
|
||||
tcx: None,
|
||||
#[cfg(feature="llvm")]
|
||||
trans: None,
|
||||
}
|
||||
}
|
||||
|
@ -474,7 +491,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature="llvm")]
|
||||
fn state_after_llvm(input: &'a Input,
|
||||
session: &'tcx Session,
|
||||
out_dir: &'a Option<PathBuf>,
|
||||
|
@ -906,6 +923,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 +936,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);
|
||||
|
@ -1063,6 +1082,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,
|
||||
|
@ -1084,6 +1104,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) {
|
||||
|
@ -1102,6 +1123,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) {
|
||||
|
@ -1123,7 +1145,7 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -1233,7 +1255,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();
|
||||
|
@ -1241,7 +1263,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 `{}`",
|
||||
|
|
|
@ -54,6 +54,7 @@ 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]
|
||||
|
@ -68,7 +69,9 @@ use pretty::{PpMode, UserIdentifiedItem};
|
|||
use rustc_resolve as resolve;
|
||||
use rustc_save_analysis as save;
|
||||
use rustc_save_analysis::DumpHandler;
|
||||
#[cfg(feature="llvm")]
|
||||
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};
|
||||
|
@ -83,6 +86,8 @@ use rustc::middle::cstore::MetadataLoader;
|
|||
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;
|
||||
|
||||
|
@ -95,6 +100,8 @@ use std::ffi::OsString;
|
|||
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;
|
||||
|
@ -112,6 +119,7 @@ pub mod test;
|
|||
|
||||
pub mod driver;
|
||||
pub mod pretty;
|
||||
#[cfg(feature="llvm")]
|
||||
pub mod target_features;
|
||||
mod derive_registrar;
|
||||
|
||||
|
@ -220,6 +228,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();
|
||||
}
|
||||
|
||||
|
@ -249,10 +258,12 @@ pub fn run_compiler<'a>(args: &[String],
|
|||
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;
|
||||
|
||||
|
@ -528,9 +539,11 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
|||
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 =
|
||||
|
@ -723,14 +736,14 @@ impl RustcDefaultCalls {
|
|||
};
|
||||
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()
|
||||
|
@ -779,6 +792,7 @@ impl RustcDefaultCalls {
|
|||
}
|
||||
PrintRequest::RelocationModels => {
|
||||
println!("Available relocation models:");
|
||||
#[cfg(features="llvm")]
|
||||
for &(name, _) in RELOC_MODEL_ARGS.iter() {
|
||||
println!(" {}", name);
|
||||
}
|
||||
|
@ -786,13 +800,17 @@ impl RustcDefaultCalls {
|
|||
}
|
||||
PrintRequest::CodeModels => {
|
||||
println!("Available code models:");
|
||||
#[cfg(features="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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -831,6 +849,7 @@ pub fn version(binary: &str, matches: &getopts::Matches) {
|
|||
println!("commit-date: {}", unw(commit_date_str()));
|
||||
println!("host: {}", config::host_triple());
|
||||
println!("release: {}", unw(release_str()));
|
||||
#[cfg(feature="llvm")]
|
||||
rustc_trans::print_version();
|
||||
}
|
||||
}
|
||||
|
@ -1128,6 +1147,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;
|
||||
}
|
||||
|
@ -1255,6 +1275,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 driver;
|
|||
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;
|
||||
|
@ -113,6 +114,7 @@ fn test_env<F>(source_string: &str,
|
|||
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::process::Command;
|
|||
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,7 @@ pub const RLIB_BYTECODE_OBJECT_V1_DATASIZE_OFFSET: usize =
|
|||
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 +204,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 +220,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();
|
||||
|
|
25
src/librustc_trans_utils/Cargo.toml
Normal file
25
src/librustc_trans_utils/Cargo.toml
Normal file
|
@ -0,0 +1,25 @@
|
|||
[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" }
|
||||
rustc_allocator = { path = "../librustc_allocator" }
|
||||
rustc_back = { path = "../librustc_back" }
|
||||
rustc_bitflags = { path = "../librustc_bitflags" }
|
||||
rustc_const_math = { path = "../librustc_const_math" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_incremental = { path = "../librustc_incremental" }
|
||||
rustc_llvm = { path = "../librustc_llvm" }
|
||||
rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
|
||||
serialize = { path = "../libserialize" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
38
src/librustc_trans_utils/lib.rs
Normal file
38
src/librustc_trans_utils/lib.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
// 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;
|
154
src/librustc_trans_utils/link.rs
Normal file
154
src/librustc_trans_utils/link.rs
Normal file
|
@ -0,0 +1,154 @@
|
|||
// 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
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue