diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index b579a9b9c64c1..5aa22f7e6d561 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -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()), diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 950e6bd8ee833..58ccfeab73d18 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -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>, pub macro_registrar_fn: Cell>, pub default_sysroot: Option, - pub building_library: Cell, // 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, @@ -477,26 +475,6 @@ pub fn expect(sess: &Session, opt: Option, 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 } diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 7f4c560c146a1..959197e5b2b02 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -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"), diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index b5797b2571d3d..d7f4173b529c4 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -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) diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 441a3a3672983..a17c8fb5c433e 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -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(); } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 6e2edb4e8b2ae..644861b59fed6 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -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, + // 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, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index daed00a32f21d..960cc2f921aa4 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1663,7 +1663,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); } } @@ -2062,7 +2062,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 { 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() } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 26f0bc7ec728c..84b08851deb7b 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -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 => {} } } diff --git a/src/test/run-make/libs-and-bins/Makefile b/src/test/run-make/libs-and-bins/Makefile new file mode 100644 index 0000000000000..4d975d2f71718 --- /dev/null +++ b/src/test/run-make/libs-and-bins/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(RUSTC) foo.rs + $(call RUN,foo) + rm $(TMPDIR)/$(call DYLIB_GLOB,foo) + diff --git a/src/test/run-make/libs-and-bins/foo.rs b/src/test/run-make/libs-and-bins/foo.rs new file mode 100644 index 0000000000000..2ebe63928cad6 --- /dev/null +++ b/src/test/run-make/libs-and-bins/foo.rs @@ -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 or the MIT license +// , 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() {}