auto merge of #13905 : alexcrichton/rust/issue-13337, r=thestinger
This has long since not been too relevant since the introduction of many crate type outputs. This commit removes the flag entirely, adjusting all logic to do the most reasonable thing when building both a library and an executable. Closes #13337
This commit is contained in:
commit
b0977b1e0f
@ -210,7 +210,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
-> (ast::Crate, syntax::ast_map::Map) {
|
||||
let time_passes = sess.time_passes();
|
||||
|
||||
sess.building_library.set(session::building_library(&sess.opts, &krate));
|
||||
*sess.crate_types.borrow_mut() = session::collect_crate_types(sess, krate.attrs.as_slice());
|
||||
|
||||
time(time_passes, "gated feature checking", (), |_|
|
||||
@ -1046,7 +1045,6 @@ pub fn build_session_(sopts: session::Options,
|
||||
entry_type: Cell::new(None),
|
||||
macro_registrar_fn: Cell::new(None),
|
||||
default_sysroot: default_sysroot,
|
||||
building_library: Cell::new(false),
|
||||
local_crate_source_file: local_crate_source_file,
|
||||
working_dir: os::getcwd(),
|
||||
lints: RefCell::new(NodeMap::new()),
|
||||
|
@ -25,7 +25,6 @@ use syntax::codemap::Span;
|
||||
use syntax::diagnostic;
|
||||
use syntax::parse::ParseSess;
|
||||
use syntax::{abi, ast, codemap};
|
||||
use syntax;
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use collections::HashSet;
|
||||
@ -185,7 +184,6 @@ pub struct Session {
|
||||
pub entry_type: Cell<Option<EntryFnType>>,
|
||||
pub macro_registrar_fn: Cell<Option<ast::NodeId>>,
|
||||
pub default_sysroot: Option<Path>,
|
||||
pub building_library: Cell<bool>,
|
||||
// The name of the root source file of the crate, in the local file system. The path is always
|
||||
// expected to be absolute. `None` means that there is no source file.
|
||||
pub local_crate_source_file: Option<Path>,
|
||||
@ -477,26 +475,6 @@ pub fn expect<T:Clone>(sess: &Session, opt: Option<T>, msg: || -> ~str) -> T {
|
||||
diagnostic::expect(sess.diagnostic(), opt, msg)
|
||||
}
|
||||
|
||||
pub fn building_library(options: &Options, krate: &ast::Crate) -> bool {
|
||||
if options.test { return false }
|
||||
for output in options.crate_types.iter() {
|
||||
match *output {
|
||||
CrateTypeExecutable => {}
|
||||
CrateTypeStaticlib | CrateTypeDylib | CrateTypeRlib => return true
|
||||
}
|
||||
}
|
||||
match syntax::attr::first_attr_value_str_by_name(krate.attrs.as_slice(),
|
||||
"crate_type") {
|
||||
Some(s) => {
|
||||
s.equiv(&("lib")) ||
|
||||
s.equiv(&("rlib")) ||
|
||||
s.equiv(&("dylib")) ||
|
||||
s.equiv(&("staticlib"))
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_lib_output() -> CrateType {
|
||||
CrateTypeRlib
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
use driver::session;
|
||||
use driver::session::Session;
|
||||
|
||||
use syntax::ast;
|
||||
@ -86,7 +86,10 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
||||
span: DUMMY_SP
|
||||
});
|
||||
|
||||
if use_start(&krate) && !self.sess.building_library.get() {
|
||||
let any_exe = self.sess.crate_types.borrow().iter().any(|ty| {
|
||||
*ty == session::CrateTypeExecutable
|
||||
});
|
||||
if use_start(&krate) && any_exe {
|
||||
vis.push(ast::ViewItem {
|
||||
node: ast::ViewItemExternCrate(token::str_to_ident("native"),
|
||||
with_version("native"),
|
||||
|
@ -125,27 +125,23 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
||||
// Remove any #[main] from the AST so it doesn't clash with
|
||||
// the one we're going to add. Only if compiling an executable.
|
||||
|
||||
fn nomain(cx: &TestCtxt, item: @ast::Item) -> @ast::Item {
|
||||
if !cx.sess.building_library.get() {
|
||||
@ast::Item {
|
||||
attrs: item.attrs.iter().filter_map(|attr| {
|
||||
if !attr.name().equiv(&("main")) {
|
||||
Some(*attr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect(),
|
||||
.. (*item).clone()
|
||||
}
|
||||
} else {
|
||||
item
|
||||
fn nomain(item: @ast::Item) -> @ast::Item {
|
||||
@ast::Item {
|
||||
attrs: item.attrs.iter().filter_map(|attr| {
|
||||
if !attr.name().equiv(&("main")) {
|
||||
Some(*attr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect(),
|
||||
.. (*item).clone()
|
||||
}
|
||||
}
|
||||
|
||||
let mod_nomain = ast::Mod {
|
||||
inner: m.inner,
|
||||
view_items: m.view_items.clone(),
|
||||
items: m.items.iter().map(|i| nomain(&self.cx, *i)).collect(),
|
||||
items: m.items.iter().map(|i| nomain(*i)).collect(),
|
||||
};
|
||||
|
||||
fold::noop_fold_mod(&mod_nomain, self)
|
||||
|
@ -48,9 +48,12 @@ impl<'a> Visitor<()> for EntryContext<'a> {
|
||||
}
|
||||
|
||||
pub fn find_entry_point(session: &Session, krate: &Crate, ast_map: &ast_map::Map) {
|
||||
if session.building_library.get() {
|
||||
let any_exe = session.crate_types.borrow().iter().any(|ty| {
|
||||
*ty == session::CrateTypeExecutable
|
||||
});
|
||||
if !any_exe {
|
||||
// No need to find a main function
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
// If the user wants no main function at all, then stop here.
|
||||
@ -132,18 +135,16 @@ fn configure_main(this: &mut EntryContext) {
|
||||
*this.session.entry_fn.borrow_mut() = this.main_fn;
|
||||
this.session.entry_type.set(Some(session::EntryMain));
|
||||
} else {
|
||||
if !this.session.building_library.get() {
|
||||
// No main function
|
||||
this.session.err("main function not found");
|
||||
if !this.non_main_fns.is_empty() {
|
||||
// There were some functions named 'main' though. Try to give the user a hint.
|
||||
this.session.note("the main function must be defined at the crate level \
|
||||
but you have one or more functions named 'main' that are not \
|
||||
defined at the crate level. Either move the definition or \
|
||||
attach the `#[main]` attribute to override this behavior.");
|
||||
for &(_, span) in this.non_main_fns.iter() {
|
||||
this.session.span_note(span, "here is a function named 'main'");
|
||||
}
|
||||
// No main function
|
||||
this.session.err("main function not found");
|
||||
if !this.non_main_fns.is_empty() {
|
||||
// There were some functions named 'main' though. Try to give the user a hint.
|
||||
this.session.note("the main function must be defined at the crate level \
|
||||
but you have one or more functions named 'main' that are not \
|
||||
defined at the crate level. Either move the definition or \
|
||||
attach the `#[main]` attribute to override this behavior.");
|
||||
for &(_, span) in this.non_main_fns.iter() {
|
||||
this.session.span_note(span, "here is a function named 'main'");
|
||||
}
|
||||
this.session.abort_if_errors();
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
// makes all other generics or inline functions that it references
|
||||
// reachable as well.
|
||||
|
||||
use driver::session;
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use middle::privacy;
|
||||
@ -89,6 +90,8 @@ struct ReachableContext<'a> {
|
||||
// A worklist of item IDs. Each item ID in this worklist will be inlined
|
||||
// and will be scanned for further references.
|
||||
worklist: Vec<ast::NodeId>,
|
||||
// Whether any output of this compilation is a library
|
||||
any_library: bool,
|
||||
}
|
||||
|
||||
impl<'a> Visitor<()> for ReachableContext<'a> {
|
||||
@ -157,10 +160,14 @@ impl<'a> Visitor<()> for ReachableContext<'a> {
|
||||
impl<'a> ReachableContext<'a> {
|
||||
// Creates a new reachability computation context.
|
||||
fn new(tcx: &'a ty::ctxt) -> ReachableContext<'a> {
|
||||
let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
|
||||
*ty != session::CrateTypeExecutable
|
||||
});
|
||||
ReachableContext {
|
||||
tcx: tcx,
|
||||
reachable_symbols: NodeSet::new(),
|
||||
worklist: Vec::new(),
|
||||
any_library: any_library,
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,7 +241,7 @@ impl<'a> ReachableContext<'a> {
|
||||
|
||||
fn propagate_node(&mut self, node: &ast_map::Node,
|
||||
search_item: ast::NodeId) {
|
||||
if !self.tcx.sess.building_library.get() {
|
||||
if !self.any_library {
|
||||
// If we are building an executable, then there's no need to flag
|
||||
// anything as external except for `extern fn` types. These
|
||||
// functions may still participate in some form of native interface,
|
||||
|
@ -1701,7 +1701,7 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: ~str, node_id: ast::Nod
|
||||
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
|
||||
}
|
||||
|
||||
if is_entry_fn(ccx.sess(), node_id) && !ccx.sess().building_library.get() {
|
||||
if is_entry_fn(ccx.sess(), node_id) {
|
||||
create_entry_wrapper(ccx, sp, llfn);
|
||||
}
|
||||
}
|
||||
@ -2100,7 +2100,10 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeI
|
||||
pub fn write_metadata(cx: &CrateContext, krate: &ast::Crate) -> Vec<u8> {
|
||||
use flate;
|
||||
|
||||
if !cx.sess().building_library.get() {
|
||||
let any_library = cx.sess().crate_types.borrow().iter().any(|ty| {
|
||||
*ty != session::CrateTypeExecutable
|
||||
});
|
||||
if !any_library {
|
||||
return Vec::new()
|
||||
}
|
||||
|
||||
|
@ -409,16 +409,14 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
|
||||
|
||||
fn check_for_entry_fn(ccx: &CrateCtxt) {
|
||||
let tcx = ccx.tcx;
|
||||
if !tcx.sess.building_library.get() {
|
||||
match *tcx.sess.entry_fn.borrow() {
|
||||
Some((id, sp)) => match tcx.sess.entry_type.get() {
|
||||
Some(session::EntryMain) => check_main_fn_ty(ccx, id, sp),
|
||||
Some(session::EntryStart) => check_start_fn_ty(ccx, id, sp),
|
||||
Some(session::EntryNone) => {}
|
||||
None => tcx.sess.bug("entry function without a type")
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
match *tcx.sess.entry_fn.borrow() {
|
||||
Some((id, sp)) => match tcx.sess.entry_type.get() {
|
||||
Some(session::EntryMain) => check_main_fn_ty(ccx, id, sp),
|
||||
Some(session::EntryStart) => check_start_fn_ty(ccx, id, sp),
|
||||
Some(session::EntryNone) => {}
|
||||
None => tcx.sess.bug("entry function without a type")
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
7
src/test/run-make/libs-and-bins/Makefile
Normal file
7
src/test/run-make/libs-and-bins/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) foo.rs
|
||||
$(call RUN,foo)
|
||||
rm $(TMPDIR)/$(call DYLIB_GLOB,foo)
|
||||
|
14
src/test/run-make/libs-and-bins/foo.rs
Normal file
14
src/test/run-make/libs-and-bins/foo.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
#![crate_type = "dylib"]
|
||||
#![crate_type = "bin"]
|
||||
|
||||
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user