Skip to content

Commit 24fdb1d

Browse files
committed
rustc/rustpkg: Use a target-specific subdirectory in build/ and lib/
As per rustpkg.md, rustpkg now builds in a target-specific subdirectory of build/, and installs libraries into a target-specific subdirectory of lib. Closes #8672
1 parent 7c8f503 commit 24fdb1d

File tree

5 files changed

+109
-40
lines changed

5 files changed

+109
-40
lines changed

doc/rustpkg.md

+15-9
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,11 @@ A valid workspace must contain each of the following subdirectories:
5252
rustpkg will install libraries for bar to `foo/lib/x86_64-apple-darwin/`.
5353
The libraries will have names of the form `foo/lib/x86_64-apple-darwin/libbar-[hash].dylib`,
5454
where [hash] is a hash of the package ID.
55-
* 'bin/': `rustpkg install` installs executable binaries into a target-specific subdirectory of this directory.
55+
* 'bin/': `rustpkg install` installs executable binaries into this directory.
5656

57-
For example, on a 64-bit machine running Mac OS X,
58-
if `foo` is a workspace, containing the package `bar`,
59-
rustpkg will install executables for `bar` to
60-
`foo/bin/x86_64-apple-darwin/`.
61-
The executables will have names of the form `foo/bin/x86_64-apple-darwin/bar`.
57+
For example, rustpkg will install executables for `bar` to
58+
`foo/bin`.
59+
The executables will have names of the form `foo/bin/bar`.
6260
* 'build/': `rustpkg build` stores temporary build artifacts in a target-specific subdirectory of this directory.
6361

6462
For example, on a 64-bit machine running Mac OS X,
@@ -85,6 +83,12 @@ rustpkg also interprets any dependencies on such a package ID literally
8583
Thus, `github.com/mozilla/rust#5c4cd30f80` is also a valid package ID,
8684
since git can deduce that 5c4cd30f80 refers to a revision of the desired repository.
8785

86+
A package identifier can name a subdirectory of another package.
87+
For example, if `foo` is a workspace, and `foo/src/bar/lib.rs` exists,
88+
as well as `foo/src/bar/extras/baz/lib.rs`,
89+
then both `bar` and `bar/extras/baz` are valid package identifiers
90+
in the workspace `foo`.
91+
8892
## Source files
8993

9094
rustpkg searches for four different fixed filenames in order to determine the crates to build:
@@ -140,9 +144,11 @@ but not in their `lib` or `bin` directories.
140144

141145
## install
142146

143-
`rustpkg install foo` builds the libraries and/or executables that are targets for `foo`,
144-
and then installs them either into `foo`'s `lib` and `bin` directories,
145-
or into the `lib` and `bin` subdirectories of the first entry in `RUST_PATH`.
147+
`rustpkg install foo` builds the libraries and/or executables that are targets for `foo`.
148+
If `RUST_PATH` is declared as an environment variable, then rustpkg installs the
149+
libraries and executables into the `lib` and `bin` subdirectories
150+
of the first entry in `RUST_PATH`.
151+
Otherwise, it installs them into `foo`'s `lib` and `bin` directories.
146152

147153
## test
148154

src/librustc/metadata/filesearch.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>,
7777
if !found {
7878
let rustpath = rust_path();
7979
for path in rustpath.iter() {
80-
debug!("is %s in visited_dirs? %?",
81-
path.push("lib").to_str(),
82-
visited_dirs.contains(&path.push("lib").to_str()));
80+
let tlib_path = make_rustpkg_target_lib_path(path, self.target_triple);
81+
debug!("is %s in visited_dirs? %?", tlib_path.to_str(),
82+
visited_dirs.contains(&tlib_path.to_str()));
8383

84-
if !visited_dirs.contains(&path.push("lib").to_str()) {
85-
visited_dirs.insert(path.push("lib").to_str());
84+
if !visited_dirs.contains(&tlib_path.to_str()) {
85+
visited_dirs.insert(tlib_path.to_str());
8686
// Don't keep searching the RUST_PATH if one match turns up --
8787
// if we did, we'd get a "multiple matching crates" error
88-
match f(&path.push("lib")) {
88+
match f(&tlib_path) {
8989
FileMatches => {
9090
break;
9191
}
@@ -145,6 +145,11 @@ fn make_target_lib_path(sysroot: &Path,
145145
sysroot.push_rel(&relative_target_lib_path(target_triple))
146146
}
147147

148+
fn make_rustpkg_target_lib_path(dir: &Path,
149+
target_triple: &str) -> Path {
150+
dir.push_rel(&Path(libdir()).push(target_triple.to_owned()))
151+
}
152+
148153
fn get_or_default_sysroot() -> Path {
149154
match os::self_exe_path() {
150155
option::Some(ref p) => (*p).pop(),

src/librustpkg/path_util.rs

+42-11
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub use package_id::PkgId;
1414
pub use target::{OutputType, Main, Lib, Test, Bench, Target, Build, Install};
1515
pub use version::{Version, NoVersion, split_version_general, try_parsing_version};
1616
pub use rustc::metadata::filesearch::rust_path;
17+
use rustc::driver::driver::host_triple;
1718

1819
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
1920
use std::os::mkdir_recursive;
@@ -94,10 +95,29 @@ pub fn workspace_contains_package_id_(pkgid: &PkgId, workspace: &Path,
9495
found
9596
}
9697

98+
/// Return the target-specific build subdirectory, pushed onto `base`;
99+
/// doesn't check that it exists or create it
100+
pub fn target_build_dir(workspace: &Path) -> Path {
101+
workspace.push("build").push(host_triple())
102+
}
103+
104+
/// Return the target-specific lib subdirectory, pushed onto `base`;
105+
/// doesn't check that it exists or create it
106+
fn target_lib_dir(workspace: &Path) -> Path {
107+
workspace.push("lib").push(host_triple())
108+
}
109+
110+
/// Return the bin subdirectory, pushed onto `base`;
111+
/// doesn't check that it exists or create it
112+
/// note: this isn't target-specific
113+
fn target_bin_dir(workspace: &Path) -> Path {
114+
workspace.push("bin")
115+
}
116+
97117
/// Figure out what the executable name for <pkgid> in <workspace>'s build
98118
/// directory is, and if the file exists, return it.
99119
pub fn built_executable_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path> {
100-
let mut result = workspace.push("build");
120+
let mut result = target_build_dir(workspace);
101121
// should use a target-specific subdirectory
102122
result = mk_output_path(Main, Build, pkgid, result);
103123
debug!("built_executable_in_workspace: checking whether %s exists",
@@ -124,7 +144,7 @@ pub fn built_bench_in_workspace(pkgid: &PkgId, workspace: &Path) -> Option<Path>
124144
}
125145

126146
fn output_in_workspace(pkgid: &PkgId, workspace: &Path, what: OutputType) -> Option<Path> {
127-
let mut result = workspace.push("build");
147+
let mut result = target_build_dir(workspace);
128148
// should use a target-specific subdirectory
129149
result = mk_output_path(what, Build, pkgid, result);
130150
debug!("output_in_workspace: checking whether %s exists",
@@ -172,11 +192,21 @@ pub fn library_in_workspace(path: &Path, short_name: &str, where: Target,
172192
prefix = %s", short_name, where, workspace.to_str(), prefix);
173193

174194
let dir_to_search = match where {
175-
Build => workspace.push(prefix).push_rel(path),
176-
Install => workspace.push(prefix)
195+
Build => target_build_dir(workspace).push_rel(path),
196+
Install => target_lib_dir(workspace)
177197
};
198+
199+
library_in(short_name, version, &dir_to_search)
200+
}
201+
202+
// rustc doesn't use target-specific subdirectories
203+
pub fn system_library(sysroot: &Path, lib_name: &str) -> Option<Path> {
204+
library_in(lib_name, &NoVersion, &sysroot.push("lib"))
205+
}
206+
207+
fn library_in(short_name: &str, version: &Version, dir_to_search: &Path) -> Option<Path> {
178208
debug!("Listing directory %s", dir_to_search.to_str());
179-
let dir_contents = os::list_dir(&dir_to_search);
209+
let dir_contents = os::list_dir(dir_to_search);
180210
debug!("dir has %? entries", dir_contents.len());
181211

182212
let lib_prefix = fmt!("%s%s", os::consts::DLL_PREFIX, short_name);
@@ -298,9 +328,10 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path,
298328
};
299329
// Artifacts in the build directory live in a package-ID-specific subdirectory,
300330
// but installed ones don't.
301-
let result = match where {
302-
Build => workspace.push(subdir).push_rel(&pkgid.path),
303-
_ => workspace.push(subdir)
331+
let result = match (where, what) {
332+
(Build, _) => target_build_dir(workspace).push_rel(&pkgid.path),
333+
(Install, Lib) => target_lib_dir(workspace),
334+
(Install, _) => target_bin_dir(workspace)
304335
};
305336
if !os::path_exists(&result) && !mkdir_recursive(&result, U_RWX) {
306337
cond.raise((result.clone(), fmt!("target_file_in_workspace couldn't \
@@ -315,10 +346,10 @@ fn target_file_in_workspace(pkgid: &PkgId, workspace: &Path,
315346
pub fn build_pkg_id_in_workspace(pkgid: &PkgId, workspace: &Path) -> Path {
316347
use conditions::bad_path::cond;
317348

318-
let mut result = workspace.push("build");
319-
// n.b. Should actually use a target-specific
320-
// subdirectory of build/
349+
let mut result = target_build_dir(workspace);
321350
result = result.push_rel(&pkgid.path);
351+
debug!("Creating build dir %s for package id %s", result.to_str(),
352+
pkgid.to_str());
322353
if os::path_exists(&result) || os::mkdir_recursive(&result, U_RWX) {
323354
result
324355
}

src/librustpkg/tests.rs

+37-11
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use path_util::{target_executable_in_workspace, target_test_in_workspace,
2727
target_bench_in_workspace, make_dir_rwx, U_RWX,
2828
library_in_workspace, installed_library_in_workspace,
2929
built_bench_in_workspace, built_test_in_workspace,
30-
built_library_in_workspace, built_executable_in_workspace};
30+
built_library_in_workspace, built_executable_in_workspace, target_build_dir};
3131
use rustc::back::link::get_cc_prog;
3232
use rustc::metadata::filesearch::rust_path;
3333
use rustc::driver::driver::{build_session, build_session_options, host_triple, optgroups};
@@ -382,7 +382,7 @@ fn llvm_bitcode_file_exists(repo: &Path, short_name: &str) -> bool {
382382
}
383383

384384
fn file_exists(repo: &Path, short_name: &str, extension: &str) -> bool {
385-
os::path_exists(&repo.push_many([~"build", short_name.to_owned(),
385+
os::path_exists(&target_build_dir(repo).push_many([short_name.to_owned(),
386386
fmt!("%s.%s", short_name, extension)]))
387387
}
388388

@@ -433,7 +433,7 @@ fn lib_output_file_name(workspace: &Path, parent: &str, short_name: &str) -> Pat
433433
}
434434

435435
fn output_file_name(workspace: &Path, short_name: &str) -> Path {
436-
workspace.push("build").push(short_name).push(fmt!("%s%s", short_name, os::EXE_SUFFIX))
436+
target_build_dir(workspace).push(short_name).push(fmt!("%s%s", short_name, os::EXE_SUFFIX))
437437
}
438438

439439
fn touch_source_file(workspace: &Path, pkgid: &PkgId) {
@@ -657,11 +657,10 @@ fn test_package_version() {
657657
None => false
658658
});
659659
assert!(built_executable_in_workspace(&temp_pkg_id, &ws)
660-
== Some(ws.push("build").
661-
push("mockgithub.com").
662-
push("catamorphism").
663-
push("test_pkg_version").
664-
push("test_pkg_version")));
660+
== Some(target_build_dir(&ws).push_many([~"mockgithub.com",
661+
~"catamorphism",
662+
~"test_pkg_version",
663+
~"test_pkg_version"])));
665664
}
666665
667666
#[test]
@@ -755,7 +754,7 @@ fn package_script_with_default_build() {
755754
}
756755
command_line_test([~"install", ~"fancy-lib"], &dir);
757756
assert_lib_exists(&dir, &Path("fancy-lib"), NoVersion);
758-
assert!(os::path_exists(&dir.push("build").push("fancy-lib").push("generated.rs")));
757+
assert!(os::path_exists(&target_build_dir(&dir).push_many([~"fancy-lib", ~"generated.rs"])));
759758
}
760759
761760
#[test]
@@ -1121,7 +1120,7 @@ fn test_import_rustpkg() {
11211120
"extern mod rustpkg; fn main() {}");
11221121
command_line_test([~"build", ~"foo"], &workspace);
11231122
debug!("workspace = %s", workspace.to_str());
1124-
assert!(os::path_exists(&workspace.push("build").push("foo").push(fmt!("pkg%s",
1123+
assert!(os::path_exists(&target_build_dir(&workspace).push("foo").push(fmt!("pkg%s",
11251124
os::EXE_SUFFIX))));
11261125
}
11271126

@@ -1133,7 +1132,7 @@ fn test_macro_pkg_script() {
11331132
"extern mod rustpkg; fn main() { debug!(\"Hi\"); }");
11341133
command_line_test([~"build", ~"foo"], &workspace);
11351134
debug!("workspace = %s", workspace.to_str());
1136-
assert!(os::path_exists(&workspace.push("build").push("foo").push(fmt!("pkg%s",
1135+
assert!(os::path_exists(&target_build_dir(&workspace).push("foo").push(fmt!("pkg%s",
11371136
os::EXE_SUFFIX))));
11381137
}
11391138

@@ -1622,6 +1621,33 @@ fn test_install_to_rust_path() {
16221621
assert!(!executable_exists(&second_workspace, "foo"));
16231622
}
16241623
1624+
fn test_target_specific_build_dir() {
1625+
let p_id = PkgId::new("foo");
1626+
let workspace = create_local_package(&p_id);
1627+
command_line_test([test_sysroot().to_str(),
1628+
~"build",
1629+
~"foo"],
1630+
&workspace);
1631+
assert!(os::path_is_dir(&target_build_dir(&workspace)));
1632+
assert!(built_executable_exists(&workspace, "foo"));
1633+
assert!(os::list_dir(&workspace.push("build")).len() == 1);
1634+
}
1635+
1636+
#[test]
1637+
fn test_target_specific_install_dir() {
1638+
let p_id = PkgId::new("foo");
1639+
let workspace = create_local_package(&p_id);
1640+
command_line_test([test_sysroot().to_str(),
1641+
~"install",
1642+
~"foo"],
1643+
&workspace);
1644+
assert!(os::path_is_dir(&workspace.push("lib").push(host_triple())));
1645+
assert_lib_exists(&workspace, &Path("foo"), NoVersion);
1646+
assert!(os::list_dir(&workspace.push("lib")).len() == 1);
1647+
assert!(os::path_is_dir(&workspace.push("bin")));
1648+
assert_executable_exists(&workspace, "foo");
1649+
}
1650+
16251651
/// Returns true if p exists and is executable
16261652
fn is_executable(p: &Path) -> bool {
16271653
use std::libc::consts::os::posix88::{S_IXUSR};

src/librustpkg/util.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use context::{in_target, StopBefore, Link, Assemble, BuildContext};
2323
use package_id::PkgId;
2424
use package_source::PkgSrc;
2525
use workspace::pkg_parent_workspaces;
26-
use path_util::{installed_library_in_workspace, U_RWX, rust_path};
26+
use path_util::{installed_library_in_workspace, U_RWX, rust_path, system_library, target_build_dir};
2727
use messages::error;
2828

2929
pub use target::{OutputType, Main, Lib, Bench, Test};
@@ -170,7 +170,7 @@ pub fn compile_input(context: &BuildContext,
170170
// tjc: by default, use the package ID name as the link name
171171
// not sure if we should support anything else
172172

173-
let out_dir = workspace.push("build").push_rel(&pkg_id.path);
173+
let out_dir = target_build_dir(workspace).push_rel(&pkg_id.path);
174174

175175
let binary = os::args()[0].to_managed();
176176

@@ -381,7 +381,8 @@ pub fn find_and_install_dependencies(context: &BuildContext,
381381
None => sess.str_of(lib_ident)
382382
};
383383
debug!("Finding and installing... %s", lib_name);
384-
match installed_library_in_workspace(&Path(lib_name), &context.sysroot()) {
384+
// Check standard Rust library path first
385+
match system_library(&context.sysroot(), lib_name) {
385386
Some(ref installed_path) => {
386387
debug!("It exists: %s", installed_path.to_str());
387388
// Say that [path for c] has a discovered dependency on

0 commit comments

Comments
 (0)