Skip to content

rustc: Improve crate id extraction #11077

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

Merged
merged 1 commit into from
Dec 21, 2013
Merged
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
4 changes: 2 additions & 2 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ pub mod write {
*/

pub fn build_link_meta(sess: Session,
c: &ast::Crate,
attrs: &[ast::Attribute],
output: &Path,
symbol_hasher: &mut Sha256)
-> LinkMeta {
Expand All @@ -458,7 +458,7 @@ pub fn build_link_meta(sess: Session,
truncated_hash_result(symbol_hasher).to_managed()
}

let pkgid = match attr::find_pkgid(c.attrs) {
let pkgid = match attr::find_pkgid(attrs) {
None => {
let stem = session::expect(
sess,
Expand Down
38 changes: 1 addition & 37 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub fn phase_2_configure_and_expand(sess: Session,
let time_passes = sess.time_passes();

*sess.building_library = session::building_library(sess.opts, &crate);
*sess.outputs = session::collect_outputs(sess.opts, &crate);
*sess.outputs = session::collect_outputs(sess.opts, crate.attrs);

time(time_passes, "gated feature checking", (), |_|
front::feature_gate::check_crate(sess, &crate));
Expand Down Expand Up @@ -446,42 +446,6 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
let (outputs, trans) = {
let expanded_crate = {
let crate = phase_1_parse_input(sess, cfg.clone(), input);
let (crate_id, crate_name, crate_file_name) = sess.opts.print_metas;
// these nasty nested conditions are to avoid doing extra work
if crate_id || crate_name || crate_file_name {
let t_outputs = build_output_filenames(input, outdir, output, crate.attrs, sess);
if crate_id || crate_name {
let pkgid = match attr::find_pkgid(crate.attrs) {
Some(pkgid) => pkgid,
None => fail!("No crate_id and --crate-id or --crate-name requested")
};
if crate_id {
println(pkgid.to_str());
}
if crate_name {
println(pkgid.name);
}
}

if crate_file_name {
let lm = link::build_link_meta(sess, &crate, &t_outputs.obj_filename,
&mut ::util::sha2::Sha256::new());
// if the vector is empty we default to OutputExecutable.
let style = sess.opts.outputs.get_opt(0).unwrap_or(&OutputExecutable);
let fname = link::filename_for_input(&sess, *style, &lm,
&t_outputs.out_filename);
println!("{}", fname.display());

// we already maybe printed the first one, so skip it
for style in sess.opts.outputs.iter().skip(1) {
let fname = link::filename_for_input(&sess, *style, &lm,
&t_outputs.out_filename);
println!("{}", fname.display());
}
}

return;
}
if stop_after_phase_1(sess) { return; }
phase_2_configure_and_expand(sess, cfg, crate)
};
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/driver/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,14 +421,15 @@ pub fn building_library(options: &options, crate: &ast::Crate) -> bool {
}
}

pub fn collect_outputs(options: &options, crate: &ast::Crate) -> ~[OutputStyle] {
pub fn collect_outputs(options: &options,
attrs: &[ast::Attribute]) -> ~[OutputStyle] {
// If we're generating a test executable, then ignore all other output
// styles at all other locations
if options.test {
return ~[OutputExecutable];
}
let mut base = options.outputs.clone();
let mut iter = crate.attrs.iter().filter_map(|a| {
let mut iter = attrs.iter().filter_map(|a| {
if "crate_type" == a.name() {
match a.value_str() {
Some(n) if "rlib" == n => Some(OutputRlib),
Expand Down
100 changes: 75 additions & 25 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,12 @@
extern mod extra;
extern mod syntax;

use driver::driver::{host_triple, optgroups, early_error};
use driver::driver::{str_input, file_input, build_session_options};
use driver::driver::{build_session, build_configuration, parse_pretty};
use driver::driver::{PpMode, pretty_print_input, list_metadata};
use driver::driver::{compile_input};
use back::link;
use driver::session;
use middle::lint;

use d = driver::driver;

use std::cast;
use std::comm;
use std::io;
Expand All @@ -41,9 +39,12 @@ use std::task;
use std::vec;
use extra::getopts::groups;
use extra::getopts;
use syntax::ast;
use syntax::attr;
use syntax::codemap;
use syntax::diagnostic::Emitter;
use syntax::diagnostic;
use syntax::parse;

pub mod middle {
pub mod trans;
Expand Down Expand Up @@ -137,7 +138,7 @@ pub fn version(argv0: &str) {
None => "unknown version"
};
println!("{} {}", argv0, vers);
println!("host: {}", host_triple());
println!("host: {}", d::host_triple());
}

pub fn usage(argv0: &str) {
Expand All @@ -146,7 +147,7 @@ pub fn usage(argv0: &str) {
Additional help:
-W help Print 'lint' options and default settings
-Z help Print internal options for debugging rustc\n",
groups::usage(message, optgroups()));
groups::usage(message, d::optgroups()));
}

pub fn describe_warnings() {
Expand Down Expand Up @@ -206,10 +207,10 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
if args.is_empty() { usage(binary); return; }

let matches =
&match getopts::groups::getopts(args, optgroups()) {
&match getopts::groups::getopts(args, d::optgroups()) {
Ok(m) => m,
Err(f) => {
early_error(demitter, f.to_err_msg());
d::early_error(demitter, f.to_err_msg());
}
};

Expand Down Expand Up @@ -246,48 +247,97 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
return;
}
let input = match matches.free.len() {
0u => early_error(demitter, "no input filename given"),
0u => d::early_error(demitter, "no input filename given"),
1u => {
let ifile = matches.free[0].as_slice();
if "-" == ifile {
let src = str::from_utf8_owned(io::stdin().read_to_end());
str_input(src.to_managed())
d::str_input(src.to_managed())
} else {
file_input(Path::new(ifile))
d::file_input(Path::new(ifile))
}
}
_ => early_error(demitter, "multiple input filenames provided")
_ => d::early_error(demitter, "multiple input filenames provided")
};

let sopts = build_session_options(binary, matches, demitter);
let sess = build_session(sopts, demitter);
let sopts = d::build_session_options(binary, matches, demitter);
let sess = d::build_session(sopts, demitter);
let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
let ofile = matches.opt_str("o").map(|o| Path::new(o));
let cfg = build_configuration(sess);
let cfg = d::build_configuration(sess);
let pretty = matches.opt_default("pretty", "normal").map(|a| {
parse_pretty(sess, a)
d::parse_pretty(sess, a)
});
match pretty {
Some::<PpMode>(ppm) => {
pretty_print_input(sess, cfg, &input, ppm);
Some::<d::PpMode>(ppm) => {
d::pretty_print_input(sess, cfg, &input, ppm);
return;
}
None::<PpMode> => {/* continue */ }
None::<d::PpMode> => {/* continue */ }
}
let ls = matches.opt_present("ls");
if ls {
match input {
file_input(ref ifile) => {
list_metadata(sess, &(*ifile), @mut io::stdout() as @mut io::Writer);
d::file_input(ref ifile) => {
d::list_metadata(sess, &(*ifile),
@mut io::stdout() as @mut io::Writer);
}
str_input(_) => {
early_error(demitter, "can not list metadata for stdin");
d::str_input(_) => {
d::early_error(demitter, "can not list metadata for stdin");
}
}
return;
}
let (crate_id, crate_name, crate_file_name) = sopts.print_metas;
// these nasty nested conditions are to avoid doing extra work
if crate_id || crate_name || crate_file_name {
let attrs = parse_crate_attrs(sess, &input);
let t_outputs = d::build_output_filenames(&input, &odir, &ofile,
attrs, sess);
if crate_id || crate_name {
let pkgid = match attr::find_pkgid(attrs) {
Some(pkgid) => pkgid,
None => {
sess.fatal("No crate_id and --crate-id or \
--crate-name requested")
}
};
if crate_id {
println(pkgid.to_str());
}
if crate_name {
println(pkgid.name);
}
}

if crate_file_name {
let lm = link::build_link_meta(sess, attrs, &t_outputs.obj_filename,
&mut ::util::sha2::Sha256::new());
let outputs = session::collect_outputs(sopts, attrs);
for &style in outputs.iter() {
let fname = link::filename_for_input(&sess, style, &lm,
&t_outputs.out_filename);
println!("{}", fname.filename_display());
}
}

return;
}

d::compile_input(sess, cfg, &input, &odir, &ofile);
}

compile_input(sess, cfg, &input, &odir, &ofile);
fn parse_crate_attrs(sess: session::Session,
input: &d::input) -> ~[ast::Attribute] {
match *input {
d::file_input(ref ifile) => {
parse::parse_crate_attrs_from_file(ifile, ~[], sess.parse_sess)
}
d::str_input(src) => {
parse::parse_crate_attrs_from_source_str(
d::anon_src(), src, ~[], sess.parse_sess)
}
}
}

#[deriving(Eq)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3096,7 +3096,7 @@ pub fn trans_crate(sess: session::Session,
}

let mut symbol_hasher = Sha256::new();
let link_meta = link::build_link_meta(sess, &crate, output,
let link_meta = link::build_link_meta(sess, crate.attrs, output,
&mut symbol_hasher);

// Append ".rc" to crate name as LLVM module identifier.
Expand Down
24 changes: 24 additions & 0 deletions src/libsyntax/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ pub fn parse_crate_from_file(
// why is there no p.abort_if_errors here?
}

pub fn parse_crate_attrs_from_file(
input: &Path,
cfg: ast::CrateConfig,
sess: @mut ParseSess
) -> ~[ast::Attribute] {
let parser = new_parser_from_file(sess, cfg, input);
let (inner, _) = parser.parse_inner_attrs_and_next();
return inner;
}

pub fn parse_crate_from_source_str(
name: @str,
source: @str,
Expand All @@ -92,6 +102,20 @@ pub fn parse_crate_from_source_str(
maybe_aborted(p.parse_crate_mod(),p)
}

pub fn parse_crate_attrs_from_source_str(
name: @str,
source: @str,
cfg: ast::CrateConfig,
sess: @mut ParseSess
) -> ~[ast::Attribute] {
let p = new_parser_from_source_str(sess,
/*bad*/ cfg.clone(),
name,
source);
let (inner, _) = maybe_aborted(p.parse_inner_attrs_and_next(),p);
return inner;
}

pub fn parse_expr_from_source_str(
name: @str,
source: @str,
Expand Down
10 changes: 10 additions & 0 deletions src/test/run-make/crate-data-smoke/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-include ../tools.mk

all:
[ `$(RUSTC) --crate-id crate.rs` = "foo#0.9" ]
[ `$(RUSTC) --crate-name crate.rs` = "foo" ]
[ `$(RUSTC) --crate-file-name crate.rs` = "foo" ]
[ `$(RUSTC) --crate-file-name --lib --test crate.rs` = "foo" ]
[ `$(RUSTC) --crate-file-name --test lib.rs` = "mylib" ]
$(RUSTC) --crate-file-name lib.rs
$(RUSTC) --crate-file-name rlib.rs
7 changes: 7 additions & 0 deletions src/test/run-make/crate-data-smoke/crate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#[crate_id = "foo#0.9"];

// Querying about the crate metadata should *not* parse the entire crate, it
// only needs the crate attributes (which are guaranteed to be at the top) be
// sure that if we have an error like a missing module that we can still query
// about the crate id.
mod error;
2 changes: 2 additions & 0 deletions src/test/run-make/crate-data-smoke/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#[crate_id = "mylib"];
#[crate_type = "lib"];
2 changes: 2 additions & 0 deletions src/test/run-make/crate-data-smoke/rlib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#[crate_id = "mylib"];
#[crate_type = "rlib"];