about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/doc/rust.md9
-rw-r--r--src/librustc/driver/session.rs74
-rw-r--r--src/test/run-make/obey-crate-type-flag/Makefile13
-rw-r--r--src/test/run-make/obey-crate-type-flag/test.rs13
4 files changed, 74 insertions, 35 deletions
diff --git a/src/doc/rust.md b/src/doc/rust.md
index 5d505e55d2c..f2df445a5a2 100644
--- a/src/doc/rust.md
+++ b/src/doc/rust.md
@@ -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
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index a412742ab3a..f9a429a2a16 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -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 {
diff --git a/src/test/run-make/obey-crate-type-flag/Makefile b/src/test/run-make/obey-crate-type-flag/Makefile
new file mode 100644
index 00000000000..c28bc7c7b5e
--- /dev/null
+++ b/src/test/run-make/obey-crate-type-flag/Makefile
@@ -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
diff --git a/src/test/run-make/obey-crate-type-flag/test.rs b/src/test/run-make/obey-crate-type-flag/test.rs
new file mode 100644
index 00000000000..8eb82b48eac
--- /dev/null
+++ b/src/test/run-make/obey-crate-type-flag/test.rs
@@ -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"]
+