mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
auto merge of #8176 : catamorphism/rust/rustpkg-extern-mod, r=catamorphism
r? @graydon Also, notably, make rustpkgtest depend on the rustpkg executable (otherwise, tests that shell out to rustpgk might run when rustpkg doesn't exist).
This commit is contained in:
commit
6f6dce7bbc
28
doc/rust.md
28
doc/rust.md
@ -744,7 +744,7 @@ There are several kinds of view item:
|
|||||||
##### Extern mod declarations
|
##### Extern mod declarations
|
||||||
|
|
||||||
~~~~~~~~ {.ebnf .gram}
|
~~~~~~~~ {.ebnf .gram}
|
||||||
extern_mod_decl : "extern" "mod" ident [ '(' link_attrs ')' ] ? ;
|
extern_mod_decl : "extern" "mod" ident [ '(' link_attrs ')' ] ? [ '=' string_lit ] ? ;
|
||||||
link_attrs : link_attr [ ',' link_attrs ] + ;
|
link_attrs : link_attr [ ',' link_attrs ] + ;
|
||||||
link_attr : ident '=' literal ;
|
link_attr : ident '=' literal ;
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
@ -755,13 +755,25 @@ as the `ident` provided in the `extern_mod_decl`.
|
|||||||
|
|
||||||
The external crate is resolved to a specific `soname` at compile time,
|
The external crate is resolved to a specific `soname` at compile time,
|
||||||
and a runtime linkage requirement to that `soname` is passed to the linker for
|
and a runtime linkage requirement to that `soname` is passed to the linker for
|
||||||
loading at runtime. The `soname` is resolved at compile time by scanning the
|
loading at runtime.
|
||||||
compiler's library path and matching the `link_attrs` provided in the
|
The `soname` is resolved at compile time by scanning the compiler's library path
|
||||||
`use_decl` against any `#link` attributes that were declared on the external
|
and matching the `link_attrs` provided in the `use_decl` against any `#link` attributes that
|
||||||
crate when it was compiled. If no `link_attrs` are provided, a default `name`
|
were declared on the external crate when it was compiled.
|
||||||
attribute is assumed, equal to the `ident` given in the `use_decl`.
|
If no `link_attrs` are provided,
|
||||||
|
a default `name` attribute is assumed,
|
||||||
|
equal to the `ident` given in the `use_decl`.
|
||||||
|
|
||||||
Three examples of `extern mod` declarations:
|
Optionally, an identifier in an `extern mod` declaration may be followed by an equals sign,
|
||||||
|
then a string literal denoting a relative path on the filesystem.
|
||||||
|
This path should exist in one of the directories in the Rust path,
|
||||||
|
which by default contains the `.rust` subdirectory of the current directory and each of its parents,
|
||||||
|
as well as any directories in the colon-separated (or semicolon-separated on Windows)
|
||||||
|
list of paths that is the `RUST_PATH` environment variable.
|
||||||
|
The meaning of `extern mod a = "b/c/d";`, supposing that `/a` is in the RUST_PATH,
|
||||||
|
is that the name `a` should be taken as a reference to the crate whose absolute location is
|
||||||
|
`/a/b/c/d`.
|
||||||
|
|
||||||
|
Four examples of `extern mod` declarations:
|
||||||
|
|
||||||
~~~~~~~~{.xfail-test}
|
~~~~~~~~{.xfail-test}
|
||||||
extern mod pcre (uuid = "54aba0f8-a7b1-4beb-92f1-4cf625264841");
|
extern mod pcre (uuid = "54aba0f8-a7b1-4beb-92f1-4cf625264841");
|
||||||
@ -769,6 +781,8 @@ extern mod pcre (uuid = "54aba0f8-a7b1-4beb-92f1-4cf625264841");
|
|||||||
extern mod extra; // equivalent to: extern mod extra ( name = "extra" );
|
extern mod extra; // equivalent to: extern mod extra ( name = "extra" );
|
||||||
|
|
||||||
extern mod rustextra (name = "extra"); // linking to 'extra' under another name
|
extern mod rustextra (name = "extra"); // linking to 'extra' under another name
|
||||||
|
|
||||||
|
extern mod complicated_mod = "some-file/in/the-rust/path";
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
##### Use declarations
|
##### Use declarations
|
||||||
|
@ -348,7 +348,9 @@ $(3)/stage$(1)/test/rustpkgtest-$(2)$$(X_$(2)): \
|
|||||||
$$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS) \
|
$$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS) \
|
||||||
$$(SREQ$(1)_T_$(2)_H_$(3)) \
|
$$(SREQ$(1)_T_$(2)_H_$(3)) \
|
||||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2)) \
|
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2)) \
|
||||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2))
|
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2)) \
|
||||||
|
$$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$$(X_$(2)) \
|
||||||
|
$$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(2))
|
||||||
@$$(call E, compile_and_link: $$@)
|
@$$(call E, compile_and_link: $$@)
|
||||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
|
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ use lib::llvm::llvm;
|
|||||||
use lib::llvm::ModuleRef;
|
use lib::llvm::ModuleRef;
|
||||||
use lib;
|
use lib;
|
||||||
use metadata::common::LinkMeta;
|
use metadata::common::LinkMeta;
|
||||||
use metadata::{encoder, csearch, cstore};
|
use metadata::{encoder, csearch, cstore, filesearch};
|
||||||
use middle::trans::context::CrateContext;
|
use middle::trans::context::CrateContext;
|
||||||
use middle::trans::common::gensym_name;
|
use middle::trans::common::gensym_name;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
@ -497,6 +497,7 @@ pub fn build_link_meta(sess: Session,
|
|||||||
struct ProvidedMetas {
|
struct ProvidedMetas {
|
||||||
name: Option<@str>,
|
name: Option<@str>,
|
||||||
vers: Option<@str>,
|
vers: Option<@str>,
|
||||||
|
pkg_id: Option<@str>,
|
||||||
cmh_items: ~[@ast::MetaItem]
|
cmh_items: ~[@ast::MetaItem]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,6 +505,7 @@ pub fn build_link_meta(sess: Session,
|
|||||||
ProvidedMetas {
|
ProvidedMetas {
|
||||||
let mut name = None;
|
let mut name = None;
|
||||||
let mut vers = None;
|
let mut vers = None;
|
||||||
|
let mut pkg_id = None;
|
||||||
let mut cmh_items = ~[];
|
let mut cmh_items = ~[];
|
||||||
let linkage_metas = attr::find_linkage_metas(c.attrs);
|
let linkage_metas = attr::find_linkage_metas(c.attrs);
|
||||||
attr::require_unique_names(sess.diagnostic(), linkage_metas);
|
attr::require_unique_names(sess.diagnostic(), linkage_metas);
|
||||||
@ -511,6 +513,7 @@ pub fn build_link_meta(sess: Session,
|
|||||||
match meta.name_str_pair() {
|
match meta.name_str_pair() {
|
||||||
Some((n, value)) if "name" == n => name = Some(value),
|
Some((n, value)) if "name" == n => name = Some(value),
|
||||||
Some((n, value)) if "vers" == n => vers = Some(value),
|
Some((n, value)) if "vers" == n => vers = Some(value),
|
||||||
|
Some((n, value)) if "package_id" == n => pkg_id = Some(value),
|
||||||
_ => cmh_items.push(*meta)
|
_ => cmh_items.push(*meta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,6 +521,7 @@ pub fn build_link_meta(sess: Session,
|
|||||||
ProvidedMetas {
|
ProvidedMetas {
|
||||||
name: name,
|
name: name,
|
||||||
vers: vers,
|
vers: vers,
|
||||||
|
pkg_id: pkg_id,
|
||||||
cmh_items: cmh_items
|
cmh_items: cmh_items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -525,7 +529,8 @@ pub fn build_link_meta(sess: Session,
|
|||||||
// This calculates CMH as defined above
|
// This calculates CMH as defined above
|
||||||
fn crate_meta_extras_hash(symbol_hasher: &mut hash::State,
|
fn crate_meta_extras_hash(symbol_hasher: &mut hash::State,
|
||||||
cmh_items: ~[@ast::MetaItem],
|
cmh_items: ~[@ast::MetaItem],
|
||||||
dep_hashes: ~[@str]) -> @str {
|
dep_hashes: ~[@str],
|
||||||
|
pkg_id: Option<@str>) -> @str {
|
||||||
fn len_and_str(s: &str) -> ~str {
|
fn len_and_str(s: &str) -> ~str {
|
||||||
fmt!("%u_%s", s.len(), s)
|
fmt!("%u_%s", s.len(), s)
|
||||||
}
|
}
|
||||||
@ -563,7 +568,10 @@ pub fn build_link_meta(sess: Session,
|
|||||||
write_string(symbol_hasher, len_and_str(*dh));
|
write_string(symbol_hasher, len_and_str(*dh));
|
||||||
}
|
}
|
||||||
|
|
||||||
// tjc: allocation is unfortunate; need to change std::hash
|
for p in pkg_id.iter() {
|
||||||
|
write_string(symbol_hasher, len_and_str(*p));
|
||||||
|
}
|
||||||
|
|
||||||
return truncated_hash_result(symbol_hasher).to_managed();
|
return truncated_hash_result(symbol_hasher).to_managed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -605,6 +613,7 @@ pub fn build_link_meta(sess: Session,
|
|||||||
let ProvidedMetas {
|
let ProvidedMetas {
|
||||||
name: opt_name,
|
name: opt_name,
|
||||||
vers: opt_vers,
|
vers: opt_vers,
|
||||||
|
pkg_id: opt_pkg_id,
|
||||||
cmh_items: cmh_items
|
cmh_items: cmh_items
|
||||||
} = provided_link_metas(sess, c);
|
} = provided_link_metas(sess, c);
|
||||||
let name = crate_meta_name(sess, output, opt_name);
|
let name = crate_meta_name(sess, output, opt_name);
|
||||||
@ -612,11 +621,12 @@ pub fn build_link_meta(sess: Session,
|
|||||||
let dep_hashes = cstore::get_dep_hashes(sess.cstore);
|
let dep_hashes = cstore::get_dep_hashes(sess.cstore);
|
||||||
let extras_hash =
|
let extras_hash =
|
||||||
crate_meta_extras_hash(symbol_hasher, cmh_items,
|
crate_meta_extras_hash(symbol_hasher, cmh_items,
|
||||||
dep_hashes);
|
dep_hashes, opt_pkg_id);
|
||||||
|
|
||||||
LinkMeta {
|
LinkMeta {
|
||||||
name: name,
|
name: name,
|
||||||
vers: vers,
|
vers: vers,
|
||||||
|
package_id: opt_pkg_id,
|
||||||
extras_hash: extras_hash
|
extras_hash: extras_hash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -939,6 +949,11 @@ pub fn link_args(sess: Session,
|
|||||||
args.push(~"-L" + path.to_str());
|
args.push(~"-L" + path.to_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let rustpath = filesearch::rust_path();
|
||||||
|
for path in rustpath.iter() {
|
||||||
|
args.push(~"-L" + path.to_str());
|
||||||
|
}
|
||||||
|
|
||||||
// The names of the extern libraries
|
// The names of the extern libraries
|
||||||
let used_libs = cstore::get_used_libraries(cstore);
|
let used_libs = cstore::get_used_libraries(cstore);
|
||||||
for l in used_libs.iter() { args.push(~"-l" + *l); }
|
for l in used_libs.iter() { args.push(~"-l" + *l); }
|
||||||
|
@ -14,10 +14,7 @@ use metadata::cstore;
|
|||||||
use metadata::filesearch;
|
use metadata::filesearch;
|
||||||
|
|
||||||
use std::hashmap::HashSet;
|
use std::hashmap::HashSet;
|
||||||
use std::num;
|
use std::{num, os, path, uint, util, vec};
|
||||||
use std::os;
|
|
||||||
use std::util;
|
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
fn not_win32(os: session::os) -> bool {
|
fn not_win32(os: session::os) -> bool {
|
||||||
os != session::os_win32
|
os != session::os_win32
|
||||||
@ -122,42 +119,7 @@ pub fn get_rpath_relative_to_output(os: session::os,
|
|||||||
session::os_win32 => util::unreachable()
|
session::os_win32 => util::unreachable()
|
||||||
};
|
};
|
||||||
|
|
||||||
Path(prefix).push_rel(&get_relative_to(&os::make_absolute(output),
|
Path(prefix).push_rel(&os::make_absolute(output).get_relative_to(&os::make_absolute(lib)))
|
||||||
&os::make_absolute(lib)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the relative path from one file to another
|
|
||||||
pub fn get_relative_to(abs1: &Path, abs2: &Path) -> Path {
|
|
||||||
assert!(abs1.is_absolute);
|
|
||||||
assert!(abs2.is_absolute);
|
|
||||||
let abs1 = abs1.normalize();
|
|
||||||
let abs2 = abs2.normalize();
|
|
||||||
debug!("finding relative path from %s to %s",
|
|
||||||
abs1.to_str(), abs2.to_str());
|
|
||||||
let split1: &[~str] = abs1.components;
|
|
||||||
let split2: &[~str] = abs2.components;
|
|
||||||
let len1 = split1.len();
|
|
||||||
let len2 = split2.len();
|
|
||||||
assert!(len1 > 0);
|
|
||||||
assert!(len2 > 0);
|
|
||||||
|
|
||||||
let max_common_path = num::min(len1, len2) - 1;
|
|
||||||
let mut start_idx = 0;
|
|
||||||
while start_idx < max_common_path
|
|
||||||
&& split1[start_idx] == split2[start_idx] {
|
|
||||||
start_idx += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut path = ~[];
|
|
||||||
for _ in range(start_idx, len1 - 1) { path.push(~".."); };
|
|
||||||
|
|
||||||
path.push_all(split2.slice(start_idx, len2 - 1));
|
|
||||||
|
|
||||||
return if !path.is_empty() {
|
|
||||||
Path("").push_many(path)
|
|
||||||
} else {
|
|
||||||
Path(".")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] {
|
fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] {
|
||||||
@ -208,8 +170,7 @@ mod test {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use back::rpath::{get_absolute_rpath, get_install_prefix_rpath};
|
use back::rpath::{get_absolute_rpath, get_install_prefix_rpath};
|
||||||
use back::rpath::{get_relative_to, get_rpath_relative_to_output};
|
use back::rpath::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
|
||||||
use back::rpath::{minimize_rpaths, rpaths_to_flags};
|
|
||||||
use driver::session;
|
use driver::session;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -253,78 +214,9 @@ mod test {
|
|||||||
assert_eq!(res, ~[Path("1a"), Path("2"), Path("4a"), Path("3")]);
|
assert_eq!(res, ~[Path("1a"), Path("2"), Path("4a"), Path("3")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_relative_to1() {
|
|
||||||
let p1 = Path("/usr/bin/rustc");
|
|
||||||
let p2 = Path("/usr/lib/mylib");
|
|
||||||
let res = get_relative_to(&p1, &p2);
|
|
||||||
assert_eq!(res, Path("../lib"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_relative_to2() {
|
|
||||||
let p1 = Path("/usr/bin/rustc");
|
|
||||||
let p2 = Path("/usr/bin/../lib/mylib");
|
|
||||||
let res = get_relative_to(&p1, &p2);
|
|
||||||
assert_eq!(res, Path("../lib"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_relative_to3() {
|
|
||||||
let p1 = Path("/usr/bin/whatever/rustc");
|
|
||||||
let p2 = Path("/usr/lib/whatever/mylib");
|
|
||||||
let res = get_relative_to(&p1, &p2);
|
|
||||||
assert_eq!(res, Path("../../lib/whatever"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_relative_to4() {
|
|
||||||
let p1 = Path("/usr/bin/whatever/../rustc");
|
|
||||||
let p2 = Path("/usr/lib/whatever/mylib");
|
|
||||||
let res = get_relative_to(&p1, &p2);
|
|
||||||
assert_eq!(res, Path("../lib/whatever"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_relative_to5() {
|
|
||||||
let p1 = Path("/usr/bin/whatever/../rustc");
|
|
||||||
let p2 = Path("/usr/lib/whatever/../mylib");
|
|
||||||
let res = get_relative_to(&p1, &p2);
|
|
||||||
assert_eq!(res, Path("../lib"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_relative_to6() {
|
|
||||||
let p1 = Path("/1");
|
|
||||||
let p2 = Path("/2/3");
|
|
||||||
let res = get_relative_to(&p1, &p2);
|
|
||||||
assert_eq!(res, Path("2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_relative_to7() {
|
|
||||||
let p1 = Path("/1/2");
|
|
||||||
let p2 = Path("/3");
|
|
||||||
let res = get_relative_to(&p1, &p2);
|
|
||||||
assert_eq!(res, Path(".."));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_relative_to8() {
|
|
||||||
let p1 = Path("/home/brian/Dev/rust/build/").push_rel(
|
|
||||||
&Path("stage2/lib/rustc/i686-unknown-linux-gnu/lib/librustc.so"));
|
|
||||||
let p2 = Path("/home/brian/Dev/rust/build/stage2/bin/..").push_rel(
|
|
||||||
&Path("lib/rustc/i686-unknown-linux-gnu/lib/libstd.so"));
|
|
||||||
let res = get_relative_to(&p1, &p2);
|
|
||||||
debug!("test_relative_tu8: %s vs. %s",
|
|
||||||
res.to_str(),
|
|
||||||
Path(".").to_str());
|
|
||||||
assert_eq!(res, Path("."));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
#[cfg(target_os = "andorid")]
|
#[cfg(target_os = "android")]
|
||||||
fn test_rpath_relative() {
|
fn test_rpath_relative() {
|
||||||
let o = session::os_linux;
|
let o = session::os_linux;
|
||||||
let res = get_rpath_relative_to_output(o,
|
let res = get_rpath_relative_to_output(o,
|
||||||
@ -344,7 +236,6 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
fn test_rpath_relative() {
|
fn test_rpath_relative() {
|
||||||
// this is why refinements would be nice
|
|
||||||
let o = session::os_macos;
|
let o = session::os_macos;
|
||||||
let res = get_rpath_relative_to_output(o,
|
let res = get_rpath_relative_to_output(o,
|
||||||
&Path("bin/rustc"),
|
&Path("bin/rustc"),
|
||||||
|
@ -47,7 +47,7 @@ fn inject_libstd_ref(sess: Session, crate: &ast::Crate) -> @ast::Crate {
|
|||||||
let n1 = sess.next_node_id();
|
let n1 = sess.next_node_id();
|
||||||
let vi1 = ast::view_item {
|
let vi1 = ast::view_item {
|
||||||
node: ast::view_item_extern_mod(
|
node: ast::view_item_extern_mod(
|
||||||
sess.ident_of("std"), ~[], n1),
|
sess.ident_of("std"), None, ~[], n1),
|
||||||
attrs: ~[
|
attrs: ~[
|
||||||
attr::mk_attr(
|
attr::mk_attr(
|
||||||
attr::mk_name_value_item_str(@"vers", STD_VERSION.to_managed()))
|
attr::mk_name_value_item_str(@"vers", STD_VERSION.to_managed()))
|
||||||
|
@ -282,7 +282,7 @@ fn mk_std(cx: &TestCtxt) -> ast::view_item {
|
|||||||
cx.sess.next_node_id()))])
|
cx.sess.next_node_id()))])
|
||||||
} else {
|
} else {
|
||||||
let mi = attr::mk_name_value_item_str(@"vers", @"0.8-pre");
|
let mi = attr::mk_name_value_item_str(@"vers", @"0.8-pre");
|
||||||
ast::view_item_extern_mod(id_extra, ~[mi], cx.sess.next_node_id())
|
ast::view_item_extern_mod(id_extra, None, ~[mi], cx.sess.next_node_id())
|
||||||
};
|
};
|
||||||
ast::view_item {
|
ast::view_item {
|
||||||
node: vi,
|
node: vi,
|
||||||
|
@ -185,5 +185,7 @@ pub static tag_item_impl_vtables: uint = 0x82;
|
|||||||
pub struct LinkMeta {
|
pub struct LinkMeta {
|
||||||
name: @str,
|
name: @str,
|
||||||
vers: @str,
|
vers: @str,
|
||||||
|
// Optional package ID
|
||||||
|
package_id: Option<@str>, // non-None if this was a URL-like package ID
|
||||||
extras_hash: @str
|
extras_hash: @str
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ use metadata::loader;
|
|||||||
|
|
||||||
use std::hashmap::HashMap;
|
use std::hashmap::HashMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use std::vec;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr::AttrMetaMethods;
|
||||||
use syntax::codemap::{span, dummy_sp};
|
use syntax::codemap::{span, dummy_sp};
|
||||||
@ -137,18 +138,33 @@ fn visit_crate(e: &Env, c: &ast::Crate) {
|
|||||||
|
|
||||||
fn visit_view_item(e: @mut Env, i: &ast::view_item) {
|
fn visit_view_item(e: @mut Env, i: &ast::view_item) {
|
||||||
match i.node {
|
match i.node {
|
||||||
ast::view_item_extern_mod(ident, ref meta_items, id) => {
|
ast::view_item_extern_mod(ident, path_opt, ref meta_items, id) => {
|
||||||
debug!("resolving extern mod stmt. ident: %?, meta: %?",
|
let ident = token::ident_to_str(&ident);
|
||||||
ident, *meta_items);
|
let meta_items = match path_opt {
|
||||||
let cnum = resolve_crate(e,
|
None => meta_items.clone(),
|
||||||
ident,
|
Some(p) => {
|
||||||
(*meta_items).clone(),
|
let p_path = Path(p);
|
||||||
@"",
|
match p_path.filestem() {
|
||||||
i.span);
|
Some(s) =>
|
||||||
cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum);
|
vec::append(
|
||||||
|
~[attr::mk_name_value_item_str(@"package_id", p),
|
||||||
|
attr::mk_name_value_item_str(@"name", s.to_managed())],
|
||||||
|
*meta_items),
|
||||||
|
None => e.diag.span_bug(i.span, "Bad package path in `extern mod` item")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
debug!("resolving extern mod stmt. ident: %?, meta: %?",
|
||||||
|
ident, meta_items);
|
||||||
|
let cnum = resolve_crate(e,
|
||||||
|
ident,
|
||||||
|
meta_items,
|
||||||
|
@"",
|
||||||
|
i.span);
|
||||||
|
cstore::add_extern_mod_stmt_cnum(e.cstore, id, cnum);
|
||||||
}
|
}
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item(e: &Env, i: @ast::item) {
|
fn visit_item(e: &Env, i: @ast::item) {
|
||||||
@ -233,12 +249,12 @@ fn existing_match(e: &Env, metas: &[@ast::MetaItem], hash: &str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_crate(e: @mut Env,
|
fn resolve_crate(e: @mut Env,
|
||||||
ident: ast::ident,
|
ident: @str,
|
||||||
metas: ~[@ast::MetaItem],
|
metas: ~[@ast::MetaItem],
|
||||||
hash: @str,
|
hash: @str,
|
||||||
span: span)
|
span: span)
|
||||||
-> ast::CrateNum {
|
-> ast::CrateNum {
|
||||||
let metas = metas_with_ident(token::ident_to_str(&ident), metas);
|
let metas = metas_with_ident(ident, metas);
|
||||||
|
|
||||||
match existing_match(e, metas, hash) {
|
match existing_match(e, metas, hash) {
|
||||||
None => {
|
None => {
|
||||||
@ -279,7 +295,7 @@ fn resolve_crate(e: @mut Env,
|
|||||||
match attr::last_meta_item_value_str_by_name(load_ctxt.metas,
|
match attr::last_meta_item_value_str_by_name(load_ctxt.metas,
|
||||||
"name") {
|
"name") {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => token::ident_to_str(&ident),
|
None => ident
|
||||||
};
|
};
|
||||||
let cmeta = @cstore::crate_metadata {
|
let cmeta = @cstore::crate_metadata {
|
||||||
name: cname,
|
name: cname,
|
||||||
@ -308,7 +324,6 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map {
|
|||||||
let r = decoder::get_crate_deps(cdata);
|
let r = decoder::get_crate_deps(cdata);
|
||||||
for dep in r.iter() {
|
for dep in r.iter() {
|
||||||
let extrn_cnum = dep.cnum;
|
let extrn_cnum = dep.cnum;
|
||||||
let cname = dep.name;
|
|
||||||
let cname_str = token::ident_to_str(&dep.name);
|
let cname_str = token::ident_to_str(&dep.name);
|
||||||
let cmetas = metas_with(dep.vers, @"vers", ~[]);
|
let cmetas = metas_with(dep.vers, @"vers", ~[]);
|
||||||
debug!("resolving dep crate %s ver: %s hash: %s",
|
debug!("resolving dep crate %s ver: %s hash: %s",
|
||||||
@ -327,7 +342,7 @@ fn resolve_crate_deps(e: @mut Env, cdata: @~[u8]) -> cstore::cnum_map {
|
|||||||
// FIXME (#2404): Need better error reporting than just a bogus
|
// FIXME (#2404): Need better error reporting than just a bogus
|
||||||
// span.
|
// span.
|
||||||
let fake_span = dummy_sp();
|
let fake_span = dummy_sp();
|
||||||
let local_cnum = resolve_crate(e, cname, cmetas, dep.hash,
|
let local_cnum = resolve_crate(e, cname_str, cmetas, dep.hash,
|
||||||
fake_span);
|
fake_span);
|
||||||
cnum_map.insert(extrn_cnum, local_cnum);
|
cnum_map.insert(extrn_cnum, local_cnum);
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,15 @@
|
|||||||
|
|
||||||
use std::option;
|
use std::option;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::result;
|
use std::{result, str};
|
||||||
|
use std::hashmap::HashSet;
|
||||||
|
|
||||||
// A module for searching for libraries
|
// A module for searching for libraries
|
||||||
// FIXME (#2658): I'm not happy how this module turned out. Should
|
// FIXME (#2658): I'm not happy how this module turned out. Should
|
||||||
// probably just be folded into cstore.
|
// probably just be folded into cstore.
|
||||||
|
|
||||||
|
/// Functions with type `pick` take a parent directory as well as
|
||||||
|
/// a file found in that directory.
|
||||||
pub type pick<'self, T> = &'self fn(path: &Path) -> Option<T>;
|
pub type pick<'self, T> = &'self fn(path: &Path) -> Option<T>;
|
||||||
|
|
||||||
pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
|
pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
|
||||||
@ -46,28 +49,33 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>,
|
|||||||
impl FileSearch for FileSearchImpl {
|
impl FileSearch for FileSearchImpl {
|
||||||
fn sysroot(&self) -> @Path { self.sysroot }
|
fn sysroot(&self) -> @Path { self.sysroot }
|
||||||
fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool {
|
fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool {
|
||||||
|
let mut visited_dirs = HashSet::new();
|
||||||
|
|
||||||
debug!("filesearch: searching additional lib search paths [%?]",
|
debug!("filesearch: searching additional lib search paths [%?]",
|
||||||
self.addl_lib_search_paths.len());
|
self.addl_lib_search_paths.len());
|
||||||
// a little weird
|
for path in self.addl_lib_search_paths.iter() {
|
||||||
self.addl_lib_search_paths.iter().advance(|path| f(path));
|
f(path);
|
||||||
|
visited_dirs.insert(path.to_str());
|
||||||
|
}
|
||||||
|
|
||||||
debug!("filesearch: searching target lib path");
|
debug!("filesearch: searching target lib path");
|
||||||
if !f(&make_target_lib_path(self.sysroot,
|
let tlib_path = make_target_lib_path(self.sysroot,
|
||||||
self.target_triple)) {
|
self.target_triple);
|
||||||
return false;
|
if !visited_dirs.contains(&tlib_path.to_str()) {
|
||||||
}
|
if !f(&tlib_path) {
|
||||||
debug!("filesearch: searching rustpkg lib path nearest");
|
return false;
|
||||||
if match get_rustpkg_lib_path_nearest() {
|
|
||||||
result::Ok(ref p) => f(p),
|
|
||||||
result::Err(_) => true
|
|
||||||
} {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
debug!("filesearch: searching rustpkg lib path");
|
}
|
||||||
match get_rustpkg_lib_path() {
|
visited_dirs.insert(tlib_path.to_str());
|
||||||
result::Ok(ref p) => f(p),
|
// Try RUST_PATH
|
||||||
result::Err(_) => true
|
let rustpath = rust_path();
|
||||||
}
|
for path in rustpath.iter() {
|
||||||
|
if !visited_dirs.contains(&path.push("lib").to_str()) {
|
||||||
|
f(&path.push("lib"));
|
||||||
|
visited_dirs.insert(path.push("lib").to_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
}
|
}
|
||||||
fn get_target_lib_path(&self) -> Path {
|
fn get_target_lib_path(&self) -> Path {
|
||||||
make_target_lib_path(self.sysroot, self.target_triple)
|
make_target_lib_path(self.sysroot, self.target_triple)
|
||||||
@ -94,12 +102,15 @@ pub fn search<T>(filesearch: @FileSearch, pick: pick<T>) -> Option<T> {
|
|||||||
for path in r.iter() {
|
for path in r.iter() {
|
||||||
debug!("testing %s", path.to_str());
|
debug!("testing %s", path.to_str());
|
||||||
let maybe_picked = pick(path);
|
let maybe_picked = pick(path);
|
||||||
if maybe_picked.is_some() {
|
match maybe_picked {
|
||||||
debug!("picked %s", path.to_str());
|
Some(_) => {
|
||||||
rslt = maybe_picked;
|
debug!("picked %s", path.to_str());
|
||||||
break;
|
rslt = maybe_picked;
|
||||||
} else {
|
break;
|
||||||
debug!("rejected %s", path.to_str());
|
}
|
||||||
|
None => {
|
||||||
|
debug!("rejected %s", path.to_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rslt.is_none()
|
rslt.is_none()
|
||||||
@ -132,55 +143,59 @@ fn get_sysroot(maybe_sysroot: &Option<@Path>) -> @Path {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rustpkg_sysroot() -> Result<Path, ~str> {
|
#[cfg(windows)]
|
||||||
result::Ok(get_or_default_sysroot().push_many([libdir(), ~"rustpkg"]))
|
static PATH_ENTRY_SEPARATOR: &'static str = ";";
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
static PATH_ENTRY_SEPARATOR: &'static str = ":";
|
||||||
|
|
||||||
|
/// Returns RUST_PATH as a string, without default paths added
|
||||||
|
pub fn get_rust_path() -> Option<~str> {
|
||||||
|
os::getenv("RUST_PATH")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rustpkg_root() -> Result<Path, ~str> {
|
/// Returns the value of RUST_PATH, as a list
|
||||||
match os::getenv("RUSTPKG_ROOT") {
|
/// of Paths. Includes default entries for, if they exist:
|
||||||
Some(ref _p) => result::Ok(Path((*_p))),
|
/// $HOME/.rust
|
||||||
None => match os::homedir() {
|
/// DIR/.rust for any DIR that's the current working directory
|
||||||
Some(ref _q) => result::Ok((*_q).push(".rustpkg")),
|
/// or an ancestor of it
|
||||||
None => result::Err(~"no RUSTPKG_ROOT or home directory")
|
pub fn rust_path() -> ~[Path] {
|
||||||
|
let mut env_rust_path: ~[Path] = match get_rust_path() {
|
||||||
|
Some(env_path) => {
|
||||||
|
let env_path_components: ~[&str] =
|
||||||
|
env_path.split_str_iter(PATH_ENTRY_SEPARATOR).collect();
|
||||||
|
env_path_components.map(|&s| Path(s))
|
||||||
|
}
|
||||||
|
None => ~[]
|
||||||
|
};
|
||||||
|
let cwd = os::getcwd();
|
||||||
|
// now add in default entries
|
||||||
|
let cwd_dot_rust = cwd.push(".rust");
|
||||||
|
if !env_rust_path.contains(&cwd_dot_rust) {
|
||||||
|
env_rust_path.push(cwd_dot_rust);
|
||||||
|
}
|
||||||
|
if !env_rust_path.contains(&cwd) {
|
||||||
|
env_rust_path.push(cwd.clone());
|
||||||
|
}
|
||||||
|
do cwd.each_parent() |p| {
|
||||||
|
if !env_rust_path.contains(&p.push(".rust")) {
|
||||||
|
push_if_exists(&mut env_rust_path, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
let h = os::homedir();
|
||||||
|
for h in h.iter() {
|
||||||
pub fn get_rustpkg_root_nearest() -> Result<Path, ~str> {
|
if !env_rust_path.contains(&h.push(".rust")) {
|
||||||
do get_rustpkg_root().chain |p| {
|
push_if_exists(&mut env_rust_path, h);
|
||||||
let cwd = os::getcwd();
|
|
||||||
let cwd_rustpkg = cwd.push(".rustpkg");
|
|
||||||
let rustpkg_is_non_root_file =
|
|
||||||
!os::path_is_dir(&cwd_rustpkg) && cwd_rustpkg != p;
|
|
||||||
let mut par_rustpkg = cwd.pop().push(".rustpkg");
|
|
||||||
let mut rslt = result::Ok(cwd_rustpkg);
|
|
||||||
|
|
||||||
if rustpkg_is_non_root_file {
|
|
||||||
while par_rustpkg != p {
|
|
||||||
if os::path_is_dir(&par_rustpkg) {
|
|
||||||
rslt = result::Ok(par_rustpkg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if par_rustpkg.components.len() == 1 {
|
|
||||||
// We just checked /.rustpkg, stop now.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
par_rustpkg = par_rustpkg.pop().pop().push(".rustpkg");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
rslt
|
|
||||||
}
|
}
|
||||||
|
env_rust_path
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_rustpkg_lib_path() -> Result<Path, ~str> {
|
|
||||||
do get_rustpkg_root().chain |p| {
|
|
||||||
result::Ok(p.push(libdir()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_rustpkg_lib_path_nearest() -> Result<Path, ~str> {
|
/// Adds p/.rust into vec, only if it exists
|
||||||
do get_rustpkg_root_nearest().chain |p| {
|
fn push_if_exists(vec: &mut ~[Path], p: &Path) {
|
||||||
result::Ok(p.push(libdir()))
|
let maybe_dir = p.push(".rust");
|
||||||
|
if os::path_exists(&maybe_dir) {
|
||||||
|
vec.push(maybe_dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ use metadata::filesearch::FileSearch;
|
|||||||
use metadata::filesearch;
|
use metadata::filesearch;
|
||||||
use syntax::codemap::span;
|
use syntax::codemap::span;
|
||||||
use syntax::diagnostic::span_handler;
|
use syntax::diagnostic::span_handler;
|
||||||
use syntax::parse::token;
|
|
||||||
use syntax::parse::token::ident_interner;
|
use syntax::parse::token::ident_interner;
|
||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
use syntax::{ast, attr};
|
use syntax::{ast, attr};
|
||||||
@ -46,7 +45,7 @@ pub struct Context {
|
|||||||
diag: @span_handler,
|
diag: @span_handler,
|
||||||
filesearch: @FileSearch,
|
filesearch: @FileSearch,
|
||||||
span: span,
|
span: span,
|
||||||
ident: ast::ident,
|
ident: @str,
|
||||||
metas: ~[@ast::MetaItem],
|
metas: ~[@ast::MetaItem],
|
||||||
hash: @str,
|
hash: @str,
|
||||||
os: os,
|
os: os,
|
||||||
@ -60,7 +59,7 @@ pub fn load_library_crate(cx: &Context) -> (~str, @~[u8]) {
|
|||||||
None => {
|
None => {
|
||||||
cx.diag.span_fatal(cx.span,
|
cx.diag.span_fatal(cx.span,
|
||||||
fmt!("can't find crate for `%s`",
|
fmt!("can't find crate for `%s`",
|
||||||
token::ident_to_str(&cx.ident)));
|
cx.ident));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,37 +88,38 @@ fn find_library_crate_aux(
|
|||||||
filesearch: @filesearch::FileSearch
|
filesearch: @filesearch::FileSearch
|
||||||
) -> Option<(~str, @~[u8])> {
|
) -> Option<(~str, @~[u8])> {
|
||||||
let crate_name = crate_name_from_metas(cx.metas);
|
let crate_name = crate_name_from_metas(cx.metas);
|
||||||
let prefix = prefix + crate_name + "-";
|
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
|
||||||
|
let prefix = fmt!("%s%s-", prefix, crate_name);
|
||||||
let mut matches = ~[];
|
let mut matches = ~[];
|
||||||
filesearch::search(filesearch, |path| -> Option<()> {
|
filesearch::search(filesearch, |path| -> Option<()> {
|
||||||
debug!("inspecting file %s", path.to_str());
|
let path_str = path.filename();
|
||||||
match path.filename() {
|
match path_str {
|
||||||
Some(ref f) if f.starts_with(prefix) && f.ends_with(suffix) => {
|
None => None,
|
||||||
debug!("%s is a candidate", path.to_str());
|
Some(path_str) =>
|
||||||
match get_metadata_section(cx.os, path) {
|
if path_str.starts_with(prefix) && path_str.ends_with(suffix) {
|
||||||
Some(cvec) =>
|
debug!("%s is a candidate", path.to_str());
|
||||||
if !crate_matches(cvec, cx.metas, cx.hash) {
|
match get_metadata_section(cx.os, path) {
|
||||||
debug!("skipping %s, metadata doesn't match",
|
Some(cvec) =>
|
||||||
path.to_str());
|
if !crate_matches(cvec, cx.metas, cx.hash) {
|
||||||
None
|
debug!("skipping %s, metadata doesn't match",
|
||||||
} else {
|
path.to_str());
|
||||||
debug!("found %s with matching metadata", path.to_str());
|
None
|
||||||
matches.push((path.to_str(), cvec));
|
} else {
|
||||||
None
|
debug!("found %s with matching metadata", path.to_str());
|
||||||
},
|
matches.push((path.to_str(), cvec));
|
||||||
_ => {
|
None
|
||||||
debug!("could not load metadata for %s", path.to_str());
|
},
|
||||||
None
|
_ => {
|
||||||
}
|
debug!("could not load metadata for %s", path.to_str());
|
||||||
}
|
None
|
||||||
}
|
}
|
||||||
_ => {
|
}
|
||||||
debug!("skipping %s, doesn't look like %s*%s", path.to_str(),
|
}
|
||||||
prefix, suffix);
|
else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
match matches.len() {
|
match matches.len() {
|
||||||
0 => None,
|
0 => None,
|
||||||
@ -137,8 +137,8 @@ fn find_library_crate_aux(
|
|||||||
}
|
}
|
||||||
cx.diag.handler().abort_if_errors();
|
cx.diag.handler().abort_if_errors();
|
||||||
None
|
None
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn crate_name_from_metas(metas: &[@ast::MetaItem]) -> @str {
|
pub fn crate_name_from_metas(metas: &[@ast::MetaItem]) -> @str {
|
||||||
@ -151,6 +151,16 @@ pub fn crate_name_from_metas(metas: &[@ast::MetaItem]) -> @str {
|
|||||||
fail!("expected to find the crate name")
|
fail!("expected to find the crate name")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn package_id_from_metas(metas: &[@ast::MetaItem]) -> Option<@str> {
|
||||||
|
for m in metas.iter() {
|
||||||
|
match m.name_str_pair() {
|
||||||
|
Some((name, s)) if "package_id" == name => { return Some(s); }
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn note_linkage_attrs(intr: @ident_interner,
|
pub fn note_linkage_attrs(intr: @ident_interner,
|
||||||
diag: @span_handler,
|
diag: @span_handler,
|
||||||
attrs: ~[ast::Attribute]) {
|
attrs: ~[ast::Attribute]) {
|
||||||
@ -175,6 +185,8 @@ fn crate_matches(crate_data: @~[u8],
|
|||||||
pub fn metadata_matches(extern_metas: &[@ast::MetaItem],
|
pub fn metadata_matches(extern_metas: &[@ast::MetaItem],
|
||||||
local_metas: &[@ast::MetaItem]) -> bool {
|
local_metas: &[@ast::MetaItem]) -> bool {
|
||||||
|
|
||||||
|
// extern_metas: metas we read from the crate
|
||||||
|
// local_metas: metas we're looking for
|
||||||
debug!("matching %u metadata requirements against %u items",
|
debug!("matching %u metadata requirements against %u items",
|
||||||
local_metas.len(), extern_metas.len());
|
local_metas.len(), extern_metas.len());
|
||||||
|
|
||||||
|
@ -1487,9 +1487,10 @@ impl Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view_item_extern_mod(name, _, node_id) => {
|
view_item_extern_mod(name, _, _, node_id) => {
|
||||||
|
// n.b. we don't need to look at the path option here, because cstore already did
|
||||||
match find_extern_mod_stmt_cnum(self.session.cstore,
|
match find_extern_mod_stmt_cnum(self.session.cstore,
|
||||||
node_id) {
|
node_id) {
|
||||||
Some(crate_id) => {
|
Some(crate_id) => {
|
||||||
let def_id = def_id { crate: crate_id, node: 0 };
|
let def_id = def_id { crate: crate_id, node: 0 };
|
||||||
let parent_link = ModuleParentLink
|
let parent_link = ModuleParentLink
|
||||||
|
@ -23,33 +23,30 @@ fn default_ctxt(p: @Path) -> Ctx {
|
|||||||
Ctx { sysroot_opt: Some(p), json: false, dep_cache: @mut HashMap::new() }
|
Ctx { sysroot_opt: Some(p), json: false, dep_cache: @mut HashMap::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_lib(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Version,
|
pub fn build_lib(sysroot: @Path, root: Path, name: ~str, version: Version,
|
||||||
lib: Path) {
|
lib: Path) {
|
||||||
|
|
||||||
let pkg_src = PkgSrc {
|
let pkg_src = PkgSrc {
|
||||||
root: root,
|
root: root,
|
||||||
dst_dir: dest.clone(),
|
id: PkgId{ version: version, ..PkgId::new(name)},
|
||||||
id: PkgId{ version: version, ..PkgId::new(name, &dest.pop())},
|
|
||||||
libs: ~[mk_crate(lib)],
|
libs: ~[mk_crate(lib)],
|
||||||
mains: ~[],
|
mains: ~[],
|
||||||
tests: ~[],
|
tests: ~[],
|
||||||
benchs: ~[]
|
benchs: ~[]
|
||||||
};
|
};
|
||||||
pkg_src.build(&default_ctxt(sysroot), pkg_src.dst_dir, ~[]);
|
pkg_src.build(&default_ctxt(sysroot), ~[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_exe(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Version,
|
pub fn build_exe(sysroot: @Path, root: Path, name: ~str, version: Version, main: Path) {
|
||||||
main: Path) {
|
|
||||||
let pkg_src = PkgSrc {
|
let pkg_src = PkgSrc {
|
||||||
root: root,
|
root: root,
|
||||||
dst_dir: dest.clone(),
|
id: PkgId{ version: version, ..PkgId::new(name)},
|
||||||
id: PkgId{ version: version, ..PkgId::new(name, &dest.pop())},
|
|
||||||
libs: ~[],
|
libs: ~[],
|
||||||
mains: ~[mk_crate(main)],
|
mains: ~[mk_crate(main)],
|
||||||
tests: ~[],
|
tests: ~[],
|
||||||
benchs: ~[]
|
benchs: ~[]
|
||||||
};
|
};
|
||||||
pkg_src.build(&default_ctxt(sysroot), pkg_src.dst_dir, ~[]);
|
pkg_src.build(&default_ctxt(sysroot), ~[]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,12 +59,9 @@ pub fn install_lib(sysroot: @Path,
|
|||||||
debug!("sysroot = %s", sysroot.to_str());
|
debug!("sysroot = %s", sysroot.to_str());
|
||||||
debug!("workspace = %s", workspace.to_str());
|
debug!("workspace = %s", workspace.to_str());
|
||||||
// make a PkgSrc
|
// make a PkgSrc
|
||||||
let pkg_id = PkgId{ version: version, ..PkgId::new(name, &workspace)};
|
let pkg_id = PkgId{ version: version, ..PkgId::new(name)};
|
||||||
let build_dir = workspace.push("build");
|
|
||||||
let dst_dir = build_dir.push_rel(&*pkg_id.local_path);
|
|
||||||
let pkg_src = PkgSrc {
|
let pkg_src = PkgSrc {
|
||||||
root: workspace.clone(),
|
root: workspace.clone(),
|
||||||
dst_dir: dst_dir.clone(),
|
|
||||||
id: pkg_id.clone(),
|
id: pkg_id.clone(),
|
||||||
libs: ~[mk_crate(lib_path)],
|
libs: ~[mk_crate(lib_path)],
|
||||||
mains: ~[],
|
mains: ~[],
|
||||||
@ -75,13 +69,13 @@ pub fn install_lib(sysroot: @Path,
|
|||||||
benchs: ~[]
|
benchs: ~[]
|
||||||
};
|
};
|
||||||
let cx = default_ctxt(sysroot);
|
let cx = default_ctxt(sysroot);
|
||||||
pkg_src.build(&cx, dst_dir, ~[]);
|
pkg_src.build(&cx, ~[]);
|
||||||
cx.install_no_build(&workspace, &pkg_id);
|
cx.install_no_build(&workspace, &pkg_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install_exe(sysroot: @Path, workspace: Path, name: ~str, version: Version) {
|
pub fn install_exe(sysroot: @Path, workspace: Path, name: ~str, version: Version) {
|
||||||
default_ctxt(sysroot).install(&workspace, &PkgId{ version: version,
|
default_ctxt(sysroot).install(&workspace, &PkgId{ version: version,
|
||||||
..PkgId::new(name, &workspace)});
|
..PkgId::new(name)});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
|
|
||||||
use std::hashmap::HashMap;
|
use std::hashmap::HashMap;
|
||||||
|
use std::os;
|
||||||
|
|
||||||
pub struct Ctx {
|
pub struct Ctx {
|
||||||
// Sysroot -- if this is None, uses rustc filesearch's
|
// Sysroot -- if this is None, uses rustc filesearch's
|
||||||
@ -23,3 +24,26 @@ pub struct Ctx {
|
|||||||
// though I'm not sure why the value is a bool
|
// though I'm not sure why the value is a bool
|
||||||
dep_cache: @mut HashMap<~str, bool>,
|
dep_cache: @mut HashMap<~str, bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Ctx {
|
||||||
|
/// Debugging
|
||||||
|
pub fn sysroot_opt_str(&self) -> ~str {
|
||||||
|
match self.sysroot_opt {
|
||||||
|
None => ~"[none]",
|
||||||
|
Some(p) => p.to_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We assume that if ../../rustc exists, then we're running
|
||||||
|
/// rustpkg from a Rust target directory. This is part of a
|
||||||
|
/// kludgy hack used to adjust the sysroot.
|
||||||
|
pub fn in_target(sysroot_opt: Option<@Path>) -> bool {
|
||||||
|
match sysroot_opt {
|
||||||
|
None => false,
|
||||||
|
Some(p) => {
|
||||||
|
debug!("Checking whether %s is in target", p.to_str());
|
||||||
|
os::path_is_dir(&p.pop().pop().push("rustc"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
// Listing installed packages
|
// Listing installed packages
|
||||||
|
|
||||||
|
use rustc::metadata::filesearch::rust_path;
|
||||||
use path_util::*;
|
use path_util::*;
|
||||||
use std::os;
|
use std::os;
|
||||||
|
|
||||||
@ -20,21 +21,46 @@ pub fn list_installed_packages(f: &fn(&PkgId) -> bool) -> bool {
|
|||||||
for exec in binfiles.iter() {
|
for exec in binfiles.iter() {
|
||||||
let exec_path = Path(*exec).filestem();
|
let exec_path = Path(*exec).filestem();
|
||||||
do exec_path.iter().advance |s| {
|
do exec_path.iter().advance |s| {
|
||||||
f(&PkgId::new(*s, p))
|
f(&PkgId::new(*s))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let libfiles = os::list_dir(&p.push("lib"));
|
let libfiles = os::list_dir(&p.push("lib"));
|
||||||
for lib in libfiles.iter() {
|
for lib in libfiles.iter() {
|
||||||
debug!("Full name: %s", *lib);
|
let lib = Path(*lib);
|
||||||
let lib_path = Path(*lib).filestem();
|
debug!("Full name: %s", lib.to_str());
|
||||||
do lib_path.iter().advance |s| {
|
match has_library(&lib) {
|
||||||
f(&PkgId::new(*s, p))
|
Some(basename) => {
|
||||||
};
|
debug!("parent = %s, child = %s",
|
||||||
}
|
p.push("lib").to_str(), lib.to_str());
|
||||||
|
let rel_p = p.push("lib/").get_relative_to(&lib);
|
||||||
|
debug!("Rel: %s", rel_p.to_str());
|
||||||
|
let rel_path = rel_p.push(basename).to_str();
|
||||||
|
debug!("Rel name: %s", rel_path);
|
||||||
|
f(&PkgId::new(rel_path));
|
||||||
|
}
|
||||||
|
None => ()
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_library(p: &Path) -> Option<~str> {
|
||||||
|
let files = os::list_dir(p);
|
||||||
|
for q in files.iter() {
|
||||||
|
let as_path = Path(*q);
|
||||||
|
if as_path.filetype() == Some(os::consts::DLL_SUFFIX.to_owned()) {
|
||||||
|
let stuff : ~str = as_path.filestem().expect("has_library: weird path");
|
||||||
|
let mut stuff2 = stuff.split_str_iter(&"-");
|
||||||
|
let stuff3: ~[&str] = stuff2.collect();
|
||||||
|
// argh
|
||||||
|
let chars_to_drop = os::consts::DLL_PREFIX.len();
|
||||||
|
return Some(stuff3[0].slice(chars_to_drop, stuff3[0].len()).to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn package_is_installed(p: &PkgId) -> bool {
|
pub fn package_is_installed(p: &PkgId) -> bool {
|
||||||
let mut is_installed = false;
|
let mut is_installed = false;
|
||||||
do list_installed_packages() |installed| {
|
do list_installed_packages() |installed| {
|
||||||
@ -44,4 +70,4 @@ pub fn package_is_installed(p: &PkgId) -> bool {
|
|||||||
false
|
false
|
||||||
};
|
};
|
||||||
is_installed
|
is_installed
|
||||||
}
|
}
|
||||||
|
@ -8,33 +8,37 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
pub use package_path::{RemotePath, LocalPath, normalize, hash};
|
|
||||||
use version::{try_getting_version, try_getting_local_version,
|
use version::{try_getting_version, try_getting_local_version,
|
||||||
Version, NoVersion, split_version};
|
Version, NoVersion, split_version};
|
||||||
|
use std::rt::io::Writer;
|
||||||
|
use std::hash::Streaming;
|
||||||
|
use std::hash;
|
||||||
|
|
||||||
/// Path-fragment identifier of a package such as
|
/// Path-fragment identifier of a package such as
|
||||||
/// 'github.com/graydon/test'; path must be a relative
|
/// 'github.com/graydon/test'; path must be a relative
|
||||||
/// path with >=1 component.
|
/// path with >=1 component.
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct PkgId {
|
pub struct PkgId {
|
||||||
/// Remote path: for example, github.com/mozilla/quux-whatever
|
/// This is a path, on the local filesystem, referring to where the
|
||||||
remote_path: RemotePath,
|
/// files for this package live. For example:
|
||||||
/// Local path: for example, /home/quux/github.com/mozilla/quux_whatever
|
/// github.com/mozilla/quux-whatever (it's assumed that if we're
|
||||||
/// Note that '-' normalizes to '_' when mapping a remote path
|
/// working with a package ID of this form, rustpkg has already cloned
|
||||||
/// onto a local path
|
/// the sources into a local directory in the RUST_PATH).
|
||||||
/// Also, this will change when we implement #6407, though we'll still
|
path: Path,
|
||||||
/// need to keep track of separate local and remote paths
|
/// Short name. This is the path's filestem, but we store it
|
||||||
local_path: LocalPath,
|
|
||||||
/// Short name. This is the local path's filestem, but we store it
|
|
||||||
/// redundantly so as to not call get() everywhere (filestem() returns an
|
/// redundantly so as to not call get() everywhere (filestem() returns an
|
||||||
/// option)
|
/// option)
|
||||||
|
/// The short name does not need to be a valid Rust identifier.
|
||||||
|
/// Users can write: `extern mod foo = "...";` to get around the issue
|
||||||
|
/// of package IDs whose short names aren't valid Rust identifiers.
|
||||||
short_name: ~str,
|
short_name: ~str,
|
||||||
|
/// The requested package version.
|
||||||
version: Version
|
version: Version
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for PkgId {
|
impl Eq for PkgId {
|
||||||
fn eq(&self, p: &PkgId) -> bool {
|
fn eq(&self, p: &PkgId) -> bool {
|
||||||
*p.local_path == *self.local_path && p.version == self.version
|
p.path == self.path && p.version == self.version
|
||||||
}
|
}
|
||||||
fn ne(&self, p: &PkgId) -> bool {
|
fn ne(&self, p: &PkgId) -> bool {
|
||||||
!(self.eq(p))
|
!(self.eq(p))
|
||||||
@ -42,10 +46,7 @@ impl Eq for PkgId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PkgId {
|
impl PkgId {
|
||||||
// The PkgId constructor takes a Path argument so as
|
pub fn new(s: &str) -> PkgId {
|
||||||
// to be able to infer the version if the path refers
|
|
||||||
// to a local git repository
|
|
||||||
pub fn new(s: &str, work_dir: &Path) -> PkgId {
|
|
||||||
use conditions::bad_pkg_id::cond;
|
use conditions::bad_pkg_id::cond;
|
||||||
|
|
||||||
let mut given_version = None;
|
let mut given_version = None;
|
||||||
@ -63,51 +64,64 @@ impl PkgId {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let p = Path(s);
|
let path = Path(s);
|
||||||
if p.is_absolute {
|
if path.is_absolute {
|
||||||
return cond.raise((p, ~"absolute pkgid"));
|
return cond.raise((path, ~"absolute pkgid"));
|
||||||
}
|
}
|
||||||
if p.components.len() < 1 {
|
if path.components.len() < 1 {
|
||||||
return cond.raise((p, ~"0-length pkgid"));
|
return cond.raise((path, ~"0-length pkgid"));
|
||||||
}
|
}
|
||||||
let remote_path = RemotePath(p);
|
let short_name = path.clone().filestem().expect(fmt!("Strange path! %s", s));
|
||||||
let local_path = normalize(remote_path.clone());
|
|
||||||
let short_name = local_path.clone().filestem().expect(fmt!("Strange path! %s", s));
|
|
||||||
|
|
||||||
let version = match given_version {
|
let version = match given_version {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => match try_getting_local_version(&work_dir.push_rel(&*local_path)) {
|
None => match try_getting_local_version(&path) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => match try_getting_version(&remote_path) {
|
None => match try_getting_version(&path) {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => NoVersion
|
None => NoVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("local_path = %s, remote_path = %s", local_path.to_str(), remote_path.to_str());
|
debug!("path = %s", path.to_str());
|
||||||
PkgId {
|
PkgId {
|
||||||
local_path: local_path,
|
path: path,
|
||||||
remote_path: remote_path,
|
|
||||||
short_name: short_name,
|
short_name: short_name,
|
||||||
version: version
|
version: version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(&self) -> ~str {
|
pub fn hash(&self) -> ~str {
|
||||||
fmt!("%s-%s-%s", self.remote_path.to_str(),
|
fmt!("%s-%s-%s", self.path.to_str(),
|
||||||
hash(self.remote_path.to_str() + self.version.to_str()),
|
hash(self.path.to_str() + self.version.to_str()),
|
||||||
self.version.to_str())
|
self.version.to_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn short_name_with_version(&self) -> ~str {
|
pub fn short_name_with_version(&self) -> ~str {
|
||||||
fmt!("%s%s", self.short_name, self.version.to_str())
|
fmt!("%s%s", self.short_name, self.version.to_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// True if the ID has multiple components
|
||||||
|
pub fn is_complex(&self) -> bool {
|
||||||
|
self.short_name != self.path.to_str()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToStr for PkgId {
|
impl ToStr for PkgId {
|
||||||
fn to_str(&self) -> ~str {
|
fn to_str(&self) -> ~str {
|
||||||
// should probably use the filestem and not the whole path
|
// should probably use the filestem and not the whole path
|
||||||
fmt!("%s-%s", self.local_path.to_str(), self.version.to_str())
|
fmt!("%s-%s", self.path.to_str(), self.version.to_str())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn write<W: Writer>(writer: &mut W, string: &str) {
|
||||||
|
writer.write(string.as_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hash(data: ~str) -> ~str {
|
||||||
|
let hasher = &mut hash::default_state();
|
||||||
|
write(hasher, data);
|
||||||
|
hasher.result_str()
|
||||||
|
}
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
// Copyright 2013 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.
|
|
||||||
|
|
||||||
// rustpkg utilities having to do with local and remote paths
|
|
||||||
|
|
||||||
use std::clone::Clone;
|
|
||||||
use std::hash::Streaming;
|
|
||||||
use std::hash;
|
|
||||||
use std::option::Some;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::rt::io::Writer;
|
|
||||||
|
|
||||||
/// Wrappers to prevent local and remote paths from getting confused
|
|
||||||
/// (These will go away after #6407)
|
|
||||||
pub struct RemotePath (Path);
|
|
||||||
|
|
||||||
impl Clone for RemotePath {
|
|
||||||
fn clone(&self) -> RemotePath {
|
|
||||||
RemotePath((**self).clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct LocalPath (Path);
|
|
||||||
|
|
||||||
impl Clone for LocalPath {
|
|
||||||
fn clone(&self) -> LocalPath {
|
|
||||||
LocalPath((**self).clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// normalize should be the only way to construct a LocalPath
|
|
||||||
// (though this isn't enforced)
|
|
||||||
/// Replace all occurrences of '-' in the stem part of path with '_'
|
|
||||||
/// This is because we treat rust-foo-bar-quux and rust_foo_bar_quux
|
|
||||||
/// as the same name
|
|
||||||
pub fn normalize(p_: RemotePath) -> LocalPath {
|
|
||||||
let RemotePath(p) = p_;
|
|
||||||
match p.filestem() {
|
|
||||||
None => LocalPath(p),
|
|
||||||
Some(st) => {
|
|
||||||
let replaced = st.replace("-", "_");
|
|
||||||
if replaced != st {
|
|
||||||
LocalPath(p.with_filestem(replaced))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LocalPath(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write<W: Writer>(writer: &mut W, string: &str) {
|
|
||||||
writer.write(string.as_bytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn hash(data: ~str) -> ~str {
|
|
||||||
let hasher = &mut hash::default_state();
|
|
||||||
write(hasher, data);
|
|
||||||
hasher.result_str()
|
|
||||||
}
|
|
@ -11,7 +11,7 @@
|
|||||||
use target::*;
|
use target::*;
|
||||||
use package_id::PkgId;
|
use package_id::PkgId;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::{os, str};
|
use std::os;
|
||||||
use context::*;
|
use context::*;
|
||||||
use crate::Crate;
|
use crate::Crate;
|
||||||
use messages::*;
|
use messages::*;
|
||||||
@ -23,7 +23,6 @@ use util::compile_crate;
|
|||||||
// This contains a list of files found in the source workspace.
|
// This contains a list of files found in the source workspace.
|
||||||
pub struct PkgSrc {
|
pub struct PkgSrc {
|
||||||
root: Path, // root of where the package source code lives
|
root: Path, // root of where the package source code lives
|
||||||
dst_dir: Path, // directory where we will put the compiled output
|
|
||||||
id: PkgId,
|
id: PkgId,
|
||||||
libs: ~[Crate],
|
libs: ~[Crate],
|
||||||
mains: ~[Crate],
|
mains: ~[Crate],
|
||||||
@ -37,11 +36,9 @@ condition! {
|
|||||||
|
|
||||||
impl PkgSrc {
|
impl PkgSrc {
|
||||||
|
|
||||||
pub fn new(src_dir: &Path, dst_dir: &Path,
|
pub fn new(src_dir: &Path, id: &PkgId) -> PkgSrc {
|
||||||
id: &PkgId) -> PkgSrc {
|
|
||||||
PkgSrc {
|
PkgSrc {
|
||||||
root: (*src_dir).clone(),
|
root: (*src_dir).clone(),
|
||||||
dst_dir: (*dst_dir).clone(),
|
|
||||||
id: (*id).clone(),
|
id: (*id).clone(),
|
||||||
libs: ~[],
|
libs: ~[],
|
||||||
mains: ~[],
|
mains: ~[],
|
||||||
@ -54,8 +51,7 @@ impl PkgSrc {
|
|||||||
fn check_dir(&self) -> Path {
|
fn check_dir(&self) -> Path {
|
||||||
use conditions::nonexistent_package::cond;
|
use conditions::nonexistent_package::cond;
|
||||||
|
|
||||||
debug!("Pushing onto root: %s | %s", self.id.remote_path.to_str(),
|
debug!("Pushing onto root: %s | %s", self.id.path.to_str(), self.root.to_str());
|
||||||
self.root.to_str());
|
|
||||||
let dir;
|
let dir;
|
||||||
let dirs = pkgid_src_in_workspace(&self.id, &self.root);
|
let dirs = pkgid_src_in_workspace(&self.id, &self.root);
|
||||||
debug!("Checking dirs: %?", dirs);
|
debug!("Checking dirs: %?", dirs);
|
||||||
@ -89,18 +85,18 @@ impl PkgSrc {
|
|||||||
os::remove_dir_recursive(&local);
|
os::remove_dir_recursive(&local);
|
||||||
|
|
||||||
debug!("Checking whether %s exists locally. Cwd = %s, does it? %?",
|
debug!("Checking whether %s exists locally. Cwd = %s, does it? %?",
|
||||||
self.id.local_path.to_str(),
|
self.id.path.to_str(),
|
||||||
os::getcwd().to_str(),
|
os::getcwd().to_str(),
|
||||||
os::path_exists(&*self.id.local_path));
|
os::path_exists(&self.id.path));
|
||||||
|
|
||||||
if os::path_exists(&*self.id.local_path) {
|
if os::path_exists(&self.id.path) {
|
||||||
debug!("%s exists locally! Cloning it into %s",
|
debug!("%s exists locally! Cloning it into %s",
|
||||||
self.id.local_path.to_str(), local.to_str());
|
self.id.path.to_str(), local.to_str());
|
||||||
git_clone(&*self.id.local_path, &local, &self.id.version);
|
git_clone(&self.id.path, &local, &self.id.version);
|
||||||
return Some(local);
|
return Some(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = fmt!("https://%s", self.id.remote_path.to_str());
|
let url = fmt!("https://%s", self.id.path.to_str());
|
||||||
note(fmt!("Fetching package: git clone %s %s [version=%s]",
|
note(fmt!("Fetching package: git clone %s %s [version=%s]",
|
||||||
url, local.to_str(), self.id.version.to_str()));
|
url, local.to_str(), self.id.version.to_str()));
|
||||||
if git_clone_general(url, &local, &self.id.version) {
|
if git_clone_general(url, &local, &self.id.version) {
|
||||||
@ -125,25 +121,8 @@ impl PkgSrc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// True if the given path's stem is self's pkg ID's stem
|
/// True if the given path's stem is self's pkg ID's stem
|
||||||
/// or if the pkg ID's stem is <rust-foo> and the given path's
|
|
||||||
/// stem is foo
|
|
||||||
/// Requires that dashes in p have already been normalized to
|
|
||||||
/// underscores
|
|
||||||
fn stem_matches(&self, p: &Path) -> bool {
|
fn stem_matches(&self, p: &Path) -> bool {
|
||||||
let self_id = self.id.local_path.filestem();
|
p.filestem().map_default(false, |p| { p == &self.id.short_name })
|
||||||
if self_id == p.filestem() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for pth in self_id.iter() {
|
|
||||||
if pth.starts_with("rust_") // because p is already normalized
|
|
||||||
&& match p.filestem() {
|
|
||||||
Some(s) => str::eq_slice(s, pth.slice(5, pth.len())),
|
|
||||||
None => false
|
|
||||||
} { return true; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) {
|
fn push_crate(cs: &mut ~[Crate], prefix: uint, p: &Path) {
|
||||||
@ -164,7 +143,7 @@ impl PkgSrc {
|
|||||||
let dir = self.check_dir();
|
let dir = self.check_dir();
|
||||||
debug!("Called check_dir, I'm in %s", dir.to_str());
|
debug!("Called check_dir, I'm in %s", dir.to_str());
|
||||||
let prefix = dir.components.len();
|
let prefix = dir.components.len();
|
||||||
debug!("Matching against %?", self.id.local_path.filestem());
|
debug!("Matching against %?", self.id.short_name);
|
||||||
do os::walk_dir(&dir) |pth| {
|
do os::walk_dir(&dir) |pth| {
|
||||||
match pth.filename() {
|
match pth.filename() {
|
||||||
Some(~"lib.rs") => PkgSrc::push_crate(&mut self.libs,
|
Some(~"lib.rs") => PkgSrc::push_crate(&mut self.libs,
|
||||||
@ -202,7 +181,6 @@ impl PkgSrc {
|
|||||||
|
|
||||||
fn build_crates(&self,
|
fn build_crates(&self,
|
||||||
ctx: &Ctx,
|
ctx: &Ctx,
|
||||||
dst_dir: &Path,
|
|
||||||
src_dir: &Path,
|
src_dir: &Path,
|
||||||
crates: &[Crate],
|
crates: &[Crate],
|
||||||
cfgs: &[~str],
|
cfgs: &[~str],
|
||||||
@ -210,12 +188,13 @@ impl PkgSrc {
|
|||||||
for crate in crates.iter() {
|
for crate in crates.iter() {
|
||||||
let path = &src_dir.push_rel(&crate.file).normalize();
|
let path = &src_dir.push_rel(&crate.file).normalize();
|
||||||
note(fmt!("build_crates: compiling %s", path.to_str()));
|
note(fmt!("build_crates: compiling %s", path.to_str()));
|
||||||
note(fmt!("build_crates: destination dir is %s", dst_dir.to_str()));
|
note(fmt!("build_crates: using as workspace %s", self.root.to_str()));
|
||||||
|
|
||||||
let result = compile_crate(ctx,
|
let result = compile_crate(ctx,
|
||||||
&self.id,
|
&self.id,
|
||||||
path,
|
path,
|
||||||
dst_dir,
|
// compile_crate wants the workspace
|
||||||
|
&self.root,
|
||||||
crate.flags,
|
crate.flags,
|
||||||
crate.cfgs + cfgs,
|
crate.cfgs + cfgs,
|
||||||
false,
|
false,
|
||||||
@ -229,15 +208,15 @@ impl PkgSrc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&self, ctx: &Ctx, dst_dir: Path, cfgs: ~[~str]) {
|
pub fn build(&self, ctx: &Ctx, cfgs: ~[~str]) {
|
||||||
let dir = self.check_dir();
|
let dir = self.check_dir();
|
||||||
debug!("Building libs in %s", dir.to_str());
|
debug!("Building libs in %s", dir.to_str());
|
||||||
self.build_crates(ctx, &dst_dir, &dir, self.libs, cfgs, Lib);
|
self.build_crates(ctx, &dir, self.libs, cfgs, Lib);
|
||||||
debug!("Building mains");
|
debug!("Building mains");
|
||||||
self.build_crates(ctx, &dst_dir, &dir, self.mains, cfgs, Main);
|
self.build_crates(ctx, &dir, self.mains, cfgs, Main);
|
||||||
debug!("Building tests");
|
debug!("Building tests");
|
||||||
self.build_crates(ctx, &dst_dir, &dir, self.tests, cfgs, Test);
|
self.build_crates(ctx, &dir, self.tests, cfgs, Test);
|
||||||
debug!("Building benches");
|
debug!("Building benches");
|
||||||
self.build_crates(ctx, &dst_dir, &dir, self.benchs, cfgs, Bench);
|
self.build_crates(ctx, &dir, self.benchs, cfgs, Bench);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,65 +10,17 @@
|
|||||||
|
|
||||||
// rustpkg utilities having to do with paths and directories
|
// rustpkg utilities having to do with paths and directories
|
||||||
|
|
||||||
pub use package_path::{RemotePath, LocalPath, normalize};
|
|
||||||
pub use package_id::PkgId;
|
pub use package_id::PkgId;
|
||||||
pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install};
|
pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install};
|
||||||
pub use version::{Version, NoVersion, split_version_general};
|
pub use version::{Version, NoVersion, split_version_general};
|
||||||
|
pub use rustc::metadata::filesearch::rust_path;
|
||||||
|
|
||||||
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||||
use std::os::mkdir_recursive;
|
use std::os::mkdir_recursive;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::iterator::IteratorUtil;
|
|
||||||
use messages::*;
|
use messages::*;
|
||||||
use package_id::*;
|
use package_id::*;
|
||||||
|
|
||||||
fn push_if_exists(vec: &mut ~[Path], p: &Path) {
|
|
||||||
let maybe_dir = p.push(".rust");
|
|
||||||
if os::path_exists(&maybe_dir) {
|
|
||||||
vec.push(maybe_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
static PATH_ENTRY_SEPARATOR: &'static str = ";";
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
static PATH_ENTRY_SEPARATOR: &'static str = ":";
|
|
||||||
|
|
||||||
/// Returns RUST_PATH as a string, without default paths added
|
|
||||||
pub fn get_rust_path() -> Option<~str> {
|
|
||||||
os::getenv("RUST_PATH")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the value of RUST_PATH, as a list
|
|
||||||
/// of Paths. Includes default entries for, if they exist:
|
|
||||||
/// $HOME/.rust
|
|
||||||
/// DIR/.rust for any DIR that's the current working directory
|
|
||||||
/// or an ancestor of it
|
|
||||||
pub fn rust_path() -> ~[Path] {
|
|
||||||
let mut env_rust_path: ~[Path] = match get_rust_path() {
|
|
||||||
Some(env_path) => {
|
|
||||||
let env_path_components: ~[&str] =
|
|
||||||
env_path.split_str_iter(PATH_ENTRY_SEPARATOR).collect();
|
|
||||||
env_path_components.map(|&s| Path(s))
|
|
||||||
}
|
|
||||||
None => ~[]
|
|
||||||
};
|
|
||||||
debug!("RUST_PATH entries from environment: %?", env_rust_path);
|
|
||||||
let cwd = os::getcwd();
|
|
||||||
// now add in default entries
|
|
||||||
env_rust_path.push(cwd.clone());
|
|
||||||
do cwd.each_parent() |p| { push_if_exists(&mut env_rust_path, p) };
|
|
||||||
let h = os::homedir();
|
|
||||||
// Avoid adding duplicates
|
|
||||||
// could still add dups if someone puts one of these in the RUST_PATH
|
|
||||||
// manually, though...
|
|
||||||
for hdir in h.iter() {
|
|
||||||
if !(cwd.is_ancestor_of(hdir) || hdir.is_ancestor_of(&cwd)) {
|
|
||||||
push_if_exists(&mut env_rust_path, hdir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
env_rust_path
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_workspace() -> Path {
|
pub fn default_workspace() -> Path {
|
||||||
let p = rust_path();
|
let p = rust_path();
|
||||||
if p.is_empty() {
|
if p.is_empty() {
|
||||||
@ -99,39 +51,39 @@ pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, U_RWX) }
|
|||||||
/// pkgid's short name
|
/// pkgid's short name
|
||||||
pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
|
pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
|
||||||
let src_dir = workspace.push("src");
|
let src_dir = workspace.push("src");
|
||||||
let dirs = os::list_dir(&src_dir);
|
let mut found = false;
|
||||||
for p in dirs.iter() {
|
do os::walk_dir(&src_dir) |p| {
|
||||||
let p = Path((*p).clone());
|
|
||||||
debug!("=> p = %s", p.to_str());
|
debug!("=> p = %s", p.to_str());
|
||||||
if !os::path_is_dir(&src_dir.push_rel(&p)) {
|
if os::path_is_dir(p) {
|
||||||
loop;
|
debug!("p = %s, path = %s [%s]", p.to_str(), pkgid.path.to_str(),
|
||||||
}
|
src_dir.push_rel(&pkgid.path).to_str());
|
||||||
debug!("p = %s, remote_path = %s", p.to_str(), pkgid.remote_path.to_str());
|
|
||||||
|
|
||||||
if p == *pkgid.remote_path {
|
if *p == src_dir.push_rel(&pkgid.path) {
|
||||||
return true;
|
found = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let pf = p.filename();
|
let pf = p.filename();
|
||||||
for pf in pf.iter() {
|
for pf in pf.iter() {
|
||||||
let f_ = (*pf).clone();
|
let f_ = (*pf).clone();
|
||||||
let g = f_.to_str();
|
let g = f_.to_str();
|
||||||
match split_version_general(g, '-') {
|
match split_version_general(g, '-') {
|
||||||
Some((ref might_match, ref vers)) => {
|
Some((ref might_match, ref vers)) => {
|
||||||
debug!("might_match = %s, vers = %s", *might_match,
|
debug!("might_match = %s, vers = %s", *might_match,
|
||||||
vers.to_str());
|
vers.to_str());
|
||||||
if *might_match == pkgid.short_name
|
if *might_match == pkgid.short_name
|
||||||
&& (*vers == pkgid.version || pkgid.version == NoVersion)
|
&& (*vers == pkgid.version || pkgid.version == NoVersion)
|
||||||
{
|
{
|
||||||
return true;
|
found = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
None => ()
|
||||||
None => ()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
true
|
||||||
false
|
};
|
||||||
|
found
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of possible directories
|
/// Returns a list of possible directories
|
||||||
@ -141,9 +93,9 @@ pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
|
|||||||
pub fn pkgid_src_in_workspace(pkgid: &PkgId, workspace: &Path) -> ~[Path] {
|
pub fn pkgid_src_in_workspace(pkgid: &PkgId, workspace: &Path) -> ~[Path] {
|
||||||
let mut results = ~[];
|
let mut results = ~[];
|
||||||
let result = workspace.push("src").push(fmt!("%s-%s",
|
let result = workspace.push("src").push(fmt!("%s-%s",
|
||||||
pkgid.local_path.to_str(), pkgid.version.to_str()));
|
pkgid.path.to_str(), pkgid.version.to_str()));
|
||||||
results.push(result);
|
results.push(result);
|
||||||
results.push(workspace.push("src").push_rel(&*pkgid.remote_path));
|
results.push(workspace.push("src").push_rel(&pkgid.path));
|
||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +115,7 @@ pub fn first_pkgid_src_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<P
|
|||||||
pub fn built_executable_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
|
pub fn built_executable_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
|
||||||
let mut result = workspace.push("build");
|
let mut result = workspace.push("build");
|
||||||
// should use a target-specific subdirectory
|
// should use a target-specific subdirectory
|
||||||
result = mk_output_path(Main, Build, pkgid, &result);
|
result = mk_output_path(Main, Build, pkgid, result);
|
||||||
debug!("built_executable_in_workspace: checking whether %s exists",
|
debug!("built_executable_in_workspace: checking whether %s exists",
|
||||||
result.to_str());
|
result.to_str());
|
||||||
if os::path_exists(&result) {
|
if os::path_exists(&result) {
|
||||||
@ -191,7 +143,7 @@ pub fn built_bench_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path>
|
|||||||
fn output_in_workspace(pkgid: &PkgId, workspace: &Path, what: OutputType) -> Option<Path> {
|
fn output_in_workspace(pkgid: &PkgId, workspace: &Path, what: OutputType) -> Option<Path> {
|
||||||
let mut result = workspace.push("build");
|
let mut result = workspace.push("build");
|
||||||
// should use a target-specific subdirectory
|
// should use a target-specific subdirectory
|
||||||
result = mk_output_path(what, Build, pkgid, &result);
|
result = mk_output_path(what, Build, pkgid, result);
|
||||||
debug!("output_in_workspace: checking whether %s exists",
|
debug!("output_in_workspace: checking whether %s exists",
|
||||||
result.to_str());
|
result.to_str());
|
||||||
if os::path_exists(&result) {
|
if os::path_exists(&result) {
|
||||||
@ -206,14 +158,12 @@ fn output_in_workspace(pkgid: &PkgId, workspace: &Path, what: OutputType) -> Opt
|
|||||||
/// Figure out what the library name for <pkgid> in <workspace>'s build
|
/// Figure out what the library name for <pkgid> in <workspace>'s build
|
||||||
/// directory is, and if the file exists, return it.
|
/// directory is, and if the file exists, return it.
|
||||||
pub fn built_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
|
pub fn built_library_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
|
||||||
library_in_workspace(&pkgid.local_path, pkgid.short_name,
|
library_in_workspace(&pkgid.path, pkgid.short_name, Build, workspace, "build")
|
||||||
Build, workspace, "build")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Does the actual searching stuff
|
/// Does the actual searching stuff
|
||||||
pub fn installed_library_in_workspace(short_name: &str, workspace: &Path) -> Option<Path> {
|
pub fn installed_library_in_workspace(short_name: &str, workspace: &Path) -> Option<Path> {
|
||||||
library_in_workspace(&normalize(RemotePath(Path(short_name))),
|
library_in_workspace(&Path(short_name), short_name, Install, workspace, "lib")
|
||||||
short_name, Install, workspace, "lib")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -221,7 +171,7 @@ pub fn installed_library_in_workspace(short_name: &str, workspace: &Path) -> Opt
|
|||||||
/// don't know the entire package ID.
|
/// don't know the entire package ID.
|
||||||
/// `workspace` is used to figure out the directory to search.
|
/// `workspace` is used to figure out the directory to search.
|
||||||
/// `short_name` is taken as the link name of the library.
|
/// `short_name` is taken as the link name of the library.
|
||||||
pub fn library_in_workspace(path: &LocalPath, short_name: &str, where: Target,
|
pub fn library_in_workspace(path: &Path, short_name: &str, where: Target,
|
||||||
workspace: &Path, prefix: &str) -> Option<Path> {
|
workspace: &Path, prefix: &str) -> Option<Path> {
|
||||||
debug!("library_in_workspace: checking whether a library named %s exists",
|
debug!("library_in_workspace: checking whether a library named %s exists",
|
||||||
short_name);
|
short_name);
|
||||||
@ -233,7 +183,7 @@ pub fn library_in_workspace(path: &LocalPath, short_name: &str, where: Target,
|
|||||||
prefix = %s", short_name, where, workspace.to_str(), prefix);
|
prefix = %s", short_name, where, workspace.to_str(), prefix);
|
||||||
|
|
||||||
let dir_to_search = match where {
|
let dir_to_search = match where {
|
||||||
Build => workspace.push(prefix).push_rel(&**path),
|
Build => workspace.push(prefix).push_rel(path),
|
||||||
Install => workspace.push(prefix)
|
Install => workspace.push(prefix)
|
||||||
};
|
};
|
||||||
debug!("Listing directory %s", dir_to_search.to_str());
|
debug!("Listing directory %s", dir_to_search.to_str());
|
||||||
@ -349,7 +299,7 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path,
|
|||||||
// Artifacts in the build directory live in a package-ID-specific subdirectory,
|
// Artifacts in the build directory live in a package-ID-specific subdirectory,
|
||||||
// but installed ones don't.
|
// but installed ones don't.
|
||||||
let result = match where {
|
let result = match where {
|
||||||
Build => workspace.push(subdir).push_rel(&*pkgid.local_path),
|
Build => workspace.push(subdir).push_rel(&pkgid.path),
|
||||||
_ => workspace.push(subdir)
|
_ => workspace.push(subdir)
|
||||||
};
|
};
|
||||||
if !os::path_exists(&result) && !mkdir_recursive(&result, U_RWX) {
|
if !os::path_exists(&result) && !mkdir_recursive(&result, U_RWX) {
|
||||||
@ -357,7 +307,7 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path,
|
|||||||
create the %s dir (pkgid=%s, workspace=%s, what=%?, where=%?",
|
create the %s dir (pkgid=%s, workspace=%s, what=%?, where=%?",
|
||||||
subdir, pkgid.to_str(), workspace.to_str(), what, where)));
|
subdir, pkgid.to_str(), workspace.to_str(), what, where)));
|
||||||
}
|
}
|
||||||
mk_output_path(what, where, pkgid, &result)
|
mk_output_path(what, where, pkgid, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the directory for <pkgid>'s build artifacts in <workspace>.
|
/// Return the directory for <pkgid>'s build artifacts in <workspace>.
|
||||||
@ -368,7 +318,7 @@ pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
|
|||||||
let mut result = workspace.push("build");
|
let mut result = workspace.push("build");
|
||||||
// n.b. Should actually use a target-specific
|
// n.b. Should actually use a target-specific
|
||||||
// subdirectory of build/
|
// subdirectory of build/
|
||||||
result = result.push_rel(&*pkgid.local_path);
|
result = result.push_rel(&pkgid.path);
|
||||||
if os::path_exists(&result) || os::mkdir_recursive(&result, U_RWX) {
|
if os::path_exists(&result) || os::mkdir_recursive(&result, U_RWX) {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@ -380,19 +330,16 @@ pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
|
|||||||
/// Return the output file for a given directory name,
|
/// Return the output file for a given directory name,
|
||||||
/// given whether we're building a library and whether we're building tests
|
/// given whether we're building a library and whether we're building tests
|
||||||
pub fn mk_output_path(what: OutputType, where: Target,
|
pub fn mk_output_path(what: OutputType, where: Target,
|
||||||
pkg_id: &PkgId, workspace: &Path) -> Path {
|
pkg_id: &PkgId, workspace: Path) -> Path {
|
||||||
let short_name_with_version = fmt!("%s-%s", pkg_id.short_name,
|
let short_name_with_version = fmt!("%s-%s", pkg_id.short_name,
|
||||||
pkg_id.version.to_str());
|
pkg_id.version.to_str());
|
||||||
// Not local_path.dir_path()! For package foo/bar/blat/, we want
|
// Not local_path.dir_path()! For package foo/bar/blat/, we want
|
||||||
// the executable blat-0.5 to live under blat/
|
// the executable blat-0.5 to live under blat/
|
||||||
let dir = match where {
|
let dir = match where {
|
||||||
// If we're installing, it just goes under <workspace>...
|
// If we're installing, it just goes under <workspace>...
|
||||||
Install => {
|
Install => workspace,
|
||||||
// bad copy, but I just couldn't make the borrow checker happy
|
|
||||||
(*workspace).clone()
|
|
||||||
}
|
|
||||||
// and if we're just building, it goes in a package-specific subdir
|
// and if we're just building, it goes in a package-specific subdir
|
||||||
Build => workspace.push_rel(&*pkg_id.local_path)
|
Build => workspace.push_rel(&pkg_id.path)
|
||||||
};
|
};
|
||||||
debug!("[%?:%?] mk_output_path: short_name = %s, path = %s", what, where,
|
debug!("[%?:%?] mk_output_path: short_name = %s, path = %s", what, where,
|
||||||
if what == Lib { short_name_with_version.clone() } else { pkg_id.short_name.clone() },
|
if what == Lib { short_name_with_version.clone() } else { pkg_id.short_name.clone() },
|
||||||
|
@ -33,12 +33,13 @@ use std::hashmap::HashMap;
|
|||||||
|
|
||||||
use rustc::driver::{driver, session};
|
use rustc::driver::{driver, session};
|
||||||
use rustc::metadata::filesearch;
|
use rustc::metadata::filesearch;
|
||||||
|
use rustc::metadata::filesearch::rust_path;
|
||||||
use extra::{getopts};
|
use extra::{getopts};
|
||||||
use syntax::{ast, diagnostic};
|
use syntax::{ast, diagnostic};
|
||||||
use util::*;
|
use util::*;
|
||||||
use messages::*;
|
use messages::*;
|
||||||
use path_util::{build_pkg_id_in_workspace, first_pkgid_src_in_workspace};
|
use path_util::{build_pkg_id_in_workspace, first_pkgid_src_in_workspace};
|
||||||
use path_util::{U_RWX, rust_path, in_rust_path};
|
use path_util::{U_RWX, in_rust_path};
|
||||||
use path_util::{built_executable_in_workspace, built_library_in_workspace, default_workspace};
|
use path_util::{built_executable_in_workspace, built_library_in_workspace, default_workspace};
|
||||||
use path_util::{target_executable_in_workspace, target_library_in_workspace};
|
use path_util::{target_executable_in_workspace, target_library_in_workspace};
|
||||||
use source_control::is_git_dir;
|
use source_control::is_git_dir;
|
||||||
@ -54,7 +55,6 @@ mod crate;
|
|||||||
mod installed_packages;
|
mod installed_packages;
|
||||||
mod messages;
|
mod messages;
|
||||||
mod package_id;
|
mod package_id;
|
||||||
mod package_path;
|
|
||||||
mod package_source;
|
mod package_source;
|
||||||
mod path_util;
|
mod path_util;
|
||||||
mod search;
|
mod search;
|
||||||
@ -138,35 +138,28 @@ impl<'self> PkgScript<'self> {
|
|||||||
let crate = util::ready_crate(sess, self.crate);
|
let crate = util::ready_crate(sess, self.crate);
|
||||||
debug!("Building output filenames with script name %s",
|
debug!("Building output filenames with script name %s",
|
||||||
driver::source_name(&self.input));
|
driver::source_name(&self.input));
|
||||||
match filesearch::get_rustpkg_sysroot() {
|
let root = filesearch::get_or_default_sysroot().pop().pop(); // :-\
|
||||||
Ok(r) => {
|
debug!("Root is %s, calling compile_rest", root.to_str());
|
||||||
let root = r.pop().pop().pop().pop(); // :-\
|
let exe = self.build_dir.push(~"pkg" + util::exe_suffix());
|
||||||
debug!("Root is %s, calling compile_rest", root.to_str());
|
util::compile_crate_from_input(&self.input,
|
||||||
let exe = self.build_dir.push(~"pkg" + util::exe_suffix());
|
&self.build_dir,
|
||||||
util::compile_crate_from_input(&self.input,
|
sess,
|
||||||
&self.build_dir,
|
crate);
|
||||||
sess,
|
debug!("Running program: %s %s %s %s", exe.to_str(),
|
||||||
crate);
|
sysroot.to_str(), root.to_str(), "install");
|
||||||
debug!("Running program: %s %s %s %s", exe.to_str(),
|
// FIXME #7401 should support commands besides `install`
|
||||||
sysroot.to_str(), root.to_str(), "install");
|
let status = run::process_status(exe.to_str(), [sysroot.to_str(), ~"install"]);
|
||||||
// FIXME #7401 should support commands besides `install`
|
if status != 0 {
|
||||||
let status = run::process_status(exe.to_str(), [sysroot.to_str(), ~"install"]);
|
return (~[], status);
|
||||||
if status != 0 {
|
}
|
||||||
return (~[], status);
|
else {
|
||||||
}
|
debug!("Running program (configs): %s %s %s",
|
||||||
else {
|
exe.to_str(), root.to_str(), "configs");
|
||||||
debug!("Running program (configs): %s %s %s",
|
let output = run::process_output(exe.to_str(), [root.to_str(), ~"configs"]);
|
||||||
exe.to_str(), root.to_str(), "configs");
|
// Run the configs() function to get the configs
|
||||||
let output = run::process_output(exe.to_str(), [root.to_str(), ~"configs"]);
|
let cfgs = str::from_bytes_slice(output.output).word_iter()
|
||||||
// Run the configs() function to get the configs
|
.transform(|w| w.to_owned()).collect();
|
||||||
let cfgs = str::from_bytes_slice(output.output).word_iter()
|
(cfgs, output.status)
|
||||||
.transform(|w| w.to_owned()).collect();
|
|
||||||
(cfgs, output.status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
fail!("Running package script, couldn't find rustpkg sysroot (%s)", e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +198,7 @@ impl CtxMethods for Ctx {
|
|||||||
else {
|
else {
|
||||||
// The package id is presumed to be the first command-line
|
// The package id is presumed to be the first command-line
|
||||||
// argument
|
// argument
|
||||||
let pkgid = PkgId::new(args[0].clone(), &os::getcwd());
|
let pkgid = PkgId::new(args[0].clone());
|
||||||
do each_pkg_parent_workspace(&pkgid) |workspace| {
|
do each_pkg_parent_workspace(&pkgid) |workspace| {
|
||||||
debug!("found pkg %s in workspace %s, trying to build",
|
debug!("found pkg %s in workspace %s, trying to build",
|
||||||
pkgid.to_str(), workspace.to_str());
|
pkgid.to_str(), workspace.to_str());
|
||||||
@ -228,7 +221,7 @@ impl CtxMethods for Ctx {
|
|||||||
else {
|
else {
|
||||||
// The package id is presumed to be the first command-line
|
// The package id is presumed to be the first command-line
|
||||||
// argument
|
// argument
|
||||||
let pkgid = PkgId::new(args[0].clone(), &os::getcwd());
|
let pkgid = PkgId::new(args[0].clone());
|
||||||
let cwd = os::getcwd();
|
let cwd = os::getcwd();
|
||||||
self.clean(&cwd, &pkgid); // tjc: should use workspace, not cwd
|
self.clean(&cwd, &pkgid); // tjc: should use workspace, not cwd
|
||||||
}
|
}
|
||||||
@ -254,13 +247,12 @@ impl CtxMethods for Ctx {
|
|||||||
else {
|
else {
|
||||||
// The package id is presumed to be the first command-line
|
// The package id is presumed to be the first command-line
|
||||||
// argument
|
// argument
|
||||||
let pkgid = PkgId::new(args[0], &os::getcwd());
|
let pkgid = PkgId::new(args[0]);
|
||||||
let workspaces = pkg_parent_workspaces(&pkgid);
|
let workspaces = pkg_parent_workspaces(&pkgid);
|
||||||
if workspaces.is_empty() {
|
if workspaces.is_empty() {
|
||||||
let rp = rust_path();
|
let rp = rust_path();
|
||||||
assert!(!rp.is_empty());
|
assert!(!rp.is_empty());
|
||||||
let src = PkgSrc::new(&rp[0], &build_pkg_id_in_workspace(&pkgid, &rp[0]),
|
let src = PkgSrc::new(&rp[0], &pkgid);
|
||||||
&pkgid);
|
|
||||||
src.fetch_git();
|
src.fetch_git();
|
||||||
self.install(&rp[0], &pkgid);
|
self.install(&rp[0], &pkgid);
|
||||||
}
|
}
|
||||||
@ -275,7 +267,7 @@ impl CtxMethods for Ctx {
|
|||||||
"list" => {
|
"list" => {
|
||||||
io::println("Installed packages:");
|
io::println("Installed packages:");
|
||||||
do installed_packages::list_installed_packages |pkg_id| {
|
do installed_packages::list_installed_packages |pkg_id| {
|
||||||
println(pkg_id.local_path.to_str());
|
println(pkg_id.path.to_str());
|
||||||
true
|
true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -294,7 +286,7 @@ impl CtxMethods for Ctx {
|
|||||||
return usage::uninstall();
|
return usage::uninstall();
|
||||||
}
|
}
|
||||||
|
|
||||||
let pkgid = PkgId::new(args[0], &os::getcwd()); // ??
|
let pkgid = PkgId::new(args[0]);
|
||||||
if !installed_packages::package_is_installed(&pkgid) {
|
if !installed_packages::package_is_installed(&pkgid) {
|
||||||
warn(fmt!("Package %s doesn't seem to be installed! Doing nothing.", args[0]));
|
warn(fmt!("Package %s doesn't seem to be installed! Doing nothing.", args[0]));
|
||||||
return;
|
return;
|
||||||
@ -329,20 +321,18 @@ impl CtxMethods for Ctx {
|
|||||||
fn build(&self, workspace: &Path, pkgid: &PkgId) {
|
fn build(&self, workspace: &Path, pkgid: &PkgId) {
|
||||||
debug!("build: workspace = %s (in Rust path? %? is git dir? %? \
|
debug!("build: workspace = %s (in Rust path? %? is git dir? %? \
|
||||||
pkgid = %s", workspace.to_str(),
|
pkgid = %s", workspace.to_str(),
|
||||||
in_rust_path(workspace), is_git_dir(&workspace.push_rel(&*pkgid.local_path)),
|
in_rust_path(workspace), is_git_dir(&workspace.push_rel(&pkgid.path)),
|
||||||
pkgid.to_str());
|
pkgid.to_str());
|
||||||
let src_dir = first_pkgid_src_in_workspace(pkgid, workspace);
|
let src_dir = first_pkgid_src_in_workspace(pkgid, workspace);
|
||||||
let build_dir = build_pkg_id_in_workspace(pkgid, workspace);
|
|
||||||
debug!("Destination dir = %s", build_dir.to_str());
|
|
||||||
|
|
||||||
// If workspace isn't in the RUST_PATH, and it's a git repo,
|
// If workspace isn't in the RUST_PATH, and it's a git repo,
|
||||||
// then clone it into the first entry in RUST_PATH, and repeat
|
// then clone it into the first entry in RUST_PATH, and repeat
|
||||||
debug!("%? %? %s", in_rust_path(workspace),
|
debug!("%? %? %s", in_rust_path(workspace),
|
||||||
is_git_dir(&workspace.push_rel(&*pkgid.local_path)),
|
is_git_dir(&workspace.push_rel(&pkgid.path)),
|
||||||
workspace.to_str());
|
workspace.to_str());
|
||||||
if !in_rust_path(workspace) && is_git_dir(&workspace.push_rel(&*pkgid.local_path)) {
|
if !in_rust_path(workspace) && is_git_dir(&workspace.push_rel(&pkgid.path)) {
|
||||||
let out_dir = default_workspace().push("src").push_rel(&*pkgid.local_path);
|
let out_dir = default_workspace().push("src").push_rel(&pkgid.path);
|
||||||
source_control::git_clone(&workspace.push_rel(&*pkgid.local_path),
|
source_control::git_clone(&workspace.push_rel(&pkgid.path),
|
||||||
&out_dir, &pkgid.version);
|
&out_dir, &pkgid.version);
|
||||||
let default_ws = default_workspace();
|
let default_ws = default_workspace();
|
||||||
debug!("Calling build recursively with %? and %?", default_ws.to_str(),
|
debug!("Calling build recursively with %? and %?", default_ws.to_str(),
|
||||||
@ -351,7 +341,7 @@ impl CtxMethods for Ctx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the package source
|
// Create the package source
|
||||||
let mut src = PkgSrc::new(workspace, &build_dir, pkgid);
|
let mut src = PkgSrc::new(workspace, pkgid);
|
||||||
debug!("Package src = %?", src);
|
debug!("Package src = %?", src);
|
||||||
|
|
||||||
// Is there custom build logic? If so, use it
|
// Is there custom build logic? If so, use it
|
||||||
@ -385,7 +375,7 @@ impl CtxMethods for Ctx {
|
|||||||
// Find crates inside the workspace
|
// Find crates inside the workspace
|
||||||
src.find_crates();
|
src.find_crates();
|
||||||
// Build it!
|
// Build it!
|
||||||
src.build(self, build_dir, cfgs);
|
src.build(self, cfgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,6 +434,7 @@ impl CtxMethods for Ctx {
|
|||||||
for lib in maybe_library.iter() {
|
for lib in maybe_library.iter() {
|
||||||
let target_lib = target_lib.clone().expect(fmt!("I built %s but apparently \
|
let target_lib = target_lib.clone().expect(fmt!("I built %s but apparently \
|
||||||
didn't install it!", lib.to_str()));
|
didn't install it!", lib.to_str()));
|
||||||
|
let target_lib = target_lib.pop().push(lib.filename().expect("weird target lib"));
|
||||||
debug!("Copying: %s -> %s", lib.to_str(), target_lib.to_str());
|
debug!("Copying: %s -> %s", lib.to_str(), target_lib.to_str());
|
||||||
if !(os::mkdir_recursive(&target_lib.dir_path(), U_RWX) &&
|
if !(os::mkdir_recursive(&target_lib.dir_path(), U_RWX) &&
|
||||||
os::copy_file(lib, &target_lib)) {
|
os::copy_file(lib, &target_lib)) {
|
||||||
@ -518,9 +509,7 @@ pub fn main() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let sroot = match filesearch::get_rustpkg_sysroot() {
|
let sroot = Some(@filesearch::get_or_default_sysroot());
|
||||||
Ok(r) => Some(@r.pop().pop()), Err(_) => None
|
|
||||||
};
|
|
||||||
debug!("Using sysroot: %?", sroot);
|
debug!("Using sysroot: %?", sroot);
|
||||||
Ctx {
|
Ctx {
|
||||||
sysroot_opt: sroot, // Currently, only tests override this
|
sysroot_opt: sroot, // Currently, only tests override this
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// Utils for working with version control repositories. Just git right now.
|
// Utils for working with version control repositories. Just git right now.
|
||||||
|
|
||||||
use std::{os, run, str};
|
use std::{io, os, run, str};
|
||||||
use std::run::{ProcessOutput, ProcessOptions, Process};
|
use std::run::{ProcessOutput, ProcessOptions, Process};
|
||||||
use version::*;
|
use version::*;
|
||||||
|
|
||||||
@ -19,14 +19,37 @@ pub fn git_clone(source: &Path, target: &Path, v: &Version) {
|
|||||||
assert!(os::path_is_dir(source));
|
assert!(os::path_is_dir(source));
|
||||||
assert!(is_git_dir(source));
|
assert!(is_git_dir(source));
|
||||||
if !os::path_exists(target) {
|
if !os::path_exists(target) {
|
||||||
debug!("Running: git clone %s %s", source.to_str(),
|
debug!("Running: git clone %s %s", source.to_str(), target.to_str());
|
||||||
target.to_str());
|
let outp = run::process_output("git", [~"clone", source.to_str(), target.to_str()]);
|
||||||
assert!(git_clone_general(source.to_str(), target, v));
|
if outp.status != 0 {
|
||||||
|
io::println(str::from_bytes_owned(outp.output.clone()));
|
||||||
|
io::println(str::from_bytes_owned(outp.error));
|
||||||
|
fail!("Couldn't `git clone` %s", source.to_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
match v {
|
||||||
|
&ExactRevision(ref s) => {
|
||||||
|
debug!("`Running: git --work-tree=%s --git-dir=%s checkout %s",
|
||||||
|
*s, target.to_str(), target.push(".git").to_str());
|
||||||
|
let outp = run::process_output("git",
|
||||||
|
[fmt!("--work-tree=%s", target.to_str()),
|
||||||
|
fmt!("--git-dir=%s", target.push(".git").to_str()),
|
||||||
|
~"checkout", fmt!("%s", *s)]);
|
||||||
|
if outp.status != 0 {
|
||||||
|
io::println(str::from_bytes_owned(outp.output.clone()));
|
||||||
|
io::println(str::from_bytes_owned(outp.error));
|
||||||
|
fail!("Couldn't `git checkout %s` in %s",
|
||||||
|
*s, target.to_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Pull changes
|
// Check that no version was specified. There's no reason to not handle the
|
||||||
// Note that this ignores tags, which is probably wrong. There are no tests for
|
// case where a version was requested, but I haven't implemented it.
|
||||||
// it, though.
|
assert!(*v == NoVersion);
|
||||||
debug!("Running: git --work-tree=%s --git-dir=%s pull --no-edit %s",
|
debug!("Running: git --work-tree=%s --git-dir=%s pull --no-edit %s",
|
||||||
target.to_str(), target.push(".git").to_str(), source.to_str());
|
target.to_str(), target.push(".git").to_str(), source.to_str());
|
||||||
let outp = run::process_output("git", [fmt!("--work-tree=%s", target.to_str()),
|
let outp = run::process_output("git", [fmt!("--work-tree=%s", target.to_str()),
|
||||||
|
@ -12,11 +12,10 @@
|
|||||||
|
|
||||||
use context::Ctx;
|
use context::Ctx;
|
||||||
use std::hashmap::HashMap;
|
use std::hashmap::HashMap;
|
||||||
use std::{io, libc, os, result, run, str};
|
use std::{io, libc, os, run, str};
|
||||||
use extra::tempfile::mkdtemp;
|
use extra::tempfile::mkdtemp;
|
||||||
use std::run::ProcessOutput;
|
use std::run::ProcessOutput;
|
||||||
use installed_packages::list_installed_packages;
|
use installed_packages::list_installed_packages;
|
||||||
use package_path::*;
|
|
||||||
use package_id::{PkgId};
|
use package_id::{PkgId};
|
||||||
use version::{ExactRevision, NoVersion, Version, Tagged};
|
use version::{ExactRevision, NoVersion, Version, Tagged};
|
||||||
use path_util::{target_executable_in_workspace, target_library_in_workspace,
|
use path_util::{target_executable_in_workspace, target_library_in_workspace,
|
||||||
@ -24,7 +23,9 @@ use path_util::{target_executable_in_workspace, target_library_in_workspace,
|
|||||||
make_dir_rwx, U_RWX, library_in_workspace,
|
make_dir_rwx, U_RWX, library_in_workspace,
|
||||||
built_bench_in_workspace, built_test_in_workspace,
|
built_bench_in_workspace, built_test_in_workspace,
|
||||||
built_library_in_workspace, built_executable_in_workspace,
|
built_library_in_workspace, built_executable_in_workspace,
|
||||||
installed_library_in_workspace, rust_path};
|
installed_library_in_workspace};
|
||||||
|
use rustc::metadata::filesearch::rust_path;
|
||||||
|
use rustc::driver::driver::host_triple;
|
||||||
use target::*;
|
use target::*;
|
||||||
|
|
||||||
/// Returns the last-modified date as an Option
|
/// Returns the last-modified date as an Option
|
||||||
@ -42,31 +43,25 @@ fn fake_ctxt(sysroot_opt: Option<@Path>) -> Ctx {
|
|||||||
|
|
||||||
fn fake_pkg() -> PkgId {
|
fn fake_pkg() -> PkgId {
|
||||||
let sn = ~"bogus";
|
let sn = ~"bogus";
|
||||||
let remote = RemotePath(Path(sn));
|
|
||||||
PkgId {
|
PkgId {
|
||||||
local_path: normalize(remote.clone()),
|
path: Path(sn),
|
||||||
remote_path: remote,
|
|
||||||
short_name: sn,
|
short_name: sn,
|
||||||
version: NoVersion
|
version: NoVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn git_repo_pkg() -> PkgId {
|
fn git_repo_pkg() -> PkgId {
|
||||||
let remote = RemotePath(Path("mockgithub.com/catamorphism/test-pkg"));
|
|
||||||
PkgId {
|
PkgId {
|
||||||
local_path: normalize(remote.clone()),
|
path: Path("mockgithub.com/catamorphism/test-pkg"),
|
||||||
remote_path: remote,
|
short_name: ~"test-pkg",
|
||||||
short_name: ~"test_pkg",
|
|
||||||
version: NoVersion
|
version: NoVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn git_repo_pkg_with_tag(a_tag: ~str) -> PkgId {
|
fn git_repo_pkg_with_tag(a_tag: ~str) -> PkgId {
|
||||||
let remote = RemotePath(Path("mockgithub.com/catamorphism/test-pkg"));
|
|
||||||
PkgId {
|
PkgId {
|
||||||
local_path: normalize(remote.clone()),
|
path: Path("mockgithub.com/catamorphism/test-pkg"),
|
||||||
remote_path: remote,
|
short_name: ~"test-pkg",
|
||||||
short_name: ~"test_pkg",
|
|
||||||
version: Tagged(a_tag)
|
version: Tagged(a_tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,13 +71,13 @@ fn writeFile(file_path: &Path, contents: &str) {
|
|||||||
out.write_line(contents);
|
out.write_line(contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_empty_workspace(short_name: &LocalPath, version: &Version) -> Path {
|
fn mk_empty_workspace(short_name: &Path, version: &Version) -> Path {
|
||||||
let workspace_dir = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
|
let workspace_dir = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
|
||||||
mk_workspace(&workspace_dir, short_name, version);
|
mk_workspace(&workspace_dir, short_name, version);
|
||||||
workspace_dir
|
workspace_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_workspace(workspace: &Path, short_name: &LocalPath, version: &Version) -> Path {
|
fn mk_workspace(workspace: &Path, short_name: &Path, version: &Version) -> Path {
|
||||||
// include version number in directory name
|
// include version number in directory name
|
||||||
let package_dir = workspace.push("src").push(fmt!("%s-%s",
|
let package_dir = workspace.push("src").push(fmt!("%s-%s",
|
||||||
short_name.to_str(), version.to_str()));
|
short_name.to_str(), version.to_str()));
|
||||||
@ -90,7 +85,7 @@ fn mk_workspace(workspace: &Path, short_name: &LocalPath, version: &Version) ->
|
|||||||
package_dir
|
package_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_temp_workspace(short_name: &LocalPath, version: &Version) -> Path {
|
fn mk_temp_workspace(short_name: &Path, version: &Version) -> Path {
|
||||||
let package_dir = mk_empty_workspace(short_name,
|
let package_dir = mk_empty_workspace(short_name,
|
||||||
version).push("src").push(fmt!("%s-%s",
|
version).push("src").push(fmt!("%s-%s",
|
||||||
short_name.to_str(),
|
short_name.to_str(),
|
||||||
@ -116,6 +111,22 @@ fn mk_temp_workspace(short_name: &LocalPath, version: &Version) -> Path {
|
|||||||
package_dir
|
package_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_git(args: &[~str], env: Option<~[(~str, ~str)]>, cwd: &Path, err_msg: &str) {
|
||||||
|
let cwd = (*cwd).clone();
|
||||||
|
let mut prog = run::Process::new("git", args, run::ProcessOptions {
|
||||||
|
env: env.map(|v| v.slice(0, v.len())),
|
||||||
|
dir: Some(&cwd),
|
||||||
|
in_fd: None,
|
||||||
|
out_fd: None,
|
||||||
|
err_fd: None
|
||||||
|
});
|
||||||
|
let rslt = prog.finish_with_output();
|
||||||
|
if rslt.status != 0 {
|
||||||
|
fail!("%s [git returned %?, output = %s, error = %s]", err_msg,
|
||||||
|
rslt.status, str::from_bytes(rslt.output), str::from_bytes(rslt.error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Should create an empty git repo in p, relative to the tmp dir, and return the new
|
/// Should create an empty git repo in p, relative to the tmp dir, and return the new
|
||||||
/// absolute path
|
/// absolute path
|
||||||
fn init_git_repo(p: &Path) -> Path {
|
fn init_git_repo(p: &Path) -> Path {
|
||||||
@ -125,37 +136,14 @@ fn init_git_repo(p: &Path) -> Path {
|
|||||||
let work_dir_for_opts = work_dir.clone();
|
let work_dir_for_opts = work_dir.clone();
|
||||||
assert!(os::mkdir_recursive(&work_dir, U_RWX));
|
assert!(os::mkdir_recursive(&work_dir, U_RWX));
|
||||||
debug!("Running: git init in %s", work_dir.to_str());
|
debug!("Running: git init in %s", work_dir.to_str());
|
||||||
let opts = run::ProcessOptions {
|
let ws = work_dir.to_str();
|
||||||
env: None,
|
run_git([~"init"], None, &work_dir_for_opts,
|
||||||
dir: Some(&work_dir_for_opts),
|
fmt!("Couldn't initialize git repository in %s", ws));
|
||||||
in_fd: None,
|
// Add stuff to the dir so that git tag succeeds
|
||||||
out_fd: None,
|
writeFile(&work_dir.push("README"), "");
|
||||||
err_fd: None
|
run_git([~"add", ~"README"], None, &work_dir_for_opts, fmt!("Couldn't add in %s", ws));
|
||||||
};
|
git_commit(&work_dir_for_opts, ~"whatever");
|
||||||
let mut prog = run::Process::new("git", [~"init"], opts);
|
tmp
|
||||||
let mut output = prog.finish_with_output();
|
|
||||||
if output.status == 0 {
|
|
||||||
// Add stuff to the dir so that git tag succeeds
|
|
||||||
writeFile(&work_dir.push("README"), "");
|
|
||||||
prog = run::Process::new("git", [~"add", ~"README"], opts);
|
|
||||||
output = prog.finish_with_output();
|
|
||||||
if output.status == 0 {
|
|
||||||
prog = run::Process::new("git", [~"commit", ~"-m", ~"whatever"], opts);
|
|
||||||
output = prog.finish_with_output();
|
|
||||||
if output.status == 0 {
|
|
||||||
tmp
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fail!("Couldn't commit in %s", work_dir.to_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fail!("Couldn't add in %s", work_dir.to_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fail!("Couldn't initialize git repository in %s", work_dir.to_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_all_and_commit(repo: &Path) {
|
fn add_all_and_commit(repo: &Path) {
|
||||||
@ -164,51 +152,20 @@ fn add_all_and_commit(repo: &Path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn git_commit(repo: &Path, msg: ~str) {
|
fn git_commit(repo: &Path, msg: ~str) {
|
||||||
let mut prog = run::Process::new("git", [~"commit", ~"-m", msg],
|
run_git([~"commit", ~"--author=tester <test@mozilla.com>", ~"-m", msg],
|
||||||
run::ProcessOptions { env: None,
|
None, repo, fmt!("Couldn't commit in %s", repo.to_str()));
|
||||||
dir: Some(repo),
|
|
||||||
in_fd: None,
|
|
||||||
out_fd: None,
|
|
||||||
err_fd: None
|
|
||||||
});
|
|
||||||
let output = prog.finish_with_output();
|
|
||||||
if output.status != 0 {
|
|
||||||
fail!("Couldn't commit in %s: output was %s", repo.to_str(),
|
|
||||||
str::from_bytes(output.output + output.error))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn git_add_all(repo: &Path) {
|
fn git_add_all(repo: &Path) {
|
||||||
let mut prog = run::Process::new("git", [~"add", ~"-A"],
|
run_git([~"add", ~"-A"], None, repo, fmt!("Couldn't add all files in %s", repo.to_str()));
|
||||||
run::ProcessOptions { env: None,
|
|
||||||
dir: Some(repo),
|
|
||||||
in_fd: None,
|
|
||||||
out_fd: None,
|
|
||||||
err_fd: None
|
|
||||||
});
|
|
||||||
let output = prog.finish_with_output();
|
|
||||||
if output.status != 0 {
|
|
||||||
fail!("Couldn't add all files in %s: output was %s",
|
|
||||||
repo.to_str(), str::from_bytes(output.output + output.error))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_git_tag(repo: &Path, tag: ~str) {
|
fn add_git_tag(repo: &Path, tag: ~str) {
|
||||||
assert!(repo.is_absolute());
|
assert!(repo.is_absolute());
|
||||||
git_add_all(repo);
|
git_add_all(repo);
|
||||||
git_commit(repo, ~"whatever");
|
git_commit(repo, ~"whatever");
|
||||||
let mut prog = run::Process::new("git", [~"tag", tag.clone()],
|
run_git([~"tag", tag.clone()], None, repo,
|
||||||
run::ProcessOptions { env: None,
|
fmt!("Couldn't add git tag %s in %s", tag, repo.to_str()));
|
||||||
dir: Some(repo),
|
|
||||||
in_fd: None,
|
|
||||||
out_fd: None,
|
|
||||||
err_fd: None
|
|
||||||
});
|
|
||||||
let output = prog.finish_with_output();
|
|
||||||
if output.status != 0 {
|
|
||||||
fail!("Couldn't add git tag %s in %s", tag, repo.to_str())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_rwx(p: &Path) -> bool {
|
fn is_rwx(p: &Path) -> bool {
|
||||||
@ -231,6 +188,25 @@ fn test_sysroot() -> Path {
|
|||||||
self_path.pop()
|
self_path.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the path to rustpkg
|
||||||
|
fn rustpkg_exec() -> Path {
|
||||||
|
// Ugh
|
||||||
|
let first_try = test_sysroot().push("lib").push("rustc")
|
||||||
|
.push(host_triple()).push("bin").push("rustpkg");
|
||||||
|
if is_executable(&first_try) {
|
||||||
|
first_try
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let second_try = test_sysroot().push("bin").push("rustpkg");
|
||||||
|
if is_executable(&second_try) {
|
||||||
|
second_try
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fail!("in rustpkg test, can't find an installed rustpkg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
|
fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
|
||||||
command_line_test_with_env(args, cwd, None)
|
command_line_test_with_env(args, cwd, None)
|
||||||
}
|
}
|
||||||
@ -240,8 +216,9 @@ fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
|
|||||||
/// Returns the process's output.
|
/// Returns the process's output.
|
||||||
fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~str)]>)
|
fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~str)]>)
|
||||||
-> ProcessOutput {
|
-> ProcessOutput {
|
||||||
let cmd = test_sysroot().push("bin").push("rustpkg").to_str();
|
let cmd = rustpkg_exec().to_str();
|
||||||
debug!("About to run command: %? %? in %s", cmd, args, cwd.to_str());
|
debug!("cd %s; %s %s",
|
||||||
|
cwd.to_str(), cmd, args.connect(" "));
|
||||||
assert!(os::path_is_dir(&*cwd));
|
assert!(os::path_is_dir(&*cwd));
|
||||||
let cwd = (*cwd).clone();
|
let cwd = (*cwd).clone();
|
||||||
let mut prog = run::Process::new(cmd, args, run::ProcessOptions {
|
let mut prog = run::Process::new(cmd, args, run::ProcessOptions {
|
||||||
@ -263,14 +240,15 @@ So tests that use this need to check the existence of a file
|
|||||||
to make sure the command succeeded
|
to make sure the command succeeded
|
||||||
*/
|
*/
|
||||||
if output.status != 0 {
|
if output.status != 0 {
|
||||||
fail!("Command %s %? failed with exit code %?",
|
fail!("Command %s %? failed with exit code %?; its output was {{{ %s }}}",
|
||||||
cmd, args, output.status);
|
cmd, args, output.status,
|
||||||
|
str::from_bytes(output.output) + str::from_bytes(output.error));
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_local_package(pkgid: &PkgId) -> Path {
|
fn create_local_package(pkgid: &PkgId) -> Path {
|
||||||
let parent_dir = mk_temp_workspace(&pkgid.local_path, &pkgid.version);
|
let parent_dir = mk_temp_workspace(&pkgid.path, &pkgid.version);
|
||||||
debug!("Created empty package dir for %s, returning %s", pkgid.to_str(), parent_dir.to_str());
|
debug!("Created empty package dir for %s, returning %s", pkgid.to_str(), parent_dir.to_str());
|
||||||
parent_dir.pop().pop()
|
parent_dir.pop().pop()
|
||||||
}
|
}
|
||||||
@ -327,26 +305,26 @@ fn create_local_package_with_custom_build_hook(pkgid: &PkgId,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_lib_exists(repo: &Path, short_name: &str, v: Version) {
|
fn assert_lib_exists(repo: &Path, short_name: &str, _v: Version) { // ??? version?
|
||||||
debug!("assert_lib_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
debug!("assert_lib_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
||||||
let lib = target_library_in_workspace(&(PkgId {
|
let lib = installed_library_in_workspace(short_name, repo);
|
||||||
version: v, ..PkgId::new(short_name, repo)}
|
debug!("assert_lib_exists: checking whether %? exists", lib);
|
||||||
), repo);
|
assert!(lib.is_some());
|
||||||
debug!("assert_lib_exists: checking whether %s exists", lib.to_str());
|
let libname = lib.get_ref();
|
||||||
assert!(os::path_exists(&lib));
|
assert!(os::path_exists(libname));
|
||||||
assert!(is_rwx(&lib));
|
assert!(is_rwx(libname));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_executable_exists(repo: &Path, short_name: &str) {
|
fn assert_executable_exists(repo: &Path, short_name: &str) {
|
||||||
debug!("assert_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
debug!("assert_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
||||||
let exec = target_executable_in_workspace(&PkgId::new(short_name, repo), repo);
|
let exec = target_executable_in_workspace(&PkgId::new(short_name), repo);
|
||||||
assert!(os::path_exists(&exec));
|
assert!(os::path_exists(&exec));
|
||||||
assert!(is_rwx(&exec));
|
assert!(is_rwx(&exec));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_built_executable_exists(repo: &Path, short_name: &str) {
|
fn assert_built_executable_exists(repo: &Path, short_name: &str) {
|
||||||
debug!("assert_built_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
debug!("assert_built_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
|
||||||
let exec = built_executable_in_workspace(&PkgId::new(short_name, repo),
|
let exec = built_executable_in_workspace(&PkgId::new(short_name),
|
||||||
repo).expect("assert_built_executable_exists failed");
|
repo).expect("assert_built_executable_exists failed");
|
||||||
assert!(os::path_exists(&exec));
|
assert!(os::path_exists(&exec));
|
||||||
assert!(is_rwx(&exec));
|
assert!(is_rwx(&exec));
|
||||||
@ -372,11 +350,11 @@ fn command_line_test_output_with_env(args: &[~str], env: ~[(~str, ~str)]) -> ~[~
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// assumes short_name and local_path are one and the same -- I should fix
|
// assumes short_name and path are one and the same -- I should fix
|
||||||
fn lib_output_file_name(workspace: &Path, parent: &str, short_name: &str) -> Path {
|
fn lib_output_file_name(workspace: &Path, parent: &str, short_name: &str) -> Path {
|
||||||
debug!("lib_output_file_name: given %s and parent %s and short name %s",
|
debug!("lib_output_file_name: given %s and parent %s and short name %s",
|
||||||
workspace.to_str(), parent, short_name);
|
workspace.to_str(), parent, short_name);
|
||||||
library_in_workspace(&normalize(RemotePath(Path(short_name))),
|
library_in_workspace(&Path(short_name),
|
||||||
short_name,
|
short_name,
|
||||||
Build,
|
Build,
|
||||||
workspace,
|
workspace,
|
||||||
@ -451,7 +429,7 @@ fn test_install_valid() {
|
|||||||
debug!("sysroot = %s", sysroot.to_str());
|
debug!("sysroot = %s", sysroot.to_str());
|
||||||
let ctxt = fake_ctxt(Some(@sysroot));
|
let ctxt = fake_ctxt(Some(@sysroot));
|
||||||
let temp_pkg_id = fake_pkg();
|
let temp_pkg_id = fake_pkg();
|
||||||
let temp_workspace = mk_temp_workspace(&temp_pkg_id.local_path, &NoVersion).pop().pop();
|
let temp_workspace = mk_temp_workspace(&temp_pkg_id.path, &NoVersion).pop().pop();
|
||||||
debug!("temp_workspace = %s", temp_workspace.to_str());
|
debug!("temp_workspace = %s", temp_workspace.to_str());
|
||||||
// should have test, bench, lib, and main
|
// should have test, bench, lib, and main
|
||||||
ctxt.install(&temp_workspace, &temp_pkg_id);
|
ctxt.install(&temp_workspace, &temp_pkg_id);
|
||||||
@ -504,7 +482,7 @@ fn test_install_git() {
|
|||||||
let sysroot = test_sysroot();
|
let sysroot = test_sysroot();
|
||||||
debug!("sysroot = %s", sysroot.to_str());
|
debug!("sysroot = %s", sysroot.to_str());
|
||||||
let temp_pkg_id = git_repo_pkg();
|
let temp_pkg_id = git_repo_pkg();
|
||||||
let repo = init_git_repo(&Path(temp_pkg_id.local_path.to_str()));
|
let repo = init_git_repo(&temp_pkg_id.path);
|
||||||
let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg");
|
let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg");
|
||||||
writeFile(&repo_subdir.push("main.rs"),
|
writeFile(&repo_subdir.push("main.rs"),
|
||||||
"fn main() { let _x = (); }");
|
"fn main() { let _x = (); }");
|
||||||
@ -517,9 +495,9 @@ fn test_install_git() {
|
|||||||
add_git_tag(&repo_subdir, ~"0.1"); // this has the effect of committing the files
|
add_git_tag(&repo_subdir, ~"0.1"); // this has the effect of committing the files
|
||||||
|
|
||||||
debug!("test_install_git: calling rustpkg install %s in %s",
|
debug!("test_install_git: calling rustpkg install %s in %s",
|
||||||
temp_pkg_id.local_path.to_str(), repo.to_str());
|
temp_pkg_id.path.to_str(), repo.to_str());
|
||||||
// should have test, bench, lib, and main
|
// should have test, bench, lib, and main
|
||||||
command_line_test([~"install", temp_pkg_id.local_path.to_str()], &repo);
|
command_line_test([~"install", temp_pkg_id.path.to_str()], &repo);
|
||||||
// Check that all files exist
|
// Check that all files exist
|
||||||
debug!("Checking for files in %s", repo.to_str());
|
debug!("Checking for files in %s", repo.to_str());
|
||||||
let exec = target_executable_in_workspace(&temp_pkg_id, &repo);
|
let exec = target_executable_in_workspace(&temp_pkg_id, &repo);
|
||||||
@ -563,18 +541,18 @@ fn test_package_ids_must_be_relative_path_like() {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let whatever = PkgId::new("foo", &os::getcwd());
|
let whatever = PkgId::new("foo");
|
||||||
|
|
||||||
assert_eq!(~"foo-0.1", whatever.to_str());
|
assert_eq!(~"foo-0.1", whatever.to_str());
|
||||||
assert!("github.com/catamorphism/test_pkg-0.1" ==
|
assert!("github.com/catamorphism/test-pkg-0.1" ==
|
||||||
PkgId::new("github.com/catamorphism/test-pkg", &os::getcwd()).to_str());
|
PkgId::new("github.com/catamorphism/test-pkg").to_str());
|
||||||
|
|
||||||
do cond.trap(|(p, e)| {
|
do cond.trap(|(p, e)| {
|
||||||
assert!("" == p.to_str());
|
assert!("" == p.to_str());
|
||||||
assert!("0-length pkgid" == e);
|
assert!("0-length pkgid" == e);
|
||||||
whatever.clone()
|
whatever.clone()
|
||||||
}).inside {
|
}).inside {
|
||||||
let x = PkgId::new("", &os::getcwd());
|
let x = PkgId::new("");
|
||||||
assert_eq!(~"foo-0.1", x.to_str());
|
assert_eq!(~"foo-0.1", x.to_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,8 +561,7 @@ fn test_package_ids_must_be_relative_path_like() {
|
|||||||
assert!("absolute pkgid" == e);
|
assert!("absolute pkgid" == e);
|
||||||
whatever.clone()
|
whatever.clone()
|
||||||
}).inside {
|
}).inside {
|
||||||
let z = PkgId::new(os::make_absolute(&Path("foo/bar/quux")).to_str(),
|
let z = PkgId::new(os::make_absolute(&Path("foo/bar/quux")).to_str());
|
||||||
&os::getcwd());
|
|
||||||
assert_eq!(~"foo-0.1", z.to_str());
|
assert_eq!(~"foo-0.1", z.to_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +584,7 @@ fn test_package_version() {
|
|||||||
"#[bench] pub fn f() { (); }");
|
"#[bench] pub fn f() { (); }");
|
||||||
add_git_tag(&repo_subdir, ~"0.4");
|
add_git_tag(&repo_subdir, ~"0.4");
|
||||||
|
|
||||||
let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version", &repo);
|
let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version");
|
||||||
match temp_pkg_id.version {
|
match temp_pkg_id.version {
|
||||||
ExactRevision(~"0.4") => (),
|
ExactRevision(~"0.4") => (),
|
||||||
_ => fail!(fmt!("test_package_version: package version was %?, expected Some(0.4)",
|
_ => fail!(fmt!("test_package_version: package version was %?, expected Some(0.4)",
|
||||||
@ -656,7 +633,7 @@ fn test_package_request_version() {
|
|||||||
}
|
}
|
||||||
None => false
|
None => false
|
||||||
});
|
});
|
||||||
let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version#0.3", &repo);
|
let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version#0.3");
|
||||||
assert!(target_executable_in_workspace(&temp_pkg_id, &repo.push(".rust"))
|
assert!(target_executable_in_workspace(&temp_pkg_id, &repo.push(".rust"))
|
||||||
== repo.push(".rust").push("bin").push("test_pkg_version"));
|
== repo.push(".rust").push("bin").push("test_pkg_version"));
|
||||||
|
|
||||||
@ -696,12 +673,12 @@ fn rustpkg_library_target() {
|
|||||||
|
|
||||||
add_git_tag(&package_dir, ~"1.0");
|
add_git_tag(&package_dir, ~"1.0");
|
||||||
command_line_test([~"install", ~"foo"], &foo_repo);
|
command_line_test([~"install", ~"foo"], &foo_repo);
|
||||||
assert_lib_exists(&foo_repo, "foo", ExactRevision(~"1.0"));
|
assert_lib_exists(&foo_repo.push(".rust"), "foo", ExactRevision(~"1.0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rustpkg_local_pkg() {
|
fn rustpkg_local_pkg() {
|
||||||
let dir = create_local_package(&PkgId::new("foo", &os::getcwd()));
|
let dir = create_local_package(&PkgId::new("foo"));
|
||||||
command_line_test([~"install", ~"foo"], &dir);
|
command_line_test([~"install", ~"foo"], &dir);
|
||||||
assert_executable_exists(&dir, "foo");
|
assert_executable_exists(&dir, "foo");
|
||||||
}
|
}
|
||||||
@ -711,7 +688,7 @@ fn rustpkg_local_pkg() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn package_script_with_default_build() {
|
fn package_script_with_default_build() {
|
||||||
let dir = create_local_package(&PkgId::new("fancy-lib", &os::getcwd()));
|
let dir = create_local_package(&PkgId::new("fancy-lib"));
|
||||||
debug!("dir = %s", dir.to_str());
|
debug!("dir = %s", dir.to_str());
|
||||||
let source = test_sysroot().pop().pop().pop().push("src").push("librustpkg").
|
let source = test_sysroot().pop().pop().pop().push("src").push("librustpkg").
|
||||||
push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs");
|
push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs");
|
||||||
@ -763,7 +740,7 @@ fn rustpkg_clean_no_arg() {
|
|||||||
command_line_test([~"build"], &package_dir);
|
command_line_test([~"build"], &package_dir);
|
||||||
assert_built_executable_exists(&tmp, "foo");
|
assert_built_executable_exists(&tmp, "foo");
|
||||||
command_line_test([~"clean"], &package_dir);
|
command_line_test([~"clean"], &package_dir);
|
||||||
assert!(!built_executable_in_workspace(&PkgId::new("foo", &package_dir),
|
assert!(!built_executable_in_workspace(&PkgId::new("foo"),
|
||||||
&tmp).map_default(false, |m| { os::path_exists(m) }));
|
&tmp).map_default(false, |m| { os::path_exists(m) }));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,14 +748,13 @@ fn rustpkg_clean_no_arg() {
|
|||||||
#[ignore (reason = "Specifying env doesn't work -- see #8028")]
|
#[ignore (reason = "Specifying env doesn't work -- see #8028")]
|
||||||
fn rust_path_test() {
|
fn rust_path_test() {
|
||||||
let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed");
|
let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed");
|
||||||
let dir = mk_workspace(&dir_for_path, &normalize(RemotePath(Path("foo"))), &NoVersion);
|
let dir = mk_workspace(&dir_for_path, &Path("foo"), &NoVersion);
|
||||||
debug!("dir = %s", dir.to_str());
|
debug!("dir = %s", dir.to_str());
|
||||||
writeFile(&dir.push("main.rs"), "fn main() { let _x = (); }");
|
writeFile(&dir.push("main.rs"), "fn main() { let _x = (); }");
|
||||||
|
|
||||||
let cwd = os::getcwd();
|
let cwd = os::getcwd();
|
||||||
debug!("cwd = %s", cwd.to_str());
|
debug!("cwd = %s", cwd.to_str());
|
||||||
debug!("Running command: cd %s; RUST_LOG=rustpkg RUST_PATH=%s rustpkg install foo",
|
// use command_line_test_with_env
|
||||||
cwd.to_str(), dir_for_path.to_str());
|
|
||||||
let mut prog = run::Process::new("rustpkg",
|
let mut prog = run::Process::new("rustpkg",
|
||||||
[~"install", ~"foo"],
|
[~"install", ~"foo"],
|
||||||
run::ProcessOptions { env: Some(&[(~"RUST_LOG",
|
run::ProcessOptions { env: Some(&[(~"RUST_LOG",
|
||||||
@ -830,39 +806,38 @@ fn rust_path_parse() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_list() {
|
fn test_list() {
|
||||||
let dir = mkdtemp(&os::tmpdir(), "test_list").expect("test_list failed");
|
let dir = mkdtemp(&os::tmpdir(), "test_list").expect("test_list failed");
|
||||||
let foo = PkgId::new("foo", &dir);
|
let foo = PkgId::new("foo");
|
||||||
create_local_package_in(&foo, &dir);
|
create_local_package_in(&foo, &dir);
|
||||||
let bar = PkgId::new("bar", &dir);
|
let bar = PkgId::new("bar");
|
||||||
create_local_package_in(&bar, &dir);
|
create_local_package_in(&bar, &dir);
|
||||||
let quux = PkgId::new("quux", &dir);
|
let quux = PkgId::new("quux");
|
||||||
create_local_package_in(&quux, &dir);
|
create_local_package_in(&quux, &dir);
|
||||||
|
|
||||||
// NOTE Not really great output, though...
|
// list doesn't output very much right now...
|
||||||
// NOTE do any tests need to be unignored?
|
|
||||||
command_line_test([~"install", ~"foo"], &dir);
|
command_line_test([~"install", ~"foo"], &dir);
|
||||||
let env_arg = ~[(~"RUST_PATH", dir.to_str())];
|
let env_arg = ~[(~"RUST_PATH", dir.to_str())];
|
||||||
debug!("RUST_PATH = %s", dir.to_str());
|
debug!("RUST_PATH = %s", dir.to_str());
|
||||||
let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
|
let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
|
||||||
assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
|
assert!(list_output.iter().any(|x| x.starts_with("foo")));
|
||||||
|
|
||||||
command_line_test([~"install", ~"bar"], &dir);
|
command_line_test([~"install", ~"bar"], &dir);
|
||||||
let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
|
let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
|
||||||
assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
|
assert!(list_output.iter().any(|x| x.starts_with("foo")));
|
||||||
assert!(list_output.iter().any(|x| x.starts_with("libbar_")));
|
assert!(list_output.iter().any(|x| x.starts_with("bar")));
|
||||||
|
|
||||||
command_line_test([~"install", ~"quux"], &dir);
|
command_line_test([~"install", ~"quux"], &dir);
|
||||||
let list_output = command_line_test_output_with_env([~"list"], env_arg);
|
let list_output = command_line_test_output_with_env([~"list"], env_arg);
|
||||||
assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
|
assert!(list_output.iter().any(|x| x.starts_with("foo")));
|
||||||
assert!(list_output.iter().any(|x| x.starts_with("libbar_")));
|
assert!(list_output.iter().any(|x| x.starts_with("bar")));
|
||||||
assert!(list_output.iter().any(|x| x.starts_with("libquux_")));
|
assert!(list_output.iter().any(|x| x.starts_with("quux")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn install_remove() {
|
fn install_remove() {
|
||||||
let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove");
|
let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove");
|
||||||
let foo = PkgId::new("foo", &dir);
|
let foo = PkgId::new("foo");
|
||||||
let bar = PkgId::new("bar", &dir);
|
let bar = PkgId::new("bar");
|
||||||
let quux = PkgId::new("quux", &dir);
|
let quux = PkgId::new("quux");
|
||||||
create_local_package_in(&foo, &dir);
|
create_local_package_in(&foo, &dir);
|
||||||
create_local_package_in(&bar, &dir);
|
create_local_package_in(&bar, &dir);
|
||||||
create_local_package_in(&quux, &dir);
|
create_local_package_in(&quux, &dir);
|
||||||
@ -887,7 +862,7 @@ fn install_check_duplicates() {
|
|||||||
// ("Is already installed -- doing nothing")
|
// ("Is already installed -- doing nothing")
|
||||||
// check invariant that there are no dups in the pkg database
|
// check invariant that there are no dups in the pkg database
|
||||||
let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove");
|
let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove");
|
||||||
let foo = PkgId::new("foo", &dir);
|
let foo = PkgId::new("foo");
|
||||||
create_local_package_in(&foo, &dir);
|
create_local_package_in(&foo, &dir);
|
||||||
|
|
||||||
command_line_test([~"install", ~"foo"], &dir);
|
command_line_test([~"install", ~"foo"], &dir);
|
||||||
@ -895,7 +870,7 @@ fn install_check_duplicates() {
|
|||||||
let mut contents = ~[];
|
let mut contents = ~[];
|
||||||
let check_dups = |p: &PkgId| {
|
let check_dups = |p: &PkgId| {
|
||||||
if contents.contains(p) {
|
if contents.contains(p) {
|
||||||
fail!("package %s appears in `list` output more than once", p.local_path.to_str());
|
fail!("package %s appears in `list` output more than once", p.path.to_str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
contents.push((*p).clone());
|
contents.push((*p).clone());
|
||||||
@ -908,7 +883,7 @@ fn install_check_duplicates() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore(reason = "Workcache not yet implemented -- see #7075")]
|
#[ignore(reason = "Workcache not yet implemented -- see #7075")]
|
||||||
fn no_rebuilding() {
|
fn no_rebuilding() {
|
||||||
let p_id = PkgId::new("foo", &os::getcwd());
|
let p_id = PkgId::new("foo");
|
||||||
let workspace = create_local_package(&p_id);
|
let workspace = create_local_package(&p_id);
|
||||||
command_line_test([~"build", ~"foo"], &workspace);
|
command_line_test([~"build", ~"foo"], &workspace);
|
||||||
let date = datestamp(&built_library_in_workspace(&p_id,
|
let date = datestamp(&built_library_in_workspace(&p_id,
|
||||||
@ -922,8 +897,8 @@ fn no_rebuilding() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore(reason = "Workcache not yet implemented -- see #7075")]
|
#[ignore(reason = "Workcache not yet implemented -- see #7075")]
|
||||||
fn no_rebuilding_dep() {
|
fn no_rebuilding_dep() {
|
||||||
let p_id = PkgId::new("foo", &os::getcwd());
|
let p_id = PkgId::new("foo");
|
||||||
let dep_id = PkgId::new("bar", &os::getcwd());
|
let dep_id = PkgId::new("bar");
|
||||||
let workspace = create_local_package_with_dep(&p_id, &dep_id);
|
let workspace = create_local_package_with_dep(&p_id, &dep_id);
|
||||||
command_line_test([~"build", ~"foo"], &workspace);
|
command_line_test([~"build", ~"foo"], &workspace);
|
||||||
let bar_date = datestamp(&lib_output_file_name(&workspace,
|
let bar_date = datestamp(&lib_output_file_name(&workspace,
|
||||||
@ -935,8 +910,8 @@ fn no_rebuilding_dep() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn do_rebuild_dep_dates_change() {
|
fn do_rebuild_dep_dates_change() {
|
||||||
let p_id = PkgId::new("foo", &os::getcwd());
|
let p_id = PkgId::new("foo");
|
||||||
let dep_id = PkgId::new("bar", &os::getcwd());
|
let dep_id = PkgId::new("bar");
|
||||||
let workspace = create_local_package_with_dep(&p_id, &dep_id);
|
let workspace = create_local_package_with_dep(&p_id, &dep_id);
|
||||||
command_line_test([~"build", ~"foo"], &workspace);
|
command_line_test([~"build", ~"foo"], &workspace);
|
||||||
let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
|
let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
|
||||||
@ -948,8 +923,8 @@ fn do_rebuild_dep_dates_change() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn do_rebuild_dep_only_contents_change() {
|
fn do_rebuild_dep_only_contents_change() {
|
||||||
let p_id = PkgId::new("foo", &os::getcwd());
|
let p_id = PkgId::new("foo");
|
||||||
let dep_id = PkgId::new("bar", &os::getcwd());
|
let dep_id = PkgId::new("bar");
|
||||||
let workspace = create_local_package_with_dep(&p_id, &dep_id);
|
let workspace = create_local_package_with_dep(&p_id, &dep_id);
|
||||||
command_line_test([~"build", ~"foo"], &workspace);
|
command_line_test([~"build", ~"foo"], &workspace);
|
||||||
let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
|
let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
|
||||||
@ -962,8 +937,8 @@ fn do_rebuild_dep_only_contents_change() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_versions() {
|
fn test_versions() {
|
||||||
let workspace = create_local_package(&PkgId::new("foo#0.1", &os::getcwd()));
|
let workspace = create_local_package(&PkgId::new("foo#0.1"));
|
||||||
create_local_package(&PkgId::new("foo#0.2", &os::getcwd()));
|
create_local_package(&PkgId::new("foo#0.2"));
|
||||||
command_line_test([~"install", ~"foo#0.1"], &workspace);
|
command_line_test([~"install", ~"foo#0.1"], &workspace);
|
||||||
let output = command_line_test_output([~"list"]);
|
let output = command_line_test_output([~"list"]);
|
||||||
// make sure output includes versions
|
// make sure output includes versions
|
||||||
@ -973,7 +948,7 @@ fn test_versions() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore(reason = "do not yet implemented")]
|
#[ignore(reason = "do not yet implemented")]
|
||||||
fn test_build_hooks() {
|
fn test_build_hooks() {
|
||||||
let workspace = create_local_package_with_custom_build_hook(&PkgId::new("foo", &os::getcwd()),
|
let workspace = create_local_package_with_custom_build_hook(&PkgId::new("foo"),
|
||||||
"frob");
|
"frob");
|
||||||
command_line_test([~"do", ~"foo", ~"frob"], &workspace);
|
command_line_test([~"do", ~"foo", ~"frob"], &workspace);
|
||||||
}
|
}
|
||||||
@ -983,7 +958,7 @@ fn test_build_hooks() {
|
|||||||
#[ignore(reason = "info not yet implemented")]
|
#[ignore(reason = "info not yet implemented")]
|
||||||
fn test_info() {
|
fn test_info() {
|
||||||
let expected_info = ~"package foo"; // fill in
|
let expected_info = ~"package foo"; // fill in
|
||||||
let workspace = create_local_package(&PkgId::new("foo", &os::getcwd()));
|
let workspace = create_local_package(&PkgId::new("foo"));
|
||||||
let output = command_line_test([~"info", ~"foo"], &workspace);
|
let output = command_line_test([~"info", ~"foo"], &workspace);
|
||||||
assert_eq!(str::from_bytes(output.output), expected_info);
|
assert_eq!(str::from_bytes(output.output), expected_info);
|
||||||
}
|
}
|
||||||
@ -992,7 +967,7 @@ fn test_info() {
|
|||||||
#[ignore(reason = "test not yet implemented")]
|
#[ignore(reason = "test not yet implemented")]
|
||||||
fn test_rustpkg_test() {
|
fn test_rustpkg_test() {
|
||||||
let expected_results = ~"1 out of 1 tests passed"; // fill in
|
let expected_results = ~"1 out of 1 tests passed"; // fill in
|
||||||
let workspace = create_local_package_with_test(&PkgId::new("foo", &os::getcwd()));
|
let workspace = create_local_package_with_test(&PkgId::new("foo"));
|
||||||
let output = command_line_test([~"test", ~"foo"], &workspace);
|
let output = command_line_test([~"test", ~"foo"], &workspace);
|
||||||
assert_eq!(str::from_bytes(output.output), expected_results);
|
assert_eq!(str::from_bytes(output.output), expected_results);
|
||||||
}
|
}
|
||||||
@ -1000,7 +975,7 @@ fn test_rustpkg_test() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[ignore(reason = "test not yet implemented")]
|
#[ignore(reason = "test not yet implemented")]
|
||||||
fn test_uninstall() {
|
fn test_uninstall() {
|
||||||
let workspace = create_local_package(&PkgId::new("foo", &os::getcwd()));
|
let workspace = create_local_package(&PkgId::new("foo"));
|
||||||
let _output = command_line_test([~"info", ~"foo"], &workspace);
|
let _output = command_line_test([~"info", ~"foo"], &workspace);
|
||||||
command_line_test([~"uninstall", ~"foo"], &workspace);
|
command_line_test([~"uninstall", ~"foo"], &workspace);
|
||||||
let output = command_line_test([~"list"], &workspace);
|
let output = command_line_test([~"list"], &workspace);
|
||||||
@ -1010,8 +985,8 @@ fn test_uninstall() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_non_numeric_tag() {
|
fn test_non_numeric_tag() {
|
||||||
let temp_pkg_id = git_repo_pkg();
|
let temp_pkg_id = git_repo_pkg();
|
||||||
let repo = init_git_repo(&Path(temp_pkg_id.local_path.to_str()));
|
let repo = init_git_repo(&temp_pkg_id.path);
|
||||||
let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg");
|
let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test-pkg");
|
||||||
writeFile(&repo_subdir.push("foo"), "foo");
|
writeFile(&repo_subdir.push("foo"), "foo");
|
||||||
writeFile(&repo_subdir.push("lib.rs"),
|
writeFile(&repo_subdir.push("lib.rs"),
|
||||||
"pub fn f() { let _x = (); }");
|
"pub fn f() { let _x = (); }");
|
||||||
@ -1021,13 +996,70 @@ fn test_non_numeric_tag() {
|
|||||||
writeFile(&repo_subdir.push("not_on_testbranch_only"), "bye bye");
|
writeFile(&repo_subdir.push("not_on_testbranch_only"), "bye bye");
|
||||||
add_all_and_commit(&repo_subdir);
|
add_all_and_commit(&repo_subdir);
|
||||||
|
|
||||||
|
command_line_test([~"install", fmt!("%s#testbranch", temp_pkg_id.path.to_str())], &repo);
|
||||||
command_line_test([~"install", fmt!("%s#testbranch", temp_pkg_id.remote_path.to_str())],
|
|
||||||
&repo);
|
|
||||||
let file1 = repo.push_many(["mockgithub.com", "catamorphism",
|
let file1 = repo.push_many(["mockgithub.com", "catamorphism",
|
||||||
"test_pkg", "testbranch_only"]);
|
"test-pkg", "testbranch_only"]);
|
||||||
let file2 = repo.push_many(["mockgithub.com", "catamorphism", "test_pkg",
|
let file2 = repo.push_many(["mockgithub.com", "catamorphism", "test-pkg",
|
||||||
"master_only"]);
|
"master_only"]);
|
||||||
assert!(os::path_exists(&file1));
|
assert!(os::path_exists(&file1));
|
||||||
assert!(!os::path_exists(&file2));
|
assert!(!os::path_exists(&file2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_extern_mod() {
|
||||||
|
let dir = mkdtemp(&os::tmpdir(), "test_extern_mod").expect("test_extern_mod");
|
||||||
|
let main_file = dir.push("main.rs");
|
||||||
|
let lib_depend_dir = mkdtemp(&os::tmpdir(), "foo").expect("test_extern_mod");
|
||||||
|
let aux_dir = lib_depend_dir.push_many(["src", "mockgithub.com", "catamorphism", "test_pkg"]);
|
||||||
|
assert!(os::mkdir_recursive(&aux_dir, U_RWX));
|
||||||
|
let aux_pkg_file = aux_dir.push("lib.rs");
|
||||||
|
|
||||||
|
writeFile(&aux_pkg_file, "pub mod bar { pub fn assert_true() { assert!(true); } }\n");
|
||||||
|
assert!(os::path_exists(&aux_pkg_file));
|
||||||
|
|
||||||
|
writeFile(&main_file,
|
||||||
|
"extern mod test = \"mockgithub.com/catamorphism/test_pkg\";\nuse test::bar;\
|
||||||
|
fn main() { bar::assert_true(); }\n");
|
||||||
|
|
||||||
|
command_line_test([~"install", ~"mockgithub.com/catamorphism/test_pkg"], &lib_depend_dir);
|
||||||
|
|
||||||
|
let exec_file = dir.push("out");
|
||||||
|
// Be sure to extend the existing environment
|
||||||
|
let env = Some([(~"RUST_PATH", lib_depend_dir.to_str())] + os::env());
|
||||||
|
let rustpkg_exec = rustpkg_exec();
|
||||||
|
let rustc = rustpkg_exec.with_filename("rustc");
|
||||||
|
debug!("RUST_PATH=%s %s %s \n --sysroot %s -o %s",
|
||||||
|
lib_depend_dir.to_str(),
|
||||||
|
rustc.to_str(),
|
||||||
|
main_file.to_str(),
|
||||||
|
test_sysroot().to_str(),
|
||||||
|
exec_file.to_str());
|
||||||
|
|
||||||
|
let mut prog = run::Process::new(rustc.to_str(), [main_file.to_str(),
|
||||||
|
~"--sysroot", test_sysroot().to_str(),
|
||||||
|
~"-o", exec_file.to_str()],
|
||||||
|
run::ProcessOptions {
|
||||||
|
env: env.map(|v| v.slice(0, v.len())),
|
||||||
|
dir: Some(&dir),
|
||||||
|
in_fd: None,
|
||||||
|
out_fd: None,
|
||||||
|
err_fd: None
|
||||||
|
});
|
||||||
|
let outp = prog.finish_with_output();
|
||||||
|
if outp.status != 0 {
|
||||||
|
fail!("output was %s, error was %s",
|
||||||
|
str::from_bytes(outp.output),
|
||||||
|
str::from_bytes(outp.error));
|
||||||
|
}
|
||||||
|
assert!(os::path_exists(&exec_file) && is_executable(&exec_file));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if p exists and is executable
|
||||||
|
fn is_executable(p: &Path) -> bool {
|
||||||
|
use std::libc::consts::os::posix88::{S_IXUSR};
|
||||||
|
|
||||||
|
match p.get_mode() {
|
||||||
|
None => false,
|
||||||
|
Some(mode) => mode & S_IXUSR as uint == S_IXUSR as uint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,9 +8,8 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::{os, result};
|
use std::os;
|
||||||
use rustc::driver::{driver, session};
|
use rustc::driver::{driver, session};
|
||||||
use rustc::metadata::filesearch;
|
|
||||||
use extra::getopts::groups::getopts;
|
use extra::getopts::groups::getopts;
|
||||||
use syntax::ast_util::*;
|
use syntax::ast_util::*;
|
||||||
use syntax::codemap::{dummy_sp, spanned};
|
use syntax::codemap::{dummy_sp, spanned};
|
||||||
@ -19,10 +18,10 @@ use syntax::{ast, attr, codemap, diagnostic, fold};
|
|||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr::AttrMetaMethods;
|
||||||
use rustc::back::link::output_type_exe;
|
use rustc::back::link::output_type_exe;
|
||||||
use rustc::driver::session::{lib_crate, bin_crate};
|
use rustc::driver::session::{lib_crate, bin_crate};
|
||||||
use context::Ctx;
|
use context::{Ctx, in_target};
|
||||||
use package_id::PkgId;
|
use package_id::PkgId;
|
||||||
use search::find_library_in_search_path;
|
use search::find_library_in_search_path;
|
||||||
use path_util::target_library_in_workspace;
|
use path_util::{target_library_in_workspace, U_RWX};
|
||||||
pub use target::{OutputType, Main, Lib, Bench, Test};
|
pub use target::{OutputType, Main, Lib, Bench, Test};
|
||||||
|
|
||||||
// It would be nice to have the list of commands in just one place -- for example,
|
// It would be nice to have the list of commands in just one place -- for example,
|
||||||
@ -47,13 +46,6 @@ impl ToStr for Pkg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root() -> Path {
|
|
||||||
match filesearch::get_rustpkg_root() {
|
|
||||||
result::Ok(path) => path,
|
|
||||||
result::Err(err) => fail!(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_cmd(cmd: &str) -> bool {
|
pub fn is_cmd(cmd: &str) -> bool {
|
||||||
COMMANDS.iter().any(|&c| c == cmd)
|
COMMANDS.iter().any(|&c| c == cmd)
|
||||||
}
|
}
|
||||||
@ -162,25 +154,25 @@ pub fn ready_crate(sess: session::Session,
|
|||||||
pub fn compile_input(ctxt: &Ctx,
|
pub fn compile_input(ctxt: &Ctx,
|
||||||
pkg_id: &PkgId,
|
pkg_id: &PkgId,
|
||||||
in_file: &Path,
|
in_file: &Path,
|
||||||
out_dir: &Path,
|
workspace: &Path,
|
||||||
flags: &[~str],
|
flags: &[~str],
|
||||||
cfgs: &[~str],
|
cfgs: &[~str],
|
||||||
opt: bool,
|
opt: bool,
|
||||||
what: OutputType) -> bool {
|
what: OutputType) -> bool {
|
||||||
|
|
||||||
let workspace = out_dir.pop().pop();
|
|
||||||
|
|
||||||
assert!(in_file.components.len() > 1);
|
assert!(in_file.components.len() > 1);
|
||||||
let input = driver::file_input((*in_file).clone());
|
let input = driver::file_input((*in_file).clone());
|
||||||
debug!("compile_input: %s / %?", in_file.to_str(), what);
|
debug!("compile_input: %s / %?", in_file.to_str(), what);
|
||||||
// tjc: by default, use the package ID name as the link name
|
// tjc: by default, use the package ID name as the link name
|
||||||
// not sure if we should support anything else
|
// not sure if we should support anything else
|
||||||
|
|
||||||
|
let out_dir = workspace.push("build").push_rel(&pkg_id.path);
|
||||||
|
|
||||||
let binary = os::args()[0].to_managed();
|
let binary = os::args()[0].to_managed();
|
||||||
|
|
||||||
debug!("flags: %s", flags.connect(" "));
|
debug!("flags: %s", flags.connect(" "));
|
||||||
debug!("cfgs: %s", cfgs.connect(" "));
|
debug!("cfgs: %s", cfgs.connect(" "));
|
||||||
debug!("compile_input's sysroot = %?", ctxt.sysroot_opt);
|
debug!("out_dir = %s", out_dir.to_str());
|
||||||
|
|
||||||
let crate_type = match what {
|
let crate_type = match what {
|
||||||
Lib => lib_crate,
|
Lib => lib_crate,
|
||||||
@ -196,12 +188,22 @@ pub fn compile_input(ctxt: &Ctx,
|
|||||||
+ flags
|
+ flags
|
||||||
+ cfgs.flat_map(|c| { ~[~"--cfg", (*c).clone()] }),
|
+ cfgs.flat_map(|c| { ~[~"--cfg", (*c).clone()] }),
|
||||||
driver::optgroups()).unwrap();
|
driver::optgroups()).unwrap();
|
||||||
|
// Hack so that rustpkg can run either out of a rustc target dir,
|
||||||
|
// or the host dir
|
||||||
|
let sysroot_to_use = if !in_target(ctxt.sysroot_opt) {
|
||||||
|
ctxt.sysroot_opt
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctxt.sysroot_opt.map(|p| { @p.pop().pop().pop() })
|
||||||
|
};
|
||||||
|
debug!("compile_input's sysroot = %?", ctxt.sysroot_opt_str());
|
||||||
|
debug!("sysroot_to_use = %?", sysroot_to_use);
|
||||||
let options = @session::options {
|
let options = @session::options {
|
||||||
crate_type: crate_type,
|
crate_type: crate_type,
|
||||||
optimize: if opt { session::Aggressive } else { session::No },
|
optimize: if opt { session::Aggressive } else { session::No },
|
||||||
test: what == Test || what == Bench,
|
test: what == Test || what == Bench,
|
||||||
maybe_sysroot: ctxt.sysroot_opt,
|
maybe_sysroot: sysroot_to_use,
|
||||||
addl_lib_search_paths: @mut (~[(*out_dir).clone()]),
|
addl_lib_search_paths: @mut (~[out_dir.clone()]),
|
||||||
// output_type should be conditional
|
// output_type should be conditional
|
||||||
output_type: output_type_exe, // Use this to get a library? That's weird
|
output_type: output_type_exe, // Use this to get a library? That's weird
|
||||||
.. (*driver::build_session_options(binary, &matches, diagnostic::emit)).clone()
|
.. (*driver::build_session_options(binary, &matches, diagnostic::emit)).clone()
|
||||||
@ -211,7 +213,12 @@ pub fn compile_input(ctxt: &Ctx,
|
|||||||
// Make sure all the library directories actually exist, since the linker will complain
|
// Make sure all the library directories actually exist, since the linker will complain
|
||||||
// otherwise
|
// otherwise
|
||||||
for p in addl_lib_search_paths.iter() {
|
for p in addl_lib_search_paths.iter() {
|
||||||
assert!(os::path_is_dir(p));
|
if os::path_exists(p) {
|
||||||
|
assert!(os::path_is_dir(p));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert!(os::mkdir_recursive(p, U_RWX));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sess = driver::build_session(options, diagnostic::emit);
|
let sess = driver::build_session(options, diagnostic::emit);
|
||||||
@ -224,35 +231,44 @@ pub fn compile_input(ctxt: &Ctx,
|
|||||||
|
|
||||||
// Not really right. Should search other workspaces too, and the installed
|
// Not really right. Should search other workspaces too, and the installed
|
||||||
// database (which doesn't exist yet)
|
// database (which doesn't exist yet)
|
||||||
find_and_install_dependencies(ctxt, sess, &workspace, crate,
|
find_and_install_dependencies(ctxt, sess, workspace, crate,
|
||||||
|p| {
|
|p| {
|
||||||
debug!("a dependency: %s", p.to_str());
|
debug!("a dependency: %s", p.to_str());
|
||||||
// Pass the directory containing a dependency
|
// Pass the directory containing a dependency
|
||||||
// as an additional lib search path
|
// as an additional lib search path
|
||||||
addl_lib_search_paths.push(p);
|
if !addl_lib_search_paths.contains(&p) {
|
||||||
|
// Might be inefficient, but this set probably
|
||||||
|
// won't get too large -- tjc
|
||||||
|
addl_lib_search_paths.push(p);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Inject the link attributes so we get the right package name and version
|
// Inject the link attributes so we get the right package name and version
|
||||||
if attr::find_linkage_metas(crate.attrs).is_empty() {
|
if attr::find_linkage_metas(crate.attrs).is_empty() {
|
||||||
let short_name_to_use = match what {
|
let name_to_use = match what {
|
||||||
Test => fmt!("%stest", pkg_id.short_name),
|
Test => fmt!("%stest", pkg_id.short_name).to_managed(),
|
||||||
Bench => fmt!("%sbench", pkg_id.short_name),
|
Bench => fmt!("%sbench", pkg_id.short_name).to_managed(),
|
||||||
_ => pkg_id.short_name.clone()
|
_ => pkg_id.short_name.to_managed()
|
||||||
};
|
};
|
||||||
debug!("Injecting link name: %s", short_name_to_use);
|
debug!("Injecting link name: %s", name_to_use);
|
||||||
let link_options =
|
let link_options =
|
||||||
~[attr::mk_name_value_item_str(@"name", short_name_to_use.to_managed()),
|
~[attr::mk_name_value_item_str(@"name", name_to_use),
|
||||||
attr::mk_name_value_item_str(@"vers", pkg_id.version.to_str().to_managed())];
|
attr::mk_name_value_item_str(@"vers", pkg_id.version.to_str().to_managed())] +
|
||||||
|
if pkg_id.is_complex() {
|
||||||
|
~[attr::mk_name_value_item_str(@"package_id",
|
||||||
|
pkg_id.path.to_str().to_managed())]
|
||||||
|
} else { ~[] };
|
||||||
|
|
||||||
|
debug!("link options: %?", link_options);
|
||||||
crate = @ast::Crate {
|
crate = @ast::Crate {
|
||||||
attrs: ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))],
|
attrs: ~[attr::mk_attr(attr::mk_list_item(@"link", link_options))],
|
||||||
.. (*crate).clone()
|
.. (*crate).clone()
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("calling compile_crate_from_input, out_dir = %s,
|
debug!("calling compile_crate_from_input, workspace = %s,
|
||||||
building_library = %?", out_dir.to_str(), sess.building_library);
|
building_library = %?", out_dir.to_str(), sess.building_library);
|
||||||
compile_crate_from_input(&input, out_dir, sess, crate);
|
compile_crate_from_input(&input, &out_dir, sess, crate);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,17 +278,22 @@ pub fn compile_input(ctxt: &Ctx,
|
|||||||
// call compile_upto and return the crate
|
// call compile_upto and return the crate
|
||||||
// also, too many arguments
|
// also, too many arguments
|
||||||
pub fn compile_crate_from_input(input: &driver::input,
|
pub fn compile_crate_from_input(input: &driver::input,
|
||||||
build_dir: &Path,
|
// should be of the form <workspace>/build/<pkg id's path>
|
||||||
|
out_dir: &Path,
|
||||||
sess: session::Session,
|
sess: session::Session,
|
||||||
crate: @ast::Crate) {
|
crate: @ast::Crate) {
|
||||||
debug!("Calling build_output_filenames with %s, building library? %?",
|
debug!("Calling build_output_filenames with %s, building library? %?",
|
||||||
build_dir.to_str(), sess.building_library);
|
out_dir.to_str(), sess.building_library);
|
||||||
|
|
||||||
// bad copy
|
// bad copy
|
||||||
let outputs = driver::build_output_filenames(input, &Some((*build_dir).clone()), &None,
|
debug!("out_dir = %s", out_dir.to_str());
|
||||||
|
let outputs = driver::build_output_filenames(input, &Some(out_dir.clone()), &None,
|
||||||
crate.attrs, sess);
|
crate.attrs, sess);
|
||||||
|
|
||||||
debug!("Outputs are %? and output type = %?", outputs, sess.opts.output_type);
|
debug!("Outputs are out_filename: %s and obj_filename: %s and output type = %?",
|
||||||
|
outputs.out_filename.to_str(),
|
||||||
|
outputs.obj_filename.to_str(),
|
||||||
|
sess.opts.output_type);
|
||||||
debug!("additional libraries:");
|
debug!("additional libraries:");
|
||||||
for lib in sess.opts.addl_lib_search_paths.iter() {
|
for lib in sess.opts.addl_lib_search_paths.iter() {
|
||||||
debug!("an additional library: %s", lib.to_str());
|
debug!("an additional library: %s", lib.to_str());
|
||||||
@ -298,15 +319,15 @@ pub fn exe_suffix() -> ~str { ~"" }
|
|||||||
// Called by build_crates
|
// Called by build_crates
|
||||||
// FIXME (#4432): Use workcache to only compile when needed
|
// FIXME (#4432): Use workcache to only compile when needed
|
||||||
pub fn compile_crate(ctxt: &Ctx, pkg_id: &PkgId,
|
pub fn compile_crate(ctxt: &Ctx, pkg_id: &PkgId,
|
||||||
crate: &Path, dir: &Path,
|
crate: &Path, workspace: &Path,
|
||||||
flags: &[~str], cfgs: &[~str], opt: bool,
|
flags: &[~str], cfgs: &[~str], opt: bool,
|
||||||
what: OutputType) -> bool {
|
what: OutputType) -> bool {
|
||||||
debug!("compile_crate: crate=%s, dir=%s", crate.to_str(), dir.to_str());
|
debug!("compile_crate: crate=%s, workspace=%s", crate.to_str(), workspace.to_str());
|
||||||
debug!("compile_crate: short_name = %s, flags =...", pkg_id.to_str());
|
debug!("compile_crate: short_name = %s, flags =...", pkg_id.to_str());
|
||||||
for fl in flags.iter() {
|
for fl in flags.iter() {
|
||||||
debug!("+++ %s", *fl);
|
debug!("+++ %s", *fl);
|
||||||
}
|
}
|
||||||
compile_input(ctxt, pkg_id, crate, dir, flags, cfgs, opt, what)
|
compile_input(ctxt, pkg_id, crate, workspace, flags, cfgs, opt, what)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -327,19 +348,20 @@ pub fn find_and_install_dependencies(ctxt: &Ctx,
|
|||||||
debug!("A view item!");
|
debug!("A view item!");
|
||||||
match vi.node {
|
match vi.node {
|
||||||
// ignore metadata, I guess
|
// ignore metadata, I guess
|
||||||
ast::view_item_extern_mod(lib_ident, _, _) => {
|
ast::view_item_extern_mod(lib_ident, path_opt, _, _) => {
|
||||||
match my_ctxt.sysroot_opt {
|
match my_ctxt.sysroot_opt {
|
||||||
Some(ref x) => debug!("sysroot: %s", x.to_str()),
|
Some(ref x) => debug!("*** sysroot: %s", x.to_str()),
|
||||||
None => debug!("No sysroot given")
|
None => debug!("No sysroot given")
|
||||||
};
|
};
|
||||||
let lib_name = sess.str_of(lib_ident);
|
let lib_name = match path_opt { // ???
|
||||||
|
Some(p) => p, None => sess.str_of(lib_ident) };
|
||||||
match find_library_in_search_path(my_ctxt.sysroot_opt, lib_name) {
|
match find_library_in_search_path(my_ctxt.sysroot_opt, lib_name) {
|
||||||
Some(installed_path) => {
|
Some(installed_path) => {
|
||||||
debug!("It exists: %s", installed_path.to_str());
|
debug!("It exists: %s", installed_path.to_str());
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Try to install it
|
// Try to install it
|
||||||
let pkg_id = PkgId::new(lib_name, &os::getcwd());
|
let pkg_id = PkgId::new(lib_name);
|
||||||
my_ctxt.install(&my_workspace, &pkg_id);
|
my_ctxt.install(&my_workspace, &pkg_id);
|
||||||
// Also, add an additional search path
|
// Also, add an additional search path
|
||||||
debug!("let installed_path...")
|
debug!("let installed_path...")
|
||||||
|
@ -15,8 +15,8 @@ extern mod std;
|
|||||||
|
|
||||||
use extra::semver;
|
use extra::semver;
|
||||||
use std::{char, os, result, run, str};
|
use std::{char, os, result, run, str};
|
||||||
use package_path::RemotePath;
|
|
||||||
use extra::tempfile::mkdtemp;
|
use extra::tempfile::mkdtemp;
|
||||||
|
use path_util::rust_path;
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub enum Version {
|
pub enum Version {
|
||||||
@ -92,19 +92,22 @@ pub fn parse_vers(vers: ~str) -> result::Result<semver::Version, ~str> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `local_path` is a git repo, and the most recent tag in that repo denotes a version,
|
/// If `local_path` is a git repo in the RUST_PATH, and the most recent tag
|
||||||
/// return it; otherwise, `None`
|
/// in that repo denotes a version, return it; otherwise, `None`
|
||||||
pub fn try_getting_local_version(local_path: &Path) -> Option<Version> {
|
pub fn try_getting_local_version(local_path: &Path) -> Option<Version> {
|
||||||
debug!("in try_getting_local_version");
|
let rustpath = rust_path();
|
||||||
let outp = run::process_output("git",
|
for rp in rustpath.iter() {
|
||||||
|
let local_path = rp.push_rel(local_path);
|
||||||
|
debug!("in try_getting_local_version");
|
||||||
|
let outp = run::process_output("git",
|
||||||
[fmt!("--git-dir=%s", local_path.push(".git").to_str()),
|
[fmt!("--git-dir=%s", local_path.push(".git").to_str()),
|
||||||
~"tag", ~"-l"]);
|
~"tag", ~"-l"]);
|
||||||
|
|
||||||
debug!("git --git-dir=%s tag -l ~~~> %?", local_path.push(".git").to_str(), outp.status);
|
debug!("git --git-dir=%s tag -l ~~~> %?", local_path.push(".git").to_str(), outp.status);
|
||||||
|
|
||||||
if outp.status != 0 {
|
if outp.status != 0 {
|
||||||
return None;
|
loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut output = None;
|
let mut output = None;
|
||||||
let output_text = str::from_bytes(outp.output);
|
let output_text = str::from_bytes(outp.output);
|
||||||
@ -112,14 +115,19 @@ pub fn try_getting_local_version(local_path: &Path) -> Option<Version> {
|
|||||||
if !l.is_whitespace() {
|
if !l.is_whitespace() {
|
||||||
output = Some(l);
|
output = Some(l);
|
||||||
}
|
}
|
||||||
|
match output.chain(try_parsing_version) {
|
||||||
|
Some(v) => return Some(v),
|
||||||
|
None => ()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
output.chain(try_parsing_version)
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `remote_path` refers to a git repo that can be downloaded,
|
/// If `remote_path` refers to a git repo that can be downloaded,
|
||||||
/// and the most recent tag in that repo denotes a version, return it;
|
/// and the most recent tag in that repo denotes a version, return it;
|
||||||
/// otherwise, `None`
|
/// otherwise, `None`
|
||||||
pub fn try_getting_version(remote_path: &RemotePath) -> Option<Version> {
|
pub fn try_getting_version(remote_path: &Path) -> Option<Version> {
|
||||||
debug!("try_getting_version: %s", remote_path.to_str());
|
debug!("try_getting_version: %s", remote_path.to_str());
|
||||||
if is_url_like(remote_path) {
|
if is_url_like(remote_path) {
|
||||||
debug!("Trying to fetch its sources..");
|
debug!("Trying to fetch its sources..");
|
||||||
@ -190,7 +198,7 @@ fn try_parsing_version(s: &str) -> Option<Version> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Just an approximation
|
/// Just an approximation
|
||||||
fn is_url_like(p: &RemotePath) -> bool {
|
fn is_url_like(p: &Path) -> bool {
|
||||||
let str = p.to_str();
|
let str = p.to_str();
|
||||||
str.split_iter('/').len_() > 2
|
str.split_iter('/').len_() > 2
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,11 @@
|
|||||||
|
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use path_util::{rust_path, workspace_contains_package_id};
|
use path_util::workspace_contains_package_id;
|
||||||
use package_id::PkgId;
|
use package_id::PkgId;
|
||||||
|
|
||||||
|
use rustc::metadata::filesearch::rust_path;
|
||||||
|
|
||||||
pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> bool {
|
pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> bool {
|
||||||
// Using the RUST_PATH, find workspaces that contain
|
// Using the RUST_PATH, find workspaces that contain
|
||||||
// this package ID
|
// this package ID
|
||||||
@ -23,7 +25,7 @@ pub fn each_pkg_parent_workspace(pkgid: &PkgId, action: &fn(&Path) -> bool) -> b
|
|||||||
// tjc: make this a condition
|
// tjc: make this a condition
|
||||||
fail!("Package %s not found in any of \
|
fail!("Package %s not found in any of \
|
||||||
the following workspaces: %s",
|
the following workspaces: %s",
|
||||||
pkgid.remote_path.to_str(),
|
pkgid.path.to_str(),
|
||||||
rust_path().to_str());
|
rust_path().to_str());
|
||||||
}
|
}
|
||||||
for ws in workspaces.iter() {
|
for ws in workspaces.iter() {
|
||||||
@ -58,5 +60,5 @@ pub fn cwd_to_workspace() -> (Path, PkgId) {
|
|||||||
let ws = cwd.pop().pop();
|
let ws = cwd.pop().pop();
|
||||||
let cwd_ = cwd.clone();
|
let cwd_ = cwd.clone();
|
||||||
let pkgid = cwd_.components.last().to_str();
|
let pkgid = cwd_.components.last().to_str();
|
||||||
(ws, PkgId::new(pkgid, &cwd))
|
(ws, PkgId::new(pkgid))
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,14 @@ Cross-platform file path handling
|
|||||||
use clone::Clone;
|
use clone::Clone;
|
||||||
use container::Container;
|
use container::Container;
|
||||||
use cmp::Eq;
|
use cmp::Eq;
|
||||||
use iterator::{Iterator, IteratorUtil};
|
use iterator::{Iterator, IteratorUtil, range};
|
||||||
use libc;
|
use libc;
|
||||||
|
use num;
|
||||||
use option::{None, Option, Some};
|
use option::{None, Option, Some};
|
||||||
use str::{OwnedStr, Str, StrSlice, StrVector};
|
use str::{OwnedStr, Str, StrSlice, StrVector};
|
||||||
use to_str::ToStr;
|
use to_str::ToStr;
|
||||||
use ascii::{AsciiCast, AsciiStr};
|
use ascii::{AsciiCast, AsciiStr};
|
||||||
use vec::{OwnedVector, ImmutableVector};
|
use vec::{OwnedVector, ImmutableVector, OwnedCopyableVector};
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub use Path = self::WindowsPath;
|
pub use Path = self::WindowsPath;
|
||||||
@ -124,6 +125,43 @@ pub trait GenericPath {
|
|||||||
|
|
||||||
/// True if `self` is an ancestor of `other`. See `test_is_ancestor_of` for examples
|
/// True if `self` is an ancestor of `other`. See `test_is_ancestor_of` for examples
|
||||||
fn is_ancestor_of(&self, (&Self)) -> bool;
|
fn is_ancestor_of(&self, (&Self)) -> bool;
|
||||||
|
|
||||||
|
/// Find the relative path from one file to another
|
||||||
|
fn get_relative_to(&self, abs2: (&Self)) -> Self {
|
||||||
|
assert!(self.is_absolute());
|
||||||
|
assert!(abs2.is_absolute());
|
||||||
|
let abs1 = self.normalize();
|
||||||
|
let abs2 = abs2.normalize();
|
||||||
|
|
||||||
|
let split1: &[~str] = abs1.components();
|
||||||
|
let split2: &[~str] = abs2.components();
|
||||||
|
let len1 = split1.len();
|
||||||
|
let len2 = split2.len();
|
||||||
|
assert!(len1 > 0);
|
||||||
|
assert!(len2 > 0);
|
||||||
|
|
||||||
|
let max_common_path = num::min(len1, len2) - 1;
|
||||||
|
let mut start_idx = 0;
|
||||||
|
while start_idx < max_common_path
|
||||||
|
&& split1[start_idx] == split2[start_idx] {
|
||||||
|
start_idx += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut path: ~[~str] = ~[];
|
||||||
|
for _ in range(start_idx, len1 - 1) { path.push(~".."); };
|
||||||
|
|
||||||
|
path.push_all(split2.slice(start_idx, len2 - 1));
|
||||||
|
|
||||||
|
let mut result: Self = GenericPath::from_str(".");
|
||||||
|
if !path.is_empty() {
|
||||||
|
// Without this type hint, the typechecker doesn't seem to like it
|
||||||
|
let p: Self = GenericPath::from_str("");
|
||||||
|
result = p.push_many(path);
|
||||||
|
};
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn components(self) -> ~[~str];
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@ -703,6 +741,7 @@ impl GenericPath for PosixPath {
|
|||||||
self.is_ancestor_of(&other.pop()))
|
self.is_ancestor_of(&other.pop()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn components(self) -> ~[~str] { self.components }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -985,6 +1024,8 @@ impl GenericPath for WindowsPath {
|
|||||||
(!other.components.is_empty() && !(self.components.is_empty() && !self.is_absolute) &&
|
(!other.components.is_empty() && !(self.components.is_empty() && !self.is_absolute) &&
|
||||||
self.is_ancestor_of(&other.pop()))
|
self.is_ancestor_of(&other.pop()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn components(self) -> ~[~str] { self.components }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn normalize(components: &[~str]) -> ~[~str] {
|
pub fn normalize(components: &[~str]) -> ~[~str] {
|
||||||
@ -1341,4 +1382,124 @@ mod tests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_to1() {
|
||||||
|
let p1 = PosixPath("/usr/bin/rustc");
|
||||||
|
let p2 = PosixPath("/usr/lib/mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, PosixPath("../lib"));
|
||||||
|
|
||||||
|
let p1 = WindowsPath("C:\\usr\\bin\\rustc");
|
||||||
|
let p2 = WindowsPath("C:\\usr\\lib\\mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, WindowsPath("..\\lib"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_to2() {
|
||||||
|
let p1 = PosixPath("/usr/bin/rustc");
|
||||||
|
let p2 = PosixPath("/usr/bin/../lib/mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, PosixPath("../lib"));
|
||||||
|
|
||||||
|
let p1 = WindowsPath("C:\\usr\\bin\\rustc");
|
||||||
|
let p2 = WindowsPath("C:\\usr\\bin\\..\\lib\\mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, WindowsPath("..\\lib"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_to3() {
|
||||||
|
let p1 = PosixPath("/usr/bin/whatever/rustc");
|
||||||
|
let p2 = PosixPath("/usr/lib/whatever/mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, PosixPath("../../lib/whatever"));
|
||||||
|
|
||||||
|
let p1 = WindowsPath("C:\\usr\\bin\\whatever\\rustc");
|
||||||
|
let p2 = WindowsPath("C:\\usr\\lib\\whatever\\mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, WindowsPath("..\\..\\lib\\whatever"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_to4() {
|
||||||
|
let p1 = PosixPath("/usr/bin/whatever/../rustc");
|
||||||
|
let p2 = PosixPath("/usr/lib/whatever/mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, PosixPath("../lib/whatever"));
|
||||||
|
|
||||||
|
let p1 = WindowsPath("C:\\usr\\bin\\whatever\\..\\rustc");
|
||||||
|
let p2 = WindowsPath("C:\\usr\\lib\\whatever\\mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, WindowsPath("..\\lib\\whatever"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_to5() {
|
||||||
|
let p1 = PosixPath("/usr/bin/whatever/../rustc");
|
||||||
|
let p2 = PosixPath("/usr/lib/whatever/../mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, PosixPath("../lib"));
|
||||||
|
|
||||||
|
let p1 = WindowsPath("C:\\usr\\bin/whatever\\..\\rustc");
|
||||||
|
let p2 = WindowsPath("C:\\usr\\lib\\whatever\\..\\mylib");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, WindowsPath("..\\lib"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_to6() {
|
||||||
|
let p1 = PosixPath("/1");
|
||||||
|
let p2 = PosixPath("/2/3");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, PosixPath("2"));
|
||||||
|
|
||||||
|
let p1 = WindowsPath("C:\\1");
|
||||||
|
let p2 = WindowsPath("C:\\2\\3");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, WindowsPath("2"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_to7() {
|
||||||
|
let p1 = PosixPath("/1/2");
|
||||||
|
let p2 = PosixPath("/3");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, PosixPath(".."));
|
||||||
|
|
||||||
|
let p1 = WindowsPath("C:\\1\\2");
|
||||||
|
let p2 = WindowsPath("C:\\3");
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
assert_eq!(res, WindowsPath(".."));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_relative_to8() {
|
||||||
|
let p1 = PosixPath("/home/brian/Dev/rust/build/").push_rel(
|
||||||
|
&PosixPath("stage2/lib/rustc/i686-unknown-linux-gnu/lib/librustc.so"));
|
||||||
|
let p2 = PosixPath("/home/brian/Dev/rust/build/stage2/bin/..").push_rel(
|
||||||
|
&PosixPath("lib/rustc/i686-unknown-linux-gnu/lib/libstd.so"));
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
debug!("test_relative_to8: %s vs. %s",
|
||||||
|
res.to_str(),
|
||||||
|
PosixPath(".").to_str());
|
||||||
|
assert_eq!(res, PosixPath("."));
|
||||||
|
|
||||||
|
let p1 = WindowsPath("C:\\home\\brian\\Dev\\rust\\build\\").push_rel(
|
||||||
|
&WindowsPath("stage2\\lib\\rustc\\i686-unknown-linux-gnu\\lib\\librustc.so"));
|
||||||
|
let p2 = WindowsPath("\\home\\brian\\Dev\\rust\\build\\stage2\\bin\\..").push_rel(
|
||||||
|
&WindowsPath("lib\\rustc\\i686-unknown-linux-gnu\\lib\\libstd.so"));
|
||||||
|
let res = p1.get_relative_to(&p2);
|
||||||
|
debug!("test_relative_to8: %s vs. %s",
|
||||||
|
res.to_str(),
|
||||||
|
WindowsPath(".").to_str());
|
||||||
|
assert_eq!(res, WindowsPath("."));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -951,7 +951,11 @@ pub struct view_item {
|
|||||||
|
|
||||||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||||
pub enum view_item_ {
|
pub enum view_item_ {
|
||||||
view_item_extern_mod(ident, ~[@MetaItem], NodeId),
|
// ident: name used to refer to this crate in the code
|
||||||
|
// optional @str: if present, this is a location (containing
|
||||||
|
// arbitrary characters) from which to fetch the crate sources
|
||||||
|
// For example, extern mod whatever = "github.com/mozilla/rust"
|
||||||
|
view_item_extern_mod(ident, Option<@str>, ~[@MetaItem], NodeId),
|
||||||
view_item_use(~[@view_path]),
|
view_item_use(~[@view_path]),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ impl Visitor<()> for IdVisitor {
|
|||||||
|
|
||||||
fn visit_view_item(@mut self, view_item: &view_item, env: ()) {
|
fn visit_view_item(@mut self, view_item: &view_item, env: ()) {
|
||||||
match view_item.node {
|
match view_item.node {
|
||||||
view_item_extern_mod(_, _, node_id) => {
|
view_item_extern_mod(_, _, _, node_id) => {
|
||||||
(self.visit_callback)(node_id)
|
(self.visit_callback)(node_id)
|
||||||
}
|
}
|
||||||
view_item_use(ref view_paths) => {
|
view_item_use(ref view_paths) => {
|
||||||
|
@ -4181,8 +4181,16 @@ impl Parser {
|
|||||||
self.this_token_to_str()));
|
self.this_token_to_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sort, ident) = match *self.token {
|
let (sort, maybe_path, ident) = match *self.token {
|
||||||
token::IDENT(*) => (ast::named, self.parse_ident()),
|
token::IDENT(*) => {
|
||||||
|
let the_ident = self.parse_ident();
|
||||||
|
let path = if *self.token == token::EQ {
|
||||||
|
self.bump();
|
||||||
|
Some(self.parse_str())
|
||||||
|
}
|
||||||
|
else { None };
|
||||||
|
(ast::named, path, the_ident)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if must_be_named_mod {
|
if must_be_named_mod {
|
||||||
self.span_fatal(*self.span,
|
self.span_fatal(*self.span,
|
||||||
@ -4191,7 +4199,7 @@ impl Parser {
|
|||||||
self.this_token_to_str()));
|
self.this_token_to_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
(ast::anonymous,
|
(ast::anonymous, None,
|
||||||
special_idents::clownshoes_foreign_mod)
|
special_idents::clownshoes_foreign_mod)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -4230,7 +4238,7 @@ impl Parser {
|
|||||||
let metadata = self.parse_optional_meta();
|
let metadata = self.parse_optional_meta();
|
||||||
self.expect(&token::SEMI);
|
self.expect(&token::SEMI);
|
||||||
iovi_view_item(ast::view_item {
|
iovi_view_item(ast::view_item {
|
||||||
node: view_item_extern_mod(ident, metadata, self.get_id()),
|
node: view_item_extern_mod(ident, maybe_path, metadata, self.get_id()),
|
||||||
attrs: attrs,
|
attrs: attrs,
|
||||||
vis: visibility,
|
vis: visibility,
|
||||||
span: mk_sp(lo, self.last_span.hi)
|
span: mk_sp(lo, self.last_span.hi)
|
||||||
@ -4812,8 +4820,13 @@ impl Parser {
|
|||||||
} else if self.eat_keyword(keywords::Extern) {
|
} else if self.eat_keyword(keywords::Extern) {
|
||||||
self.expect_keyword(keywords::Mod);
|
self.expect_keyword(keywords::Mod);
|
||||||
let ident = self.parse_ident();
|
let ident = self.parse_ident();
|
||||||
|
let path = if *self.token == token::EQ {
|
||||||
|
self.bump();
|
||||||
|
Some(self.parse_str())
|
||||||
|
}
|
||||||
|
else { None };
|
||||||
let metadata = self.parse_optional_meta();
|
let metadata = self.parse_optional_meta();
|
||||||
view_item_extern_mod(ident, metadata, self.get_id())
|
view_item_extern_mod(ident, path, metadata, self.get_id())
|
||||||
} else {
|
} else {
|
||||||
self.bug("expected view item");
|
self.bug("expected view item");
|
||||||
};
|
};
|
||||||
|
@ -1856,9 +1856,13 @@ pub fn print_view_item(s: @ps, item: &ast::view_item) {
|
|||||||
print_outer_attributes(s, item.attrs);
|
print_outer_attributes(s, item.attrs);
|
||||||
print_visibility(s, item.vis);
|
print_visibility(s, item.vis);
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::view_item_extern_mod(id, ref mta, _) => {
|
ast::view_item_extern_mod(id, ref optional_path, ref mta, _) => {
|
||||||
head(s, "extern mod");
|
head(s, "extern mod");
|
||||||
print_ident(s, id);
|
print_ident(s, id);
|
||||||
|
for p in optional_path.iter() {
|
||||||
|
word(s.s, "=");
|
||||||
|
print_string(s, *p);
|
||||||
|
}
|
||||||
if !mta.is_empty() {
|
if !mta.is_empty() {
|
||||||
popen(s);
|
popen(s);
|
||||||
commasep(s, consistent, *mta, |p, &i| print_meta_item(p, i));
|
commasep(s, consistent, *mta, |p, &i| print_meta_item(p, i));
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
// Copyright 2013 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.
|
|
||||||
|
|
||||||
// Just a test that new-style extern mods parse
|
|
||||||
|
|
||||||
// xfail-test FIXME #6407
|
|
||||||
extern mod test = "github.com/catamorphism/test-pkg";
|
|
||||||
|
|
||||||
fn main() {}
|
|
Loading…
Reference in New Issue
Block a user