Start using core::path2::Path in a lot of places.

This commit is contained in:
Graydon Hoare
2012-08-24 15:28:43 -07:00
parent a8f1bee457
commit c284b8b1dc
43 changed files with 1139 additions and 1115 deletions

View File

@@ -57,18 +57,7 @@ mod write {
return false;
}
// Decides what to call an intermediate file, given the name of the output
// and the extension to use.
fn mk_intermediate_name(output_path: ~str, extension: ~str) ->
~str unsafe {
let stem = match str::find_char(output_path, '.') {
some(dot_pos) => str::slice(output_path, 0u, dot_pos),
none => output_path
};
return stem + ~"." + extension;
}
fn run_passes(sess: session, llmod: ModuleRef, output: ~str) {
fn run_passes(sess: session, llmod: ModuleRef, output: &Path) {
let opts = sess.opts;
if sess.time_llvm_passes() { llvm::LLVMRustEnableTimePasses(); }
let mut pm = mk_pass_manager();
@@ -85,15 +74,15 @@ mod write {
match opts.output_type {
output_type_bitcode => {
if opts.optimize != session::No {
let filename = mk_intermediate_name(output, ~"no-opt.bc");
str::as_c_str(filename, |buf| {
let filename = output.with_filetype("no-opt.bc");
str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
});
}
}
_ => {
let filename = mk_intermediate_name(output, ~"bc");
str::as_c_str(filename, |buf| {
let filename = output.with_filetype("bc");
str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
});
}
@@ -163,9 +152,9 @@ mod write {
if opts.save_temps {
// Always output the bitcode file with --save-temps
let filename = mk_intermediate_name(output, ~"opt.bc");
let filename = output.with_filetype("opt.bc");
llvm::LLVMRunPassManager(pm.llpm, llmod);
str::as_c_str(filename, |buf| {
str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMWriteBitcodeToFile(llmod, buf)
});
pm = mk_pass_manager();
@@ -175,7 +164,7 @@ mod write {
let _: () = str::as_c_str(
sess.targ_cfg.target_strs.target_triple,
|buf_t| {
str::as_c_str(output, |buf_o| {
str::as_c_str(output.to_str(), |buf_o| {
WriteOutputFile(
sess,
pm.llpm,
@@ -197,7 +186,7 @@ mod write {
let _: () = str::as_c_str(
sess.targ_cfg.target_strs.target_triple,
|buf_t| {
str::as_c_str(output, |buf_o| {
str::as_c_str(output.to_str(), |buf_o| {
WriteOutputFile(
sess,
pm.llpm,
@@ -217,7 +206,7 @@ mod write {
let _: () = str::as_c_str(
sess.targ_cfg.target_strs.target_triple,
|buf_t| {
str::as_c_str(output, |buf_o| {
str::as_c_str(output.to_str(), |buf_o| {
WriteOutputFile(
sess,
pm.llpm,
@@ -239,13 +228,13 @@ mod write {
if opts.output_type == output_type_llvm_assembly {
// Given options "-S --emit-llvm": output LLVM assembly
str::as_c_str(output, |buf_o| {
str::as_c_str(output.to_str(), |buf_o| {
llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o)});
} else {
// If only a bitcode file is asked for by using the '--emit-llvm'
// flag, then output it here
llvm::LLVMRunPassManager(pm.llpm, llmod);
str::as_c_str(output,
str::as_c_str(output.to_str(),
|buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) );
}
@@ -306,7 +295,7 @@ mod write {
*
*/
fn build_link_meta(sess: session, c: ast::crate, output: ~str,
fn build_link_meta(sess: session, c: ast::crate, output: &Path,
symbol_hasher: &hash::State) -> link_meta {
type provided_metas =
@@ -384,21 +373,16 @@ fn build_link_meta(sess: session, c: ast::crate, output: ~str,
}
fn crate_meta_name(sess: session, _crate: ast::crate,
output: ~str, metas: provided_metas) -> ~str {
output: &Path, metas: provided_metas) -> ~str {
return match metas.name {
some(v) => v,
none => {
let name =
{
let mut os =
str::split_char(path::basename(output), '.');
if (vec::len(os) < 2u) {
sess.fatal(fmt!("output file name `%s` doesn't\
appear to have an extension", output));
}
vec::pop(os);
str::connect(os, ~".")
};
let name = match output.filestem() {
none => sess.fatal(fmt!("output file name `%s` doesn't\
appear to have a stem",
output.to_str())),
some(s) => s
};
warn_missing(sess, ~"name", name);
name
}
@@ -552,31 +536,17 @@ fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: ~str) -> ~str {
// If the user wants an exe generated we need to invoke
// cc to link the object file with some libs
fn link_binary(sess: session,
obj_filename: ~str,
out_filename: ~str,
obj_filename: &Path,
out_filename: &Path,
lm: link_meta) {
// Converts a library file name into a cc -l argument
fn unlib(config: @session::config, filename: ~str) -> ~str unsafe {
let rmlib = fn@(filename: ~str) -> ~str {
let found = str::find_str(filename, ~"lib");
if config.os == session::os_macos ||
(config.os == session::os_linux ||
config.os == session::os_freebsd) &&
option::is_some(found) && option::get(found) == 0u {
return str::slice(filename, 3u, str::len(filename));
} else { return filename; }
};
fn rmext(filename: ~str) -> ~str {
let mut parts = str::split_char(filename, '.');
vec::pop(parts);
return str::connect(parts, ~".");
// Converts a library file-stem into a cc -l argument
fn unlib(config: @session::config, stem: ~str) -> ~str {
if stem.starts_with("lib") &&
config.os != session::os_win32 {
stem.slice(3, stem.len())
} else {
stem
}
return match config.os {
session::os_macos => rmext(rmlib(filename)),
session::os_linux => rmext(rmlib(filename)),
session::os_freebsd => rmext(rmlib(filename)),
_ => rmext(filename)
};
}
let output = if sess.building_library {
@@ -585,17 +555,19 @@ fn link_binary(sess: session,
lm.name, lm.extras_hash, lm.vers));
debug!("link_meta.name: %s", lm.name);
debug!("long_libname: %s", long_libname);
debug!("out_filename: %s", out_filename);
debug!("dirname(out_filename): %s", path::dirname(out_filename));
debug!("out_filename: %s", out_filename.to_str());
debug!("dirname(out_filename): %s", out_filename.dir_path().to_str());
path::connect(path::dirname(out_filename), long_libname)
} else { out_filename };
out_filename.dir_path().push(long_libname)
} else {
*out_filename
};
log(debug, ~"output: " + output);
log(debug, ~"output: " + output.to_str());
// The default library location, we need this to find the runtime.
// The location of crates will be determined as needed.
let stage: ~str = ~"-L" + sess.filesearch.get_target_lib_path();
let stage: ~str = ~"-L" + sess.filesearch.get_target_lib_path().to_str();
// In the future, FreeBSD will use clang as default compiler.
// It would be flexible to use cc (system's default C compiler)
@@ -609,27 +581,28 @@ fn link_binary(sess: session,
let mut cc_args =
vec::append(~[stage], sess.targ_cfg.target_strs.cc_args);
vec::push(cc_args, ~"-o");
vec::push(cc_args, output);
vec::push(cc_args, obj_filename);
vec::push(cc_args, output.to_str());
vec::push(cc_args, obj_filename.to_str());
let mut lib_cmd;
let os = sess.targ_cfg.os;
if os == session::os_macos {
lib_cmd = ~"-dynamiclib";
} else { lib_cmd = ~"-shared"; }
} else {
lib_cmd = ~"-shared";
}
// # Crate linking
let cstore = sess.cstore;
for cstore::get_used_crate_files(cstore).each |cratepath| {
if str::ends_with(cratepath, ~".rlib") {
vec::push(cc_args, cratepath);
if cratepath.filetype() == some(~"rlib") {
vec::push(cc_args, cratepath.to_str());
again;
}
let cratepath = cratepath;
let dir = path::dirname(cratepath);
let dir = cratepath.dirname();
if dir != ~"" { vec::push(cc_args, ~"-L" + dir); }
let libarg = unlib(sess.targ_cfg, path::basename(cratepath));
let libarg = unlib(sess.targ_cfg, option::get(cratepath.filestem()));
vec::push(cc_args, ~"-l" + libarg);
}
@@ -645,7 +618,7 @@ fn link_binary(sess: session,
// forces to make sure that library can be found at runtime.
let addl_paths = sess.opts.addl_lib_search_paths;
for addl_paths.each |path| { vec::push(cc_args, ~"-L" + path); }
for addl_paths.each |path| { vec::push(cc_args, ~"-L" + path.to_str()); }
// The names of the extern libraries
let used_libs = cstore::get_used_libraries(cstore);
@@ -658,7 +631,7 @@ fn link_binary(sess: session,
// be rpathed
if sess.targ_cfg.os == session::os_macos {
vec::push(cc_args, ~"-Wl,-install_name,@rpath/"
+ path::basename(output));
+ option::get(output.filename()));
}
}
@@ -701,7 +674,7 @@ fn link_binary(sess: session,
// FIXME (#2397): At some point we want to rpath our guesses as to where
// extern libraries might live, based on the addl_lib_search_paths
vec::push_all(cc_args, rpath::get_rpath_flags(sess, output));
vec::push_all(cc_args, rpath::get_rpath_flags(sess, &output));
debug!("%s link args: %s", cc_prog, str::connect(cc_args, ~" "));
// We run 'cc' here
@@ -717,14 +690,14 @@ fn link_binary(sess: session,
// Clean up on Darwin
if sess.targ_cfg.os == session::os_macos {
run::run_program(~"dsymutil", ~[output]);
run::run_program(~"dsymutil", ~[output.to_str()]);
}
// Remove the temporary object file if we aren't saving temps
if !sess.opts.save_temps {
if ! os::remove_file(obj_filename) {
sess.warn(fmt!("failed to delete object file `%s`",
obj_filename));
obj_filename.to_str()));
}
}
}

View File

@@ -13,7 +13,7 @@ pure fn not_win32(os: session::os) -> bool {
}
}
fn get_rpath_flags(sess: session::session, out_filename: ~str) -> ~[~str] {
fn get_rpath_flags(sess: session::session, out_filename: &Path) -> ~[~str] {
let os = sess.targ_cfg.os;
// No rpath on windows
@@ -23,7 +23,6 @@ fn get_rpath_flags(sess: session::session, out_filename: ~str) -> ~[~str] {
debug!("preparing the RPATH!");
let cwd = os::getcwd();
let sysroot = sess.filesearch.sysroot();
let output = out_filename;
let libs = cstore::get_used_crate_files(sess.cstore);
@@ -32,50 +31,48 @@ fn get_rpath_flags(sess: session::session, out_filename: ~str) -> ~[~str] {
let libs = vec::append_one(libs, get_sysroot_absolute_rt_lib(sess));
let target_triple = sess.opts.target_triple;
let rpaths = get_rpaths(os, cwd, sysroot, output, libs, target_triple);
let rpaths = get_rpaths(os, &sysroot, output, libs, target_triple);
rpaths_to_flags(rpaths)
}
fn get_sysroot_absolute_rt_lib(sess: session::session) -> path::Path {
let mut path = vec::append(~[sess.filesearch.sysroot()],
filesearch::relative_target_lib_path(
sess.opts.target_triple));
vec::push(path, os::dll_filename(~"rustrt"));
path::connect_many(path)
fn get_sysroot_absolute_rt_lib(sess: session::session) -> Path {
let r = filesearch::relative_target_lib_path(sess.opts.target_triple);
sess.filesearch.sysroot().push_rel(&r).push(os::dll_filename("rustrt"))
}
fn rpaths_to_flags(rpaths: ~[~str]) -> ~[~str] {
vec::map(rpaths, |rpath| fmt!("-Wl,-rpath,%s",rpath) )
fn rpaths_to_flags(rpaths: &[Path]) -> ~[~str] {
vec::map(rpaths, |rpath| fmt!("-Wl,-rpath,%s",rpath.to_str()))
}
fn get_rpaths(os: session::os, cwd: path::Path, sysroot: path::Path,
output: path::Path, libs: ~[path::Path],
target_triple: ~str) -> ~[~str] {
debug!("cwd: %s", cwd);
debug!("sysroot: %s", sysroot);
debug!("output: %s", output);
fn get_rpaths(os: session::os,
sysroot: &Path,
output: &Path,
libs: &[Path],
target_triple: &str) -> ~[Path] {
debug!("sysroot: %s", sysroot.to_str());
debug!("output: %s", output.to_str());
debug!("libs:");
for libs.each |libpath| {
debug!(" %s", libpath);
debug!(" %s", libpath.to_str());
}
debug!("target_triple: %s", target_triple);
// Use relative paths to the libraries. Binaries can be moved
// as long as they maintain the relative relationship to the
// crates they depend on.
let rel_rpaths = get_rpaths_relative_to_output(os, cwd, output, libs);
let rel_rpaths = get_rpaths_relative_to_output(os, output, libs);
// Make backup absolute paths to the libraries. Binaries can
// be moved as long as the crates they link against don't move.
let abs_rpaths = get_absolute_rpaths(cwd, libs);
let abs_rpaths = get_absolute_rpaths(libs);
// And a final backup rpath to the global library location.
let fallback_rpaths = ~[get_install_prefix_rpath(cwd, target_triple)];
let fallback_rpaths = ~[get_install_prefix_rpath(target_triple)];
fn log_rpaths(desc: ~str, rpaths: ~[~str]) {
fn log_rpaths(desc: &str, rpaths: &[Path]) {
debug!("%s rpaths:", desc);
for rpaths.each |rpath| {
debug!(" %s", rpath);
debug!(" %s", rpath.to_str());
}
}
@@ -93,43 +90,37 @@ fn get_rpaths(os: session::os, cwd: path::Path, sysroot: path::Path,
}
fn get_rpaths_relative_to_output(os: session::os,
cwd: path::Path,
output: path::Path,
libs: ~[path::Path]) -> ~[~str] {
output: &Path,
libs: &[Path]) -> ~[Path] {
vec::map(libs, |a| {
get_rpath_relative_to_output(os, cwd, output, a)
get_rpath_relative_to_output(os, output, &a)
})
}
fn get_rpath_relative_to_output(os: session::os,
cwd: path::Path,
output: path::Path,
&&lib: path::Path) -> ~str {
output: &Path,
lib: &Path) -> Path {
assert not_win32(os);
// Mac doesn't appear to support $ORIGIN
let prefix = match os {
session::os_linux => ~"$ORIGIN" + path::path_sep(),
session::os_freebsd => ~"$ORIGIN" + path::path_sep(),
session::os_macos => ~"@executable_path" + path::path_sep(),
session::os_linux | session::os_freebsd => "$ORIGIN",
session::os_macos => "@executable_path",
session::os_win32 => core::unreachable()
};
prefix + get_relative_to(
get_absolute(cwd, output),
get_absolute(cwd, lib))
Path(prefix).push_rel(&get_relative_to(&os::make_absolute(output),
&os::make_absolute(lib)))
}
// Find the relative path from one file to another
fn get_relative_to(abs1: path::Path, abs2: path::Path) -> path::Path {
assert path::path_is_absolute(abs1);
assert path::path_is_absolute(abs2);
fn get_relative_to(abs1: &Path, abs2: &Path) -> Path {
assert abs1.is_absolute;
assert abs2.is_absolute;
debug!("finding relative path from %s to %s",
abs1, abs2);
let normal1 = path::normalize(abs1);
let normal2 = path::normalize(abs2);
let split1 = path::split(normal1);
let split2 = path::split(normal2);
abs1.to_str(), abs2.to_str());
let split1 = abs1.components;
let split2 = abs2.components;
let len1 = vec::len(split1);
let len2 = vec::len(split2);
assert len1 > 0u;
@@ -148,48 +139,39 @@ fn get_relative_to(abs1: path::Path, abs2: path::Path) -> path::Path {
vec::push_all(path, vec::view(split2, start_idx, len2 - 1u));
if vec::is_not_empty(path) {
return path::connect_many(path);
return Path("").push_many(path);
} else {
return ~".";
return Path(".");
}
}
fn get_absolute_rpaths(cwd: path::Path, libs: ~[path::Path]) -> ~[~str] {
vec::map(libs, |a| get_absolute_rpath(cwd, a) )
fn get_absolute_rpaths(libs: &[Path]) -> ~[Path] {
vec::map(libs, |a| get_absolute_rpath(&a) )
}
fn get_absolute_rpath(cwd: path::Path, &&lib: path::Path) -> ~str {
path::dirname(get_absolute(cwd, lib))
fn get_absolute_rpath(lib: &Path) -> Path {
os::make_absolute(lib).dir_path()
}
fn get_absolute(cwd: path::Path, lib: path::Path) -> path::Path {
if path::path_is_absolute(lib) {
lib
} else {
path::connect(cwd, lib)
}
}
fn get_install_prefix_rpath(cwd: path::Path, target_triple: ~str) -> ~str {
fn get_install_prefix_rpath(target_triple: &str) -> Path {
let install_prefix = env!("CFG_PREFIX");
if install_prefix == ~"" {
fail ~"rustc compiled without CFG_PREFIX environment variable";
}
let path = vec::append(
~[install_prefix],
filesearch::relative_target_lib_path(target_triple));
get_absolute(cwd, path::connect_many(path))
let tlib = filesearch::relative_target_lib_path(target_triple);
os::make_absolute(&Path(install_prefix).push_rel(&tlib))
}
fn minimize_rpaths(rpaths: ~[~str]) -> ~[~str] {
fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] {
let set = map::str_hash::<()>();
let mut minimized = ~[];
for rpaths.each |rpath| {
if !set.contains_key(rpath) {
let s = rpath.to_str();
if !set.contains_key(s) {
vec::push(minimized, rpath);
set.insert(rpath, ());
set.insert(s, ());
}
}
return minimized;
@@ -199,116 +181,112 @@ fn minimize_rpaths(rpaths: ~[~str]) -> ~[~str] {
mod test {
#[test]
fn test_rpaths_to_flags() {
let flags = rpaths_to_flags(~[~"path1", ~"path2"]);
let flags = rpaths_to_flags(~[Path("path1"),
Path("path2")]);
assert flags == ~[~"-Wl,-rpath,path1", ~"-Wl,-rpath,path2"];
}
#[test]
fn test_get_absolute1() {
let cwd = ~"/dir";
let lib = ~"some/path/lib";
let res = get_absolute(cwd, lib);
assert res == ~"/dir/some/path/lib";
}
#[test]
fn test_get_absolute2() {
let cwd = ~"/dir";
let lib = ~"/some/path/lib";
let res = get_absolute(cwd, lib);
assert res == ~"/some/path/lib";
}
#[test]
fn test_prefix_rpath() {
let res = get_install_prefix_rpath(~"/usr/lib", ~"triple");
let d = path::connect(env!("CFG_PREFIX"), ~"/lib/rustc/triple/lib");
assert str::ends_with(res, d);
let res = get_install_prefix_rpath("triple");
let d = Path(env!("CFG_PREFIX"))
.push_rel(&Path("lib/rustc/triple/lib"));
debug!("test_prefix_path: %s vs. %s",
res.to_str(),
d.to_str());
assert str::ends_with(res.to_str(), d.to_str());
}
#[test]
fn test_prefix_rpath_abs() {
let res = get_install_prefix_rpath(~"/usr/lib", ~"triple");
assert path::path_is_absolute(res);
let res = get_install_prefix_rpath("triple");
assert res.is_absolute;
}
#[test]
fn test_minimize1() {
let res = minimize_rpaths(~[~"rpath1", ~"rpath2", ~"rpath1"]);
assert res == ~[~"rpath1", ~"rpath2"];
let res = minimize_rpaths([Path("rpath1"),
Path("rpath2"),
Path("rpath1")]);
assert res == ~[Path("rpath1"), Path("rpath2")];
}
#[test]
fn test_minimize2() {
let res = minimize_rpaths(~[~"1a", ~"2", ~"2", ~"1a", ~"4a",
~"1a", ~"2", ~"3", ~"4a", ~"3"]);
assert res == ~[~"1a", ~"2", ~"4a", ~"3"];
let res = minimize_rpaths(~[Path("1a"), Path("2"), Path("2"),
Path("1a"), Path("4a"),Path("1a"),
Path("2"), Path("3"), Path("4a"),
Path("3")]);
assert res == ~[Path("1a"), Path("2"), Path("4a"), Path("3")];
}
#[test]
fn test_relative_to1() {
let p1 = ~"/usr/bin/rustc";
let p2 = ~"/usr/lib/mylib";
let res = get_relative_to(p1, p2);
assert res == ~"../lib";
let p1 = Path("/usr/bin/rustc");
let p2 = Path("/usr/lib/mylib");
let res = get_relative_to(&p1, &p2);
assert res == Path("../lib");
}
#[test]
fn test_relative_to2() {
let p1 = ~"/usr/bin/rustc";
let p2 = ~"/usr/bin/../lib/mylib";
let res = get_relative_to(p1, p2);
assert res == ~"../lib";
let p1 = Path("/usr/bin/rustc");
let p2 = Path("/usr/bin/../lib/mylib");
let res = get_relative_to(&p1, &p2);
assert res == Path("../lib");
}
#[test]
fn test_relative_to3() {
let p1 = ~"/usr/bin/whatever/rustc";
let p2 = ~"/usr/lib/whatever/mylib";
let res = get_relative_to(p1, p2);
assert res == ~"../../lib/whatever";
let p1 = Path("/usr/bin/whatever/rustc");
let p2 = Path("/usr/lib/whatever/mylib");
let res = get_relative_to(&p1, &p2);
assert res == Path("../../lib/whatever");
}
#[test]
fn test_relative_to4() {
let p1 = ~"/usr/bin/whatever/../rustc";
let p2 = ~"/usr/lib/whatever/mylib";
let res = get_relative_to(p1, p2);
assert res == ~"../lib/whatever";
let p1 = Path("/usr/bin/whatever/../rustc");
let p2 = Path("/usr/lib/whatever/mylib");
let res = get_relative_to(&p1, &p2);
assert res == Path("../lib/whatever");
}
#[test]
fn test_relative_to5() {
let p1 = ~"/usr/bin/whatever/../rustc";
let p2 = ~"/usr/lib/whatever/../mylib";
let res = get_relative_to(p1, p2);
assert res == ~"../lib";
let p1 = Path("/usr/bin/whatever/../rustc");
let p2 = Path("/usr/lib/whatever/../mylib");
let res = get_relative_to(&p1, &p2);
assert res == Path("../lib");
}
#[test]
fn test_relative_to6() {
let p1 = ~"/1";
let p2 = ~"/2/3";
let res = get_relative_to(p1, p2);
assert res == ~"2";
let p1 = Path("/1");
let p2 = Path("/2/3");
let res = get_relative_to(&p1, &p2);
assert res == Path("2");
}
#[test]
fn test_relative_to7() {
let p1 = ~"/1/2";
let p2 = ~"/3";
let res = get_relative_to(p1, p2);
assert res == ~"..";
let p1 = Path("/1/2");
let p2 = Path("/3");
let res = get_relative_to(&p1, &p2);
assert res == Path("..");
}
#[test]
fn test_relative_to8() {
let p1 = ~"/home/brian/Dev/rust/build/"
+ ~"stage2/lib/rustc/i686-unknown-linux-gnu/lib/librustc.so";
let p2 = ~"/home/brian/Dev/rust/build/stage2/bin/.."
+ ~"/lib/rustc/i686-unknown-linux-gnu/lib/libstd.so";
let res = get_relative_to(p1, p2);
assert res == ~".";
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 res == Path(".");
}
#[test]
@@ -316,8 +294,8 @@ mod test {
fn test_rpath_relative() {
let o = session::os_linux;
let res = get_rpath_relative_to_output(o,
~"/usr", ~"bin/rustc", ~"lib/libstd.so");
assert res == ~"$ORIGIN/../lib";
&Path("bin/rustc"), &Path("lib/libstd.so"));
assert res == Path("$ORIGIN/../lib");
}
#[test]
@@ -325,8 +303,8 @@ mod test {
fn test_rpath_relative() {
let o = session::os_freebsd;
let res = get_rpath_relative_to_output(o,
~"/usr", ~"bin/rustc", ~"lib/libstd.so");
assert res == ~"$ORIGIN/../lib";
&Path("bin/rustc"), &Path("lib/libstd.so"));
assert res == Path("$ORIGIN/../lib");
}
#[test]
@@ -334,14 +312,19 @@ mod test {
fn test_rpath_relative() {
// this is why refinements would be nice
let o = session::os_macos;
let res = get_rpath_relative_to_output(o, ~"/usr", ~"bin/rustc",
~"lib/libstd.so");
assert res == ~"@executable_path/../lib";
let res = get_rpath_relative_to_output(o,
&Path("bin/rustc"),
&Path("lib/libstd.so"));
assert res == Path("@executable_path/../lib");
}
#[test]
fn test_get_absolute_rpath() {
let res = get_absolute_rpath(~"/usr", ~"lib/libstd.so");
assert res == ~"/usr/lib";
let res = get_absolute_rpath(&Path("lib/libstd.so"));
debug!("test_get_absolute_rpath: %s vs. %s",
res.to_str(),
os::make_absolute(&Path("lib")).to_str());
assert res == os::make_absolute(&Path("lib"));
}
}

View File

@@ -27,7 +27,7 @@ fn anon_src() -> ~str { ~"<anon>" }
fn source_name(input: input) -> ~str {
match input {
file_input(ifile) => ifile,
file_input(ifile) => ifile.to_str(),
str_input(_) => anon_src()
}
}
@@ -92,7 +92,7 @@ fn parse_cfgspecs(cfgspecs: ~[~str]) -> ast::crate_cfg {
enum input {
/// Load source from file
file_input(~str),
file_input(Path),
/// The string is the source
str_input(~str)
}
@@ -101,7 +101,7 @@ fn parse_input(sess: session, cfg: ast::crate_cfg, input: input)
-> @ast::crate {
match input {
file_input(file) => {
parse::parse_crate_from_file(file, cfg, sess.parse_sess)
parse::parse_crate_from_file(&file, cfg, sess.parse_sess)
}
str_input(src) => {
// FIXME (#2319): Don't really want to box the source string
@@ -236,11 +236,13 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
vtable_map: vtable_map};
let (llmod, link_meta) = time(time_passes, ~"translation", ||
trans::base::trans_crate(sess, crate, ty_cx, outputs.obj_filename,
trans::base::trans_crate(sess, crate, ty_cx,
&outputs.obj_filename,
exp_map, exp_map2, maps));
time(time_passes, ~"LLVM passes", ||
link::write::run_passes(sess, llmod, outputs.obj_filename));
link::write::run_passes(sess, llmod,
&outputs.obj_filename));
let stop_after_codegen =
sess.opts.output_type != link::output_type_exe ||
@@ -249,14 +251,15 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
if stop_after_codegen { return {crate: crate, tcx: some(ty_cx)}; }
time(time_passes, ~"linking", ||
link::link_binary(sess, outputs.obj_filename,
outputs.out_filename, link_meta));
link::link_binary(sess,
&outputs.obj_filename,
&outputs.out_filename, link_meta));
return {crate: crate, tcx: some(ty_cx)};
}
fn compile_input(sess: session, cfg: ast::crate_cfg, input: input,
outdir: option<~str>, output: option<~str>) {
outdir: &option<Path>, output: &option<Path>) {
let upto = if sess.opts.parse_only { cu_parse }
else if sess.opts.no_trans { cu_no_trans }
@@ -483,6 +486,7 @@ fn build_session_options(matches: getopts::matches,
let extra_debuginfo = opt_present(matches, ~"xg");
let debuginfo = opt_present(matches, ~"g") || extra_debuginfo;
let sysroot_opt = getopts::opt_maybe_str(matches, ~"sysroot");
let sysroot_opt = option::map(sysroot_opt, |m| Path(m));
let target_opt = getopts::opt_maybe_str(matches, ~"target");
let save_temps = getopts::opt_present(matches, ~"save-temps");
match output_type {
@@ -514,7 +518,9 @@ fn build_session_options(matches: getopts::matches,
some(s) => s
};
let addl_lib_search_paths = getopts::opt_strs(matches, ~"L");
let addl_lib_search_paths =
getopts::opt_strs(matches, ~"L")
.map(|s| Path(s));
let cfg = parse_cfgspecs(getopts::opt_strs(matches, ~"cfg"));
let test = opt_present(matches, ~"test");
let sopts: @session::options =
@@ -614,11 +620,11 @@ fn opts() -> ~[getopts::opt] {
optflag(~"static"), optflag(~"gc")];
}
type output_filenames = @{out_filename: ~str, obj_filename:~str};
type output_filenames = @{out_filename:Path, obj_filename:Path};
fn build_output_filenames(input: input,
odir: option<~str>,
ofile: option<~str>,
odir: &option<Path>,
ofile: &option<Path>,
sess: session)
-> output_filenames {
let obj_path;
@@ -639,37 +645,30 @@ fn build_output_filenames(input: input,
link::output_type_object | link::output_type_exe => ~"o"
};
match ofile {
match *ofile {
none => {
// "-" as input file will cause the parser to read from stdin so we
// have to make up a name
// We want to toss everything after the final '.'
let dirname = match odir {
let dirpath = match *odir {
some(d) => d,
none => match input {
str_input(_) => os::getcwd(),
file_input(ifile) => path::dirname(ifile)
file_input(ifile) => ifile.dir_path()
}
};
let base_filename = match input {
file_input(ifile) => {
let (path, _) = path::splitext(ifile);
path::basename(path)
}
let stem = match input {
file_input(ifile) => option::get(ifile.filestem()),
str_input(_) => ~"rust_out"
};
let base_path = path::connect(dirname, base_filename);
if sess.building_library {
let basename = path::basename(base_path);
let dylibname = os::dll_filename(basename);
out_path = path::connect(dirname, dylibname);
obj_path = path::connect(dirname, basename + ~"." + obj_suffix);
out_path = dirpath.push(os::dll_filename(stem));
obj_path = dirpath.push(stem).with_filetype(obj_suffix);
} else {
out_path = base_path;
obj_path = base_path + ~"." + obj_suffix;
out_path = dirpath.push(stem);
obj_path = dirpath.push(stem).with_filetype(obj_suffix);
}
}
@@ -678,9 +677,7 @@ fn build_output_filenames(input: input,
obj_path = if stop_after_codegen {
out_file
} else {
let (base, _) = path::splitext(out_file);
let modified = base + ~"." + obj_suffix;
modified
out_file.with_filetype(obj_suffix)
};
if sess.building_library {
@@ -690,13 +687,13 @@ fn build_output_filenames(input: input,
// lib<basename>-<hash>-<version>.so no matter what.
}
if odir != none {
if *odir != none {
sess.warn(~"ignoring --out-dir flag due to -o flag.");
}
}
}
return @{out_filename: out_path,
obj_filename: obj_path};
obj_filename: obj_path};
}
fn early_error(emitter: diagnostic::emitter, msg: ~str) -> ! {
@@ -704,7 +701,7 @@ fn early_error(emitter: diagnostic::emitter, msg: ~str) -> ! {
fail;
}
fn list_metadata(sess: session, path: ~str, out: io::Writer) {
fn list_metadata(sess: session, path: &Path, out: io::Writer) {
metadata::loader::list_file_metadata(
sess.parse_sess.interner,
session::sess_os_to_meta_os(sess.targ_cfg.os), path, out);

View File

@@ -159,7 +159,7 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) {
let src = str::from_bytes(io::stdin().read_whole_stream());
str_input(src)
} else {
file_input(ifile)
file_input(Path(ifile))
}
}
_ => early_error(demitter, ~"multiple input filenames provided")
@@ -168,7 +168,9 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) {
let sopts = build_session_options(matches, demitter);
let sess = build_session(sopts, demitter);
let odir = getopts::opt_maybe_str(matches, ~"out-dir");
let odir = option::map(odir, |o| Path(o));
let ofile = getopts::opt_maybe_str(matches, ~"o");
let ofile = option::map(ofile, |o| Path(o));
let cfg = build_configuration(sess, binary, input);
let pretty =
option::map(getopts::opt_default(matches, ~"pretty",
@@ -185,7 +187,7 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) {
if ls {
match input {
file_input(ifile) => {
list_metadata(sess, ifile, io::stdout());
list_metadata(sess, &ifile, io::stdout());
}
str_input(_) => {
early_error(demitter, ~"can not list metadata for stdin");
@@ -194,7 +196,7 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) {
return;
}
compile_input(sess, cfg, input, odir, ofile);
compile_input(sess, cfg, input, &odir, &ofile);
}
/*

View File

@@ -89,8 +89,8 @@ type options =
lint_opts: ~[(lint::lint, lint::level)],
save_temps: bool,
output_type: back::link::output_type,
addl_lib_search_paths: ~[~str],
maybe_sysroot: option<~str>,
addl_lib_search_paths: ~[Path],
maybe_sysroot: option<Path>,
target_triple: ~str,
cfg: ast::crate_cfg,
test: bool,
@@ -111,7 +111,7 @@ type session_ = {targ_cfg: @config,
span_diagnostic: diagnostic::span_handler,
filesearch: filesearch::filesearch,
mut building_library: bool,
working_dir: ~str,
working_dir: Path,
lint_settings: lint::lint_settings};
enum session {

View File

@@ -199,7 +199,7 @@ fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item],
};
let cinfo = loader::load_library_crate(load_ctxt);
let cfilename = cinfo.ident;
let cfilename = Path(cinfo.ident);
let cdata = cinfo.data;
let attrs = decoder::get_crate_attributes(cdata);
@@ -225,7 +225,7 @@ fn resolve_crate(e: env, ident: ast::ident, metas: ~[@ast::meta_item],
let cstore = e.cstore;
cstore::set_crate_data(cstore, cnum, cmeta);
cstore::add_used_crate_file(cstore, cfilename);
cstore::add_used_crate_file(cstore, &cfilename);
return cnum;
}
some(cnum) => {

View File

@@ -56,7 +56,7 @@ type cstore_private =
@{metas: map::hashmap<ast::crate_num, crate_metadata>,
use_crate_map: use_crate_map,
mod_path_map: mod_path_map,
mut used_crate_files: ~[~str],
mut used_crate_files: ~[Path],
mut used_libraries: ~[~str],
mut used_link_args: ~[~str],
intr: ident_interner};
@@ -114,13 +114,13 @@ fn iter_crate_data(cstore: cstore, i: fn(ast::crate_num, crate_metadata)) {
for p(cstore).metas.each |k,v| { i(k, v);};
}
fn add_used_crate_file(cstore: cstore, lib: ~str) {
if !vec::contains(p(cstore).used_crate_files, lib) {
vec::push(p(cstore).used_crate_files, lib);
fn add_used_crate_file(cstore: cstore, lib: &Path) {
if !vec::contains(p(cstore).used_crate_files, copy *lib) {
vec::push(p(cstore).used_crate_files, copy *lib);
}
}
fn get_used_crate_files(cstore: cstore) -> ~[~str] {
fn get_used_crate_files(cstore: cstore) -> ~[Path] {
return p(cstore).used_crate_files;
}

View File

@@ -14,12 +14,10 @@ export get_cargo_root;
export get_cargo_root_nearest;
export libdir;
import path::Path;
type pick<T> = fn(path: &Path) -> option<T>;
type pick<T> = fn(path: Path) -> option<T>;
fn pick_file(file: Path, path: Path) -> option<Path> {
if path::basename(path) == file { option::some(path) }
fn pick_file(file: Path, path: &Path) -> option<Path> {
if path.file_path() == file { option::some(copy *path) }
else { option::none }
}
@@ -27,11 +25,11 @@ trait filesearch {
fn sysroot() -> Path;
fn lib_search_paths() -> ~[Path];
fn get_target_lib_path() -> Path;
fn get_target_lib_file_path(file: Path) -> Path;
fn get_target_lib_file_path(file: &Path) -> Path;
}
fn mk_filesearch(maybe_sysroot: option<Path>,
target_triple: ~str,
target_triple: &str,
addl_lib_search_paths: ~[Path]) -> filesearch {
type filesearch_impl = {sysroot: Path,
addl_lib_search_paths: ~[Path],
@@ -42,7 +40,8 @@ fn mk_filesearch(maybe_sysroot: option<Path>,
let mut paths = self.addl_lib_search_paths;
vec::push(paths,
make_target_lib_path(self.sysroot, self.target_triple));
make_target_lib_path(&self.sysroot,
self.target_triple));
match get_cargo_lib_path_nearest() {
result::ok(p) => vec::push(paths, p),
result::err(p) => ()
@@ -54,33 +53,33 @@ fn mk_filesearch(maybe_sysroot: option<Path>,
paths
}
fn get_target_lib_path() -> Path {
make_target_lib_path(self.sysroot, self.target_triple)
make_target_lib_path(&self.sysroot, self.target_triple)
}
fn get_target_lib_file_path(file: Path) -> Path {
path::connect(self.get_target_lib_path(), file)
fn get_target_lib_file_path(file: &Path) -> Path {
self.get_target_lib_path().push_rel(file)
}
}
let sysroot = get_sysroot(maybe_sysroot);
debug!("using sysroot = %s", sysroot);
debug!("using sysroot = %s", sysroot.to_str());
{sysroot: sysroot,
addl_lib_search_paths: addl_lib_search_paths,
target_triple: target_triple} as filesearch
target_triple: str::from_slice(target_triple)} as filesearch
}
fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option<T> {
let mut rslt = none;
for filesearch.lib_search_paths().each |lib_search_path| {
debug!("searching %s", lib_search_path);
for os::list_dir_path(lib_search_path).each |path| {
debug!("testing %s", path);
debug!("searching %s", lib_search_path.to_str());
for os::list_dir_path(&lib_search_path).each |path| {
debug!("testing %s", path.to_str());
let maybe_picked = pick(path);
if option::is_some(maybe_picked) {
debug!("picked %s", path);
debug!("picked %s", path.to_str());
rslt = maybe_picked;
break;
} else {
debug!("rejected %s", path);
debug!("rejected %s", path.to_str());
}
}
if option::is_some(rslt) { break; }
@@ -88,21 +87,20 @@ fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option<T> {
return rslt;
}
fn relative_target_lib_path(target_triple: ~str) -> ~[Path] {
~[libdir(), ~"rustc", target_triple, libdir()]
fn relative_target_lib_path(target_triple: &str) -> Path {
Path(libdir()).push_many([~"rustc",
str::from_slice(target_triple),
libdir()])
}
fn make_target_lib_path(sysroot: Path,
target_triple: ~str) -> Path {
let path = vec::append(~[sysroot],
relative_target_lib_path(target_triple));
let path = path::connect_many(path);
return path;
fn make_target_lib_path(sysroot: &Path,
target_triple: &str) -> Path {
sysroot.push_rel(&relative_target_lib_path(target_triple))
}
fn get_default_sysroot() -> Path {
match os::self_exe_path() {
option::some(p) => path::normalize(path::connect(p, ~"..")),
option::some(p) => p.pop(),
option::none => fail ~"can't determine value for sysroot"
}
}
@@ -115,15 +113,14 @@ fn get_sysroot(maybe_sysroot: option<Path>) -> Path {
}
fn get_cargo_sysroot() -> result<Path, ~str> {
let path = ~[get_default_sysroot(), libdir(), ~"cargo"];
result::ok(path::connect_many(path))
result::ok(get_default_sysroot().push_many([libdir(), ~"cargo"]))
}
fn get_cargo_root() -> result<Path, ~str> {
match os::getenv(~"CARGO_ROOT") {
some(_p) => result::ok(_p),
some(_p) => result::ok(Path(_p)),
none => match os::homedir() {
some(_q) => result::ok(path::connect(_q, ~".cargo")),
some(_q) => result::ok(_q.push(".cargo")),
none => result::err(~"no CARGO_ROOT or home directory")
}
}
@@ -132,21 +129,21 @@ fn get_cargo_root() -> result<Path, ~str> {
fn get_cargo_root_nearest() -> result<Path, ~str> {
do result::chain(get_cargo_root()) |p| {
let cwd = os::getcwd();
let mut dirname = path::dirname(cwd);
let mut dirpath = path::split(dirname);
let cwd_cargo = path::connect(cwd, ~".cargo");
let mut par_cargo = path::connect(dirname, ~".cargo");
let cwd_cargo = cwd.push(".cargo");
let mut par_cargo = cwd.pop().push(".cargo");
let mut rslt = result::ok(cwd_cargo);
if !os::path_is_dir(cwd_cargo) && cwd_cargo != p {
while vec::is_not_empty(dirpath) && par_cargo != p {
if os::path_is_dir(par_cargo) {
if !os::path_is_dir(&cwd_cargo) && cwd_cargo != p {
while par_cargo != p {
if os::path_is_dir(&par_cargo) {
rslt = result::ok(par_cargo);
break;
}
vec::pop(dirpath);
dirname = path::dirname(dirname);
par_cargo = path::connect(dirname, ~".cargo");
if par_cargo.components.len() == 1 {
// We just checked /.cargo, stop now.
break;
}
par_cargo = par_cargo.pop().pop().push(".cargo");
}
}
rslt
@@ -155,13 +152,13 @@ fn get_cargo_root_nearest() -> result<Path, ~str> {
fn get_cargo_lib_path() -> result<Path, ~str> {
do result::chain(get_cargo_root()) |p| {
result::ok(path::connect(p, libdir()))
result::ok(p.push(libdir()))
}
}
fn get_cargo_lib_path_nearest() -> result<Path, ~str> {
do result::chain(get_cargo_root_nearest()) |p| {
result::ok(path::connect(p, libdir()))
result::ok(p.push(libdir()))
}
}

View File

@@ -74,27 +74,28 @@ fn find_library_crate_aux(cx: ctxt,
let mut matches = ~[];
filesearch::search(filesearch, |path| {
debug!("inspecting file %s", path);
let f: ~str = path::basename(path);
debug!("inspecting file %s", path.to_str());
let f: ~str = option::get(path.filename());
if !(str::starts_with(f, prefix) && str::ends_with(f, suffix)) {
debug!("skipping %s, doesn't look like %s*%s", path, prefix,
suffix);
debug!("skipping %s, doesn't look like %s*%s", path.to_str(),
prefix, suffix);
option::none::<()>
} else {
debug!("%s is a candidate", path);
debug!("%s is a candidate", path.to_str());
match get_metadata_section(cx.os, path) {
option::some(cvec) => {
if !crate_matches(cvec, cx.metas, cx.hash) {
debug!("skipping %s, metadata doesn't match", path);
debug!("skipping %s, metadata doesn't match",
path.to_str());
option::none::<()>
} else {
debug!("found %s with matching metadata", path);
vec::push(matches, {ident: path, data: cvec});
debug!("found %s with matching metadata", path.to_str());
vec::push(matches, {ident: path.to_str(), data: cvec});
option::none::<()>
}
}
_ => {
debug!("could not load metadata for %s", path);
debug!("could not load metadata for %s", path.to_str());
option::none::<()>
}
}
@@ -168,10 +169,10 @@ fn metadata_matches(extern_metas: ~[@ast::meta_item],
}
fn get_metadata_section(os: os,
filename: ~str) -> option<@~[u8]> unsafe {
let mb = str::as_c_str(filename, |buf| {
filename: &Path) -> option<@~[u8]> unsafe {
let mb = str::as_c_str(filename.to_str(), |buf| {
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
});
});
if mb as int == 0 { return option::none::<@~[u8]>; }
let of = match mk_object_file(mb) {
option::some(of) => of,
@@ -204,12 +205,13 @@ fn meta_section_name(os: os) -> ~str {
}
// A diagnostic function for dumping crate metadata to an output stream
fn list_file_metadata(intr: ident_interner, os: os, path: ~str,
out: io::Writer) {
fn list_file_metadata(intr: ident_interner,
os: os, path: &Path, out: io::Writer) {
match get_metadata_section(os, path) {
option::some(bytes) => decoder::list_crate_metadata(intr, bytes, out),
option::none => {
out.write_str(~"could not find metadata in " + path + ~".\n");
out.write_str(~"could not find metadata in "
+ path.to_str() + ~".\n");
}
}
}

View File

@@ -5778,7 +5778,7 @@ fn write_abi_version(ccx: @crate_ctxt) {
fn trans_crate(sess: session::session,
crate: @ast::crate,
tcx: ty::ctxt,
output: ~str,
output: &Path,
emap: resolve3::ExportMap,
emap2: resolve3::ExportMap2,
maps: astencode::maps)

View File

@@ -172,7 +172,7 @@ fn create_compile_unit(cx: @crate_ctxt)
option::none => ()
}
let (_, work_dir) = get_file_path_and_dir(cx.sess.working_dir,
let (_, work_dir) = get_file_path_and_dir(cx.sess.working_dir.to_str(),
crate_name);
let unit_metadata = ~[lltag(tg),
llunused(),
@@ -197,13 +197,13 @@ fn get_cache(cx: @crate_ctxt) -> metadata_cache {
option::get(cx.dbg_cx).llmetadata
}
fn get_file_path_and_dir(work_dir: ~str, full_path: ~str) -> (~str, ~str) {
fn get_file_path_and_dir(work_dir: &str, full_path: &str) -> (~str, ~str) {
(if str::starts_with(full_path, work_dir) {
str::slice(full_path, str::len(work_dir) + 1u,
str::len(full_path))
} else {
full_path
}, work_dir)
str::from_slice(full_path)
}, str::from_slice(work_dir))
}
fn create_file(cx: @crate_ctxt, full_path: ~str) -> @metadata<file_md> {
@@ -215,8 +215,9 @@ fn create_file(cx: @crate_ctxt, full_path: ~str) -> @metadata<file_md> {
option::none => ()
}
let (file_path, work_dir) = get_file_path_and_dir(cx.sess.working_dir,
full_path);
let (file_path, work_dir) =
get_file_path_and_dir(cx.sess.working_dir.to_str(),
full_path);
let unit_node = create_compile_unit(cx).node;
let file_md = ~[lltag(tg),
llstr(file_path),

View File

@@ -210,6 +210,9 @@ fn vstore_ty_to_str(cx: ctxt, ty: ~str, vs: ty::vstore) -> ~str {
ty::vstore_fixed(_) => {
fmt!("%s/%s", ty, vstore_to_str(cx, vs))
}
ty::vstore_slice(_) => {
fmt!("%s/%s", vstore_to_str(cx, vs), ty)
}
_ => fmt!("%s%s", vstore_to_str(cx, vs), ty)
}
}