Skip to content

Commit

Permalink
rustc/rusti/rustpkg: Infer packages from extern mod directives
Browse files Browse the repository at this point in the history
This commit won't be quite as useful until I implement RUST_PATH and
until we change `extern mod` to take a general string instead of
an identifier (rust-lang#5682 and rust-lang#6407).

With that said, now if you're using rustpkg and a program contains:

extern mod foo;

rustpkg will attempt to search for `foo`, so that you don't have to
provide a -L directory explicitly. In addition, rustpkg will
actually try to build and install `foo`, unless it's already
installed (specifically, I tested that `extern mod extra;` would
not cause it to try to find source for `extra` and compile it
again).

This is as per rust-lang#5681.

Incidentally, I changed some driver code to infer the link name
from the crate link_meta attributes. If that change isn't ok, say
something.
  • Loading branch information
catamorphism committed May 28, 2013
1 parent b7397b1 commit af6aad6
Show file tree
Hide file tree
Showing 15 changed files with 628 additions and 377 deletions.
126 changes: 76 additions & 50 deletions src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,15 @@ pub fn parse_input(sess: Session, cfg: ast::crate_cfg, input: &input)
}
}

/// First phase to do, last phase to do
#[deriving(Eq)]
pub enum compile_upto {
pub struct compile_upto {
from: compile_phase,
to: compile_phase
}

#[deriving(Eq)]
pub enum compile_phase {
cu_parse,
cu_expand,
cu_typeck,
Expand All @@ -175,27 +182,32 @@ pub enum compile_upto {
#[fixed_stack_segment]
pub fn compile_rest(sess: Session,
cfg: ast::crate_cfg,
upto: compile_upto,
phases: compile_upto,
outputs: Option<@OutputFilenames>,
curr: Option<@ast::crate>)
-> (@ast::crate, Option<ty::ctxt>) {
let time_passes = sess.time_passes();
let mut crate = curr.get();

*sess.building_library = session::building_library(
sess.opts.crate_type, crate, sess.opts.test);
if phases.from == cu_parse || phases.from == cu_everything {

crate = time(time_passes, ~"expansion", ||
syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg,
crate));
*sess.building_library = session::building_library(
sess.opts.crate_type, crate, sess.opts.test);

crate = time(time_passes, ~"configuration", ||
front::config::strip_unconfigured_items(crate));
crate = time(time_passes, ~"expansion", ||
syntax::ext::expand::expand_crate(sess.parse_sess, copy cfg,
crate));

crate = time(time_passes, ~"maybe building test harness", ||
front::test::modify_for_testing(sess, crate));
crate = time(time_passes, ~"configuration", ||
front::config::strip_unconfigured_items(crate));

crate = time(time_passes, ~"maybe building test harness", ||
front::test::modify_for_testing(sess, crate));
}

if upto == cu_expand { return (crate, None); }
if phases.to == cu_expand { return (crate, None); }

assert!(phases.from != cu_no_trans);

crate = time(time_passes, ~"intrinsic injection", ||
front::intrinsic_inject::inject_intrinsic(sess, crate));
Expand All @@ -214,27 +226,26 @@ pub fn compile_rest(sess: Session,
sess.parse_sess.interner));

let lang_items = time(time_passes, ~"language item collection", ||
middle::lang_items::collect_language_items(crate, sess));

middle::lang_items::collect_language_items(crate, sess));
let middle::resolve::CrateMap {
def_map: def_map,
exp_map2: exp_map2,
trait_map: trait_map
} =
time(time_passes, ~"resolution", ||
middle::resolve::resolve_crate(sess, lang_items, crate));
trait_map: trait_map
} =
time(time_passes, ~"resolution", ||
middle::resolve::resolve_crate(sess, lang_items, crate));

time(time_passes, ~"looking for entry point",
|| middle::entry::find_entry_point(sess, crate, ast_map));

let freevars = time(time_passes, ~"freevar finding", ||
freevars::annotate_freevars(def_map, crate));
freevars::annotate_freevars(def_map, crate));

let region_map = time(time_passes, ~"region resolution", ||
middle::region::resolve_crate(sess, def_map, crate));
middle::region::resolve_crate(sess, def_map, crate));

let rp_set = time(time_passes, ~"region parameterization inference", ||
middle::region::determine_rp_in_crate(sess, ast_map, def_map, crate));
middle::region::determine_rp_in_crate(sess, ast_map, def_map, crate));

let outputs = outputs.get();

Expand All @@ -255,7 +266,7 @@ pub fn compile_rest(sess: Session,
middle::check_const::check_crate(sess, crate, ast_map, def_map,
method_map, ty_cx));

if upto == cu_typeck { return (crate, Some(ty_cx)); }
if phases.to == cu_typeck { return (crate, Some(ty_cx)); }

time(time_passes, ~"privacy checking", ||
middle::privacy::check_crate(ty_cx, &method_map, crate));
Expand Down Expand Up @@ -289,7 +300,7 @@ pub fn compile_rest(sess: Session,
time(time_passes, ~"lint checking", ||
lint::check_crate(ty_cx, crate));

if upto == cu_no_trans { return (crate, Some(ty_cx)); }
if phases.to == cu_no_trans { return (crate, Some(ty_cx)); }

let maps = astencode::Maps {
root_map: root_map,
Expand Down Expand Up @@ -346,23 +357,24 @@ pub fn compile_rest(sess: Session,
}

pub fn compile_upto(sess: Session, cfg: ast::crate_cfg,
input: &input, upto: compile_upto,
input: &input, upto: compile_phase,
outputs: Option<@OutputFilenames>)
-> (@ast::crate, Option<ty::ctxt>) {
let time_passes = sess.time_passes();
let crate = time(time_passes, ~"parsing",
|| parse_input(sess, copy cfg, input) );
if upto == cu_parse { return (crate, None); }

compile_rest(sess, cfg, upto, outputs, Some(crate))
compile_rest(sess, cfg, compile_upto { from: cu_parse, to: upto },
outputs, Some(crate))
}

pub fn compile_input(sess: Session, cfg: ast::crate_cfg, input: &input,
outdir: &Option<Path>, output: &Option<Path>) {
let upto = if sess.opts.parse_only { cu_parse }
else if sess.opts.no_trans { cu_no_trans }
else { cu_everything };
let outputs = build_output_filenames(input, outdir, output, sess);
let outputs = build_output_filenames(input, outdir, output, [], sess); // ???
compile_upto(sess, cfg, input, upto, Some(outputs));
}

Expand Down Expand Up @@ -640,8 +652,7 @@ pub fn build_session_options(binary: @~str,
~"2" => Default,
~"3" => Aggressive,
_ => {
early_error(demitter, ~"optimization level needs " +
~"to be between 0-3")
early_error(demitter, ~"optimization level needs to be between 0-3")
}
}
} else { No }
Expand Down Expand Up @@ -833,6 +844,7 @@ pub struct OutputFilenames {
pub fn build_output_filenames(input: &input,
odir: &Option<Path>,
ofile: &Option<Path>,
attrs: &[ast::attribute],
sess: Session)
-> @OutputFilenames {
let obj_path;
Expand All @@ -842,7 +854,6 @@ pub fn build_output_filenames(input: &input,
sopts.output_type != link::output_type_exe ||
sopts.is_static && *sess.building_library;


let obj_suffix =
match sopts.output_type {
link::output_type_none => ~"none",
Expand All @@ -855,29 +866,44 @@ pub fn build_output_filenames(input: &input,

match *ofile {
None => {
// "-" as input file will cause the parser to read from stdin so we
// have to make up a name
// We want to toss everything after the final '.'
let dirpath = match *odir {
Some(ref d) => (/*bad*/copy *d),
None => match *input {
str_input(_) => os::getcwd(),
file_input(ref ifile) => (*ifile).dir_path()
// "-" as input file will cause the parser to read from stdin so we
// have to make up a name
// We want to toss everything after the final '.'
let dirpath = match *odir {
Some(ref d) => (/*bad*/copy *d),
None => match *input {
str_input(_) => os::getcwd(),
file_input(ref ifile) => (*ifile).dir_path()
}
};

let mut stem = match *input {
file_input(ref ifile) => (*ifile).filestem().get(),
str_input(_) => ~"rust_out"
};

// If a linkage name meta is present, we use it as the link name
let linkage_metas = attr::find_linkage_metas(attrs);
if !linkage_metas.is_empty() {
// But if a linkage meta is present, that overrides
let maybe_matches = attr::find_meta_items_by_name(linkage_metas, "name");
if !maybe_matches.is_empty() {
match attr::get_meta_item_value_str(maybe_matches[0]) {
Some(s) => stem = copy *s,
_ => ()
}
}
// If the name is missing, we just default to the filename
// version
}
};

let stem = match *input {
file_input(ref ifile) => (*ifile).filestem().get(),
str_input(_) => ~"rust_out"
};

if *sess.building_library {
out_path = dirpath.push(os::dll_filename(stem));
obj_path = dirpath.push(stem).with_filetype(obj_suffix);
} else {
out_path = dirpath.push(stem);
obj_path = dirpath.push(stem).with_filetype(obj_suffix);
}
if *sess.building_library {
out_path = dirpath.push(os::dll_filename(stem));
obj_path = dirpath.push(stem).with_filetype(obj_suffix);
} else {
out_path = dirpath.push(stem);
obj_path = dirpath.push(stem).with_filetype(obj_suffix);
}
}

Some(ref out_file) => {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/rustc.rc
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,11 @@ pub fn version(argv0: &str) {

pub fn usage(argv0: &str) {
let message = fmt!("Usage: %s [OPTIONS] INPUT", argv0);
io::println(groups::usage(message, optgroups()) +
~"Additional help:
-W help Print 'lint' options and default settings
-Z help Print internal options for debugging rustc
");
io::println(fmt!("%s \
Additional help: \
-W help Print 'lint' options and default settings \
-Z help Print internal options for debugging rustc",
groups::usage(message, optgroups())));
}

pub fn describe_warnings() {
Expand Down
4 changes: 2 additions & 2 deletions src/librusti/rusti.rc
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ fn run(repl: Repl, input: ~str) -> Repl {
binary,
&wrapped);

let outputs = driver::build_output_filenames(&wrapped, &None, &None, sess);
let outputs = driver::build_output_filenames(&wrapped, &None, &None, [], sess);
debug!("calling compile_upto");
let (crate, _) = driver::compile_upto(sess, cfg, &wrapped,
driver::cu_everything,
Expand Down Expand Up @@ -195,7 +195,7 @@ fn compile_crate(src_filename: ~str, binary: ~str) -> Option<bool> {
*sess.building_library = true;
let cfg = driver::build_configuration(sess, binary, &input);
let outputs = driver::build_output_filenames(
&input, &None, &None, sess);
&input, &None, &None, [], sess);
// If the library already exists and is newer than the source
// file, skip compilation and return None.
let mut should_compile = true;
Expand Down
4 changes: 2 additions & 2 deletions src/librustpkg/conditions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// Useful conditions

pub use core::path::Path;
pub use util::PkgId;
pub use package_id::PkgId;

condition! {
bad_path: (super::Path, ~str) -> super::Path;
Expand All @@ -30,5 +30,5 @@ condition! {
}

condition! {
bad_pkg_id: (super::Path, ~str) -> ::util::PkgId;
bad_pkg_id: (super::Path, ~str) -> super::PkgId;
}
Loading

0 comments on commit af6aad6

Please sign in to comment.