Skip to content

Make --crate-file-name obey --crate-type #13489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
74 changes: 41 additions & 33 deletions src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 13 additions & 0 deletions src/test/run-make/obey-crate-type-flag/Makefile
Original file line number Diff line number Diff line change
@@ -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
13 changes: 13 additions & 0 deletions src/test/run-make/obey-crate-type-flag/test.rs
Original file line number Diff line number Diff line change
@@ -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"]