Skip to content

Commit c120464

Browse files
committed
rustc/rusti/rustpkg: Infer packages from extern mod directives
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. Also, I changed the addl_lib_search_paths field in the session options to be an @mut ~[Path] so that it can be modified after expansion but before later phases.
1 parent 341678b commit c120464

File tree

17 files changed

+729
-472
lines changed

17 files changed

+729
-472
lines changed

src/librustc/driver/driver.rs

+152-121
Large diffs are not rendered by default.

src/librustc/driver/session.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,9 @@ pub struct options {
136136
save_temps: bool,
137137
jit: bool,
138138
output_type: back::link::output_type,
139-
addl_lib_search_paths: ~[Path],
139+
addl_lib_search_paths: @mut ~[Path], // This is mutable for rustpkg, which
140+
// updates search paths based on the
141+
// parsed code
140142
linker: Option<~str>,
141143
linker_args: ~[~str],
142144
maybe_sysroot: Option<@Path>,
@@ -316,7 +318,7 @@ pub fn basic_options() -> @options {
316318
save_temps: false,
317319
jit: false,
318320
output_type: link::output_type_exe,
319-
addl_lib_search_paths: ~[],
321+
addl_lib_search_paths: @mut ~[],
320322
linker: None,
321323
linker_args: ~[],
322324
maybe_sysroot: None,

src/librustc/metadata/filesearch.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,18 @@ pub trait FileSearch {
3535

3636
pub fn mk_filesearch(maybe_sysroot: &Option<@Path>,
3737
target_triple: &str,
38-
addl_lib_search_paths: ~[Path])
38+
addl_lib_search_paths: @mut ~[Path])
3939
-> @FileSearch {
4040
struct FileSearchImpl {
4141
sysroot: @Path,
42-
addl_lib_search_paths: ~[Path],
42+
addl_lib_search_paths: @mut ~[Path],
4343
target_triple: ~str
4444
}
4545
impl FileSearch for FileSearchImpl {
4646
fn sysroot(&self) -> @Path { self.sysroot }
4747
fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool {
48-
debug!("filesearch: searching additional lib search paths");
48+
debug!("filesearch: searching additional lib search paths [%?]",
49+
self.addl_lib_search_paths.len());
4950
// a little weird
5051
self.addl_lib_search_paths.each(f);
5152

src/librustc/rustc.rc

+5-5
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,11 @@ pub fn version(argv0: &str) {
183183

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

193193
pub fn describe_warnings() {

src/librusti/rusti.rc

+7-6
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ fn run(repl: Repl, input: ~str) -> Repl {
121121
let options = @session::options {
122122
crate_type: session::unknown_crate,
123123
binary: binary,
124-
addl_lib_search_paths: repl.lib_search_paths.map(|p| Path(*p)),
124+
addl_lib_search_paths: @mut repl.lib_search_paths.map(|p| Path(*p)),
125125
jit: true,
126126
.. copy *session::basic_options()
127127
};
@@ -142,12 +142,13 @@ fn run(repl: Repl, input: ~str) -> Repl {
142142
binary,
143143
&wrapped);
144144

145-
let outputs = driver::build_output_filenames(&wrapped, &None, &None, sess);
145+
let outputs = driver::build_output_filenames(&wrapped, &None, &None, [], sess);
146146
debug!("calling compile_upto");
147147

148148
let crate = driver::parse_input(sess, copy cfg, &wrapped);
149-
driver::compile_rest(sess, cfg, driver::cu_everything,
150-
Some(outputs), Some(crate));
149+
driver::compile_rest(sess, cfg, driver::compile_upto { from: driver::cu_parse,
150+
to: driver::cu_everything },
151+
Some(outputs), Some(crate));
151152

152153
let mut opt = None;
153154

@@ -188,15 +189,15 @@ fn compile_crate(src_filename: ~str, binary: ~str) -> Option<bool> {
188189
let binary = @copy binary;
189190
let options = @session::options {
190191
binary: binary,
191-
addl_lib_search_paths: ~[os::getcwd()],
192+
addl_lib_search_paths: @mut ~[os::getcwd()],
192193
.. copy *session::basic_options()
193194
};
194195
let input = driver::file_input(copy src_path);
195196
let sess = driver::build_session(options, diagnostic::emit);
196197
*sess.building_library = true;
197198
let cfg = driver::build_configuration(sess, binary, &input);
198199
let outputs = driver::build_output_filenames(
199-
&input, &None, &None, sess);
200+
&input, &None, &None, [], sess);
200201
// If the library already exists and is newer than the source
201202
// file, skip compilation and return None.
202203
let mut should_compile = true;

src/librustpkg/conditions.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
// Useful conditions
1212

1313
pub use core::path::Path;
14-
pub use util::PkgId;
14+
pub use package_id::PkgId;
1515

1616
condition! {
1717
bad_path: (super::Path, ~str) -> super::Path;
1818
}
1919

2020
condition! {
21-
nonexistent_package: (super::PkgId, ~str) -> ();
21+
nonexistent_package: (super::PkgId, ~str) -> super::Path;
2222
}
2323

2424
condition! {
@@ -30,5 +30,5 @@ condition! {
3030
}
3131

3232
condition! {
33-
bad_pkg_id: (super::Path, ~str) -> ::util::PkgId;
33+
bad_pkg_id: (super::Path, ~str) -> super::PkgId;
3434
}

src/librustpkg/package_id.rs

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub use package_path::{RemotePath, LocalPath, normalize, hash};
12+
use extra::semver;
13+
use core::prelude::*;
14+
use core::result;
15+
16+
/// Placeholder
17+
pub fn default_version() -> Version { ExactRevision(0.1) }
18+
19+
/// Path-fragment identifier of a package such as
20+
/// 'github.com/graydon/test'; path must be a relative
21+
/// path with >=1 component.
22+
pub struct PkgId {
23+
/// Remote path: for example, github.com/mozilla/quux-whatever
24+
remote_path: RemotePath,
25+
/// Local path: for example, /home/quux/github.com/mozilla/quux_whatever
26+
/// Note that '-' normalizes to '_' when mapping a remote path
27+
/// onto a local path
28+
/// Also, this will change when we implement #6407, though we'll still
29+
/// need to keep track of separate local and remote paths
30+
local_path: LocalPath,
31+
/// Short name. This is the local path's filestem, but we store it
32+
/// redundantly so as to not call get() everywhere (filestem() returns an
33+
/// option)
34+
short_name: ~str,
35+
version: Version
36+
}
37+
38+
pub impl PkgId {
39+
fn new(s: &str) -> PkgId {
40+
use conditions::bad_pkg_id::cond;
41+
42+
let p = Path(s);
43+
if p.is_absolute {
44+
return cond.raise((p, ~"absolute pkgid"));
45+
}
46+
if p.components.len() < 1 {
47+
return cond.raise((p, ~"0-length pkgid"));
48+
}
49+
let remote_path = RemotePath(p);
50+
let local_path = normalize(copy remote_path);
51+
let short_name = (copy local_path).filestem().expect(fmt!("Strange path! %s", s));
52+
PkgId {
53+
local_path: local_path,
54+
remote_path: remote_path,
55+
short_name: short_name,
56+
version: default_version()
57+
}
58+
}
59+
60+
fn hash(&self) -> ~str {
61+
fmt!("%s-%s-%s", self.remote_path.to_str(),
62+
hash(self.remote_path.to_str() + self.version.to_str()),
63+
self.version.to_str())
64+
}
65+
66+
fn short_name_with_version(&self) -> ~str {
67+
fmt!("%s-%s", self.short_name, self.version.to_str())
68+
}
69+
}
70+
71+
impl ToStr for PkgId {
72+
fn to_str(&self) -> ~str {
73+
// should probably use the filestem and not the whole path
74+
fmt!("%s-%s", self.local_path.to_str(), self.version.to_str())
75+
}
76+
}
77+
78+
/// A version is either an exact revision,
79+
/// or a semantic version
80+
pub enum Version {
81+
ExactRevision(float),
82+
SemVersion(semver::Version)
83+
}
84+
85+
86+
impl Ord for Version {
87+
fn lt(&self, other: &Version) -> bool {
88+
match (self, other) {
89+
(&ExactRevision(f1), &ExactRevision(f2)) => f1 < f2,
90+
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 < v2,
91+
_ => false // incomparable, really
92+
}
93+
}
94+
fn le(&self, other: &Version) -> bool {
95+
match (self, other) {
96+
(&ExactRevision(f1), &ExactRevision(f2)) => f1 <= f2,
97+
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 <= v2,
98+
_ => false // incomparable, really
99+
}
100+
}
101+
fn ge(&self, other: &Version) -> bool {
102+
match (self, other) {
103+
(&ExactRevision(f1), &ExactRevision(f2)) => f1 > f2,
104+
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 > v2,
105+
_ => false // incomparable, really
106+
}
107+
}
108+
fn gt(&self, other: &Version) -> bool {
109+
match (self, other) {
110+
(&ExactRevision(f1), &ExactRevision(f2)) => f1 >= f2,
111+
(&SemVersion(ref v1), &SemVersion(ref v2)) => v1 >= v2,
112+
_ => false // incomparable, really
113+
}
114+
}
115+
116+
}
117+
118+
impl ToStr for Version {
119+
fn to_str(&self) -> ~str {
120+
match *self {
121+
ExactRevision(ref n) => n.to_str(),
122+
SemVersion(ref v) => v.to_str()
123+
}
124+
}
125+
}
126+
127+
pub fn parse_vers(vers: ~str) -> result::Result<semver::Version, ~str> {
128+
match semver::parse(vers) {
129+
Some(vers) => result::Ok(vers),
130+
None => result::Err(~"could not parse version: invalid")
131+
}
132+
}

src/librustpkg/package_path.rs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// rustpkg utilities having to do with local and remote paths
12+
13+
use core::path::Path;
14+
use core::option::Some;
15+
use core::{hash, str};
16+
use core::rt::io::Writer;
17+
use core::hash::Streaming;
18+
19+
/// Wrappers to prevent local and remote paths from getting confused
20+
/// (These will go away after #6407)
21+
pub struct RemotePath (Path);
22+
pub struct LocalPath (Path);
23+
24+
25+
// normalize should be the only way to construct a LocalPath
26+
// (though this isn't enforced)
27+
/// Replace all occurrences of '-' in the stem part of path with '_'
28+
/// This is because we treat rust-foo-bar-quux and rust_foo_bar_quux
29+
/// as the same name
30+
pub fn normalize(p_: RemotePath) -> LocalPath {
31+
let RemotePath(p) = p_;
32+
match p.filestem() {
33+
None => LocalPath(p),
34+
Some(st) => {
35+
let replaced = str::replace(st, "-", "_");
36+
if replaced != st {
37+
LocalPath(p.with_filestem(replaced))
38+
}
39+
else {
40+
LocalPath(p)
41+
}
42+
}
43+
}
44+
}
45+
46+
pub fn write<W: Writer>(writer: &mut W, string: &str) {
47+
let buffer = str::as_bytes_slice(string);
48+
writer.write(buffer);
49+
}
50+
51+
pub fn hash(data: ~str) -> ~str {
52+
let hasher = &mut hash::default_state();
53+
write(hasher, data);
54+
hasher.result_str()
55+
}

0 commit comments

Comments
 (0)