Only check --crate-type flags if present.

Before, normal compilation and the --crate-file-name flag would
generate output based on both #![crate_type] attributes and
--crate-type flags. Now, if one or more flag is specified by command
line, only those will be used.

Closes #11573.
This commit is contained in:
JustAPerson 2014-04-13 14:26:02 -05:00
parent ecc774f788
commit 0162f8e6e1
4 changed files with 73 additions and 34 deletions

View File

@ -3920,7 +3920,9 @@ link Rust crates together, and more information about native libraries can be
found in the [ffi tutorial][ffi].
In one session of compilation, the compiler can generate multiple artifacts
through the usage of command line flags and the `crate_type` attribute.
through the usage of either command line flags or the `crate_type` attribute.
If one or more command line flag is specified, all `crate_type` attributes will
be ignored in favor of only building the artifacts specified by command line.
* `--crate-type=bin`, `#[crate_type = "bin"]` - A runnable executable will be
produced. This requires that there is a `main` function in the crate which
@ -3963,7 +3965,10 @@ through the usage of command line flags and the `crate_type` attribute.
Note that these outputs are stackable in the sense that if multiple are
specified, then the compiler will produce each form of output at once without
having to recompile.
having to recompile. However, this only applies for outputs specified by the same
method. If only `crate_type` attributes are specified, then they will all be
built, but if one or more `--crate-type` command line flag is specified,
then only those outputs will be built.
With all these different kinds of outputs, if crate A depends on crate B, then
the compiler could find B in various different forms throughout the system. The

View File

@ -498,43 +498,51 @@ pub fn collect_crate_types(session: &Session,
if session.opts.test {
return vec!(CrateTypeExecutable)
}
// Only check command line flags if present. If no types are specified by
// command line, then reuse the empty `base` Vec to hold the types that
// will be found in crate attributes.
let mut base = session.opts.crate_types.clone();
let iter = attrs.iter().filter_map(|a| {
if a.name().equiv(&("crate_type")) {
match a.value_str() {
Some(ref n) if n.equiv(&("rlib")) => Some(CrateTypeRlib),
Some(ref n) if n.equiv(&("dylib")) => Some(CrateTypeDylib),
Some(ref n) if n.equiv(&("lib")) => {
Some(default_lib_output())
}
Some(ref n) if n.equiv(&("staticlib")) => {
Some(CrateTypeStaticlib)
}
Some(ref n) if n.equiv(&("bin")) => Some(CrateTypeExecutable),
Some(_) => {
session.add_lint(lint::UnknownCrateType,
ast::CRATE_NODE_ID,
a.span,
~"invalid `crate_type` value");
None
}
_ => {
session.add_lint(lint::UnknownCrateType, ast::CRATE_NODE_ID,
a.span, ~"`crate_type` requires a value");
None
if base.len() > 0 {
return base
} else {
let iter = attrs.iter().filter_map(|a| {
if a.name().equiv(&("crate_type")) {
match a.value_str() {
Some(ref n) if n.equiv(&("rlib")) => Some(CrateTypeRlib),
Some(ref n) if n.equiv(&("dylib")) => Some(CrateTypeDylib),
Some(ref n) if n.equiv(&("lib")) => {
Some(default_lib_output())
}
Some(ref n) if n.equiv(&("staticlib")) => {
Some(CrateTypeStaticlib)
}
Some(ref n) if n.equiv(&("bin")) => Some(CrateTypeExecutable),
Some(_) => {
session.add_lint(lint::UnknownCrateType,
ast::CRATE_NODE_ID,
a.span,
~"invalid `crate_type` value");
None
}
_ => {
session.add_lint(lint::UnknownCrateType, ast::CRATE_NODE_ID,
a.span, ~"`crate_type` requires a value");
None
}
}
} else {
None
}
} else {
None
});
base.extend(iter);
if base.len() == 0 {
base.push(CrateTypeExecutable);
}
});
base.extend(iter);
if base.len() == 0 {
base.push(CrateTypeExecutable);
base.as_mut_slice().sort();
base.dedup();
return base;
}
base.as_mut_slice().sort();
base.dedup();
return base;
}
pub fn sess_os_to_meta_os(os: abi::Os) -> metadata::loader::Os {

View File

@ -0,0 +1,13 @@
-include ../tools.mk
# check that rustc builds all crate_type attributes
# delete rlib
# delete whatever dylib is made for this system
# check that rustc only builds --crate-type flags, ignoring attributes
# fail if an rlib was built
all:
$(RUSTC) test.rs
rm $(TMPDIR)/libtest*.rlib
rm $(TMPDIR)/libtest*
$(RUSTC) --crate-type dylib test.rs
rm $(TMPDIR)/libtest*.rlib && exit 1 || exit 0

View File

@ -0,0 +1,13 @@
// 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 = "rlib"]
#![crate_type = "dylib"]