rustpkg will install libraries for bar to `foo/lib/x86_64-apple-darwin/`.
The libraries will have names of the form `foo/lib/x86_64-apple-darwin/libbar-[hash].dylib`,
where [hash] is a hash of the package ID.
-* 'bin/': `rustpkg install` installs executable binaries into a target-specific subdirectory of this directory.
+* 'bin/': `rustpkg install` installs executable binaries into this directory.
- For example, on a 64-bit machine running Mac OS X,
- if `foo` is a workspace, containing the package `bar`,
- rustpkg will install executables for `bar` to
- `foo/bin/x86_64-apple-darwin/`.
- The executables will have names of the form `foo/bin/x86_64-apple-darwin/bar`.
+ For example, rustpkg will install executables for `bar` to
+ `foo/bin`.
+ The executables will have names of the form `foo/bin/bar`.
* 'build/': `rustpkg build` stores temporary build artifacts in a target-specific subdirectory of this directory.
For example, on a 64-bit machine running Mac OS X,
Thus, `github.com/mozilla/rust#5c4cd30f80` is also a valid package ID,
since git can deduce that 5c4cd30f80 refers to a revision of the desired repository.
+A package identifier can name a subdirectory of another package.
+For example, if `foo` is a workspace, and `foo/src/bar/lib.rs` exists,
+as well as `foo/src/bar/extras/baz/lib.rs`,
+then both `bar` and `bar/extras/baz` are valid package identifiers
+in the workspace `foo`.
+
## Source files
rustpkg searches for four different fixed filenames in order to determine the crates to build:
## install
-`rustpkg install foo` builds the libraries and/or executables that are targets for `foo`,
-and then installs them either into `foo`'s `lib` and `bin` directories,
-or into the `lib` and `bin` subdirectories of the first entry in `RUST_PATH`.
+`rustpkg install foo` builds the libraries and/or executables that are targets for `foo`.
+If `RUST_PATH` is declared as an environment variable, then rustpkg installs the
+libraries and executables into the `lib` and `bin` subdirectories
+of the first entry in `RUST_PATH`.
+Otherwise, it installs them into `foo`'s `lib` and `bin` directories.
## test
if !found {
let rustpath = rust_path();
for path in rustpath.iter() {
- debug!("is %s in visited_dirs? %?",
- path.push("lib").to_str(),
- visited_dirs.contains(&path.push("lib").to_str()));
+ let tlib_path = make_rustpkg_target_lib_path(path, self.target_triple);
+ debug!("is %s in visited_dirs? %?", tlib_path.to_str(),
+ visited_dirs.contains(&tlib_path.to_str()));
- if !visited_dirs.contains(&path.push("lib").to_str()) {
- visited_dirs.insert(path.push("lib").to_str());
+ if !visited_dirs.contains(&tlib_path.to_str()) {
+ visited_dirs.insert(tlib_path.to_str());
// Don't keep searching the RUST_PATH if one match turns up --
// if we did, we'd get a "multiple matching crates" error
- match f(&path.push("lib")) {
+ match f(&tlib_path) {
FileMatches => {
break;
}
sysroot.push_rel(&relative_target_lib_path(target_triple))
}
+fn make_rustpkg_target_lib_path(dir: &Path,
+ target_triple: &str) -> Path {
+ dir.push_rel(&Path(libdir()).push(target_triple.to_owned()))
+}
+
fn get_or_default_sysroot() -> Path {
match os::self_exe_path() {
option::Some(ref p) => (*p).pop(),
pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install};
pub use version::{Version, NoVersion, split_version_general, try_parsing_version};
pub use rustc::metadata::filesearch::rust_path;
+use rustc::driver::driver::host_triple;
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use std::os::mkdir_recursive;
found
}
+/// Return the target-specific build subdirectory, pushed onto `base`;
+/// doesn't check that it exists or create it
+pub fn target_build_dir(workspace: &Path) -> Path {
+ workspace.push("build").push(host_triple())
+}
+
+/// Return the target-specific lib subdirectory, pushed onto `base`;
+/// doesn't check that it exists or create it
+fn target_lib_dir(workspace: &Path) -> Path {
+ workspace.push("lib").push(host_triple())
+}
+
+/// Return the bin subdirectory, pushed onto `base`;
+/// doesn't check that it exists or create it
+/// note: this isn't target-specific
+fn target_bin_dir(workspace: &Path) -> Path {
+ workspace.push("bin")
+}
+
/// Figure out what the executable name for <pkgid> in <workspace>'s build
/// directory is, and if the file exists, return it.
pub fn built_executable_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
- let mut result = workspace.push("build");
+ let mut result = target_build_dir(workspace);
// should use a target-specific subdirectory
result = mk_output_path(Main, Build, pkgid, result);
debug!("built_executable_in_workspace: checking whether %s exists",
}
fn output_in_workspace(pkgid: &PkgId, workspace: &Path, what: OutputType) -> Option<Path> {
- let mut result = workspace.push("build");
+ let mut result = target_build_dir(workspace);
// should use a target-specific subdirectory
result = mk_output_path(what, Build, pkgid, result);
debug!("output_in_workspace: checking whether %s exists",
prefix = %s", short_name, where, workspace.to_str(), prefix);
let dir_to_search = match where {
- Build => workspace.push(prefix).push_rel(path),
- Install => workspace.push(prefix)
+ Build => target_build_dir(workspace).push_rel(path),
+ Install => target_lib_dir(workspace)
};
+
+ library_in(short_name, version, &dir_to_search)
+}
+
+// rustc doesn't use target-specific subdirectories
+pub fn system_library(sysroot: &Path, lib_name: &str) -> Option<Path> {
+ library_in(lib_name, &NoVersion, &sysroot.push("lib"))
+}
+
+fn library_in(short_name: &str, version: &Version, dir_to_search: &Path) -> Option<Path> {
debug!("Listing directory %s", dir_to_search.to_str());
- let dir_contents = os::list_dir(&dir_to_search);
+ let dir_contents = os::list_dir(dir_to_search);
debug!("dir has %? entries", dir_contents.len());
let lib_prefix = fmt!("%s%s", os::consts::DLL_PREFIX, short_name);
};
// Artifacts in the build directory live in a package-ID-specific subdirectory,
// but installed ones don't.
- let result = match where {
- Build => workspace.push(subdir).push_rel(&pkgid.path),
- _ => workspace.push(subdir)
+ let result = match (where, what) {
+ (Build, _) => target_build_dir(workspace).push_rel(&pkgid.path),
+ (Install, Lib) => target_lib_dir(workspace),
+ (Install, _) => target_bin_dir(workspace)
};
if !os::path_exists(&result) && !mkdir_recursive(&result, U_RWX) {
cond.raise((result.clone(), fmt!("target_file_in_workspace couldn't \
pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
use conditions::bad_path::cond;
- let mut result = workspace.push("build");
- // n.b. Should actually use a target-specific
- // subdirectory of build/
+ let mut result = target_build_dir(workspace);
result = result.push_rel(&pkgid.path);
+ debug!("Creating build dir %s for package id %s", result.to_str(),
+ pkgid.to_str());
if os::path_exists(&result) || os::mkdir_recursive(&result, U_RWX) {
result
}
target_bench_in_workspace, make_dir_rwx, U_RWX,
library_in_workspace, installed_library_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, target_build_dir};
use rustc::back::link::get_cc_prog;
use rustc::metadata::filesearch::rust_path;
use rustc::driver::driver::{build_session, build_session_options, host_triple, optgroups};
}
fn file_exists(repo: &Path, short_name: &str, extension: &str) -> bool {
- os::path_exists(&repo.push_many([~"build", short_name.to_owned(),
+ os::path_exists(&target_build_dir(repo).push_many([short_name.to_owned(),
fmt!("%s.%s", short_name, extension)]))
}
}
fn output_file_name(workspace: &Path, short_name: &str) -> Path {
- workspace.push("build").push(short_name).push(fmt!("%s%s", short_name, os::EXE_SUFFIX))
+ target_build_dir(workspace).push(short_name).push(fmt!("%s%s", short_name, os::EXE_SUFFIX))
}
fn touch_source_file(workspace: &Path, pkgid: &PkgId) {
None => false
});
assert!(built_executable_in_workspace(&temp_pkg_id, &ws)
- == Some(ws.push("build").
- push("mockgithub.com").
- push("catamorphism").
- push("test_pkg_version").
- push("test_pkg_version")));
+ == Some(target_build_dir(&ws).push_many([~"mockgithub.com",
+ ~"catamorphism",
+ ~"test_pkg_version",
+ ~"test_pkg_version"])));
}
#[test]
}
command_line_test([~"install", ~"fancy-lib"], &dir);
assert_lib_exists(&dir, &Path("fancy-lib"), NoVersion);
- assert!(os::path_exists(&dir.push("build").push("fancy-lib").push("generated.rs")));
+ assert!(os::path_exists(&target_build_dir(&dir).push_many([~"fancy-lib", ~"generated.rs"])));
}
#[test]
"extern mod rustpkg; fn main() {}");
command_line_test([~"build", ~"foo"], &workspace);
debug!("workspace = %s", workspace.to_str());
- assert!(os::path_exists(&workspace.push("build").push("foo").push(fmt!("pkg%s",
+ assert!(os::path_exists(&target_build_dir(&workspace).push("foo").push(fmt!("pkg%s",
os::EXE_SUFFIX))));
}
"extern mod rustpkg; fn main() { debug!(\"Hi\"); }");
command_line_test([~"build", ~"foo"], &workspace);
debug!("workspace = %s", workspace.to_str());
- assert!(os::path_exists(&workspace.push("build").push("foo").push(fmt!("pkg%s",
+ assert!(os::path_exists(&target_build_dir(&workspace).push("foo").push(fmt!("pkg%s",
os::EXE_SUFFIX))));
}
assert!(!executable_exists(&second_workspace, "foo"));
}
+fn test_target_specific_build_dir() {
+ let p_id = PkgId::new("foo");
+ let workspace = create_local_package(&p_id);
+ command_line_test([test_sysroot().to_str(),
+ ~"build",
+ ~"foo"],
+ &workspace);
+ assert!(os::path_is_dir(&target_build_dir(&workspace)));
+ assert!(built_executable_exists(&workspace, "foo"));
+ assert!(os::list_dir(&workspace.push("build")).len() == 1);
+}
+
+#[test]
+fn test_target_specific_install_dir() {
+ let p_id = PkgId::new("foo");
+ let workspace = create_local_package(&p_id);
+ command_line_test([test_sysroot().to_str(),
+ ~"install",
+ ~"foo"],
+ &workspace);
+ assert!(os::path_is_dir(&workspace.push("lib").push(host_triple())));
+ assert_lib_exists(&workspace, &Path("foo"), NoVersion);
+ assert!(os::list_dir(&workspace.push("lib")).len() == 1);
+ assert!(os::path_is_dir(&workspace.push("bin")));
+ assert_executable_exists(&workspace, "foo");
+}
+
/// Returns true if p exists and is executable
fn is_executable(p: &Path) -> bool {
use std::libc::consts::os::posix88::{S_IXUSR};
use package_id::PkgId;
use package_source::PkgSrc;
use workspace::pkg_parent_workspaces;
-use path_util::{installed_library_in_workspace, U_RWX, rust_path};
+use path_util::{installed_library_in_workspace, U_RWX, rust_path, system_library, target_build_dir};
use messages::error;
pub use target::{OutputType, Main, Lib, Bench, Test};
// tjc: by default, use the package ID name as the link name
// not sure if we should support anything else
- let out_dir = workspace.push("build").push_rel(&pkg_id.path);
+ let out_dir = target_build_dir(workspace).push_rel(&pkg_id.path);
let binary = os::args()[0].to_managed();
None => sess.str_of(lib_ident)
};
debug!("Finding and installing... %s", lib_name);
- match installed_library_in_workspace(&Path(lib_name), &context.sysroot()) {
+ // Check standard Rust library path first
+ match system_library(&context.sysroot(), lib_name) {
Some(ref installed_path) => {
debug!("It exists: %s", installed_path.to_str());
// Say that [path for c] has a discovered dependency on