Skip to content

Commit c440743

Browse files
committed
auto merge of #7403 : catamorphism/rust/package-scripts, r=brson
r? @brson (or @graydon if available) rustpkg/api.rs provides functions intended for package scripts to call. It will probably need more functionality added to it later, but this is a start. Added a test case checking that a package script can use the API. Closes #6401
2 parents 0bad3e6 + 3789433 commit c440743

File tree

7 files changed

+166
-22
lines changed

7 files changed

+166
-22
lines changed

Diff for: src/librustc/driver/driver.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub struct compile_upto {
161161
#[deriving(Eq)]
162162
pub enum compile_phase {
163163
cu_parse,
164-
cu_expand,
164+
cu_expand, // means "it's already expanded"
165165
cu_typeck,
166166
cu_no_trans,
167167
cu_everything,

Diff for: src/librustpkg/api.rs

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use context::*;
12+
use crate::*;
13+
use package_id::*;
14+
use package_source::*;
15+
use version::Version;
16+
17+
use core::option::*;
18+
use core::os;
19+
use core::hashmap::*;
20+
use core::path::*;
21+
22+
/// Convenience functions intended for calling from pkg.rs
23+
24+
fn default_ctxt(p: @Path) -> Ctx {
25+
Ctx { sysroot_opt: Some(p), json: false, dep_cache: @mut HashMap::new() }
26+
}
27+
28+
pub fn build_lib(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Version,
29+
lib: Path) {
30+
31+
let pkg_src = PkgSrc {
32+
root: root,
33+
dst_dir: dest,
34+
id: PkgId{ version: version, ..PkgId::new(name)},
35+
libs: ~[mk_crate(lib)],
36+
mains: ~[],
37+
tests: ~[],
38+
benchs: ~[]
39+
};
40+
pkg_src.build(&default_ctxt(sysroot), pkg_src.dst_dir, ~[]);
41+
}
42+
43+
pub fn build_exe(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Version,
44+
main: Path) {
45+
let pkg_src = PkgSrc {
46+
root: root,
47+
dst_dir: dest,
48+
id: PkgId{ version: version, ..PkgId::new(name)},
49+
libs: ~[],
50+
mains: ~[mk_crate(main)],
51+
tests: ~[],
52+
benchs: ~[]
53+
};
54+
pkg_src.build(&default_ctxt(sysroot), pkg_src.dst_dir, ~[]);
55+
56+
}
57+
58+
pub fn install_lib(sysroot: @Path,
59+
workspace: Path,
60+
name: ~str,
61+
lib_path: Path,
62+
version: Version) {
63+
debug!("self_exe: %?", os::self_exe_path());
64+
debug!("sysroot = %s", sysroot.to_str());
65+
debug!("workspace = %s", workspace.to_str());
66+
// make a PkgSrc
67+
let pkg_id = PkgId{ version: version, ..PkgId::new(name)};
68+
let build_dir = workspace.push("build");
69+
let dst_dir = build_dir.push_rel(&*pkg_id.local_path);
70+
let pkg_src = PkgSrc {
71+
root: copy workspace,
72+
dst_dir: copy dst_dir,
73+
id: copy pkg_id,
74+
libs: ~[mk_crate(lib_path)],
75+
mains: ~[],
76+
tests: ~[],
77+
benchs: ~[]
78+
};
79+
let cx = default_ctxt(sysroot);
80+
pkg_src.build(&cx, dst_dir, ~[]);
81+
cx.install_no_build(&workspace, &pkg_id);
82+
}
83+
84+
pub fn install_exe(sysroot: @Path, workspace: Path, name: ~str, version: Version) {
85+
default_ctxt(sysroot).install(&workspace, &PkgId{ version: version,
86+
..PkgId::new(name)});
87+
88+
}
89+
90+
fn mk_crate(p: Path) -> Crate {
91+
Crate { file: p, flags: ~[], cfgs: ~[] }
92+
}

Diff for: src/librustpkg/rustpkg.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use context::Ctx;
4646
use package_id::PkgId;
4747
use package_source::PkgSrc;
4848

49+
pub mod api;
4950
mod conditions;
5051
mod context;
5152
mod crate;
@@ -104,8 +105,10 @@ impl<'self> PkgScript<'self> {
104105
let binary = os::args()[0].to_managed();
105106
// Build the rustc session data structures to pass
106107
// to the compiler
108+
debug!("pkgscript parse: %?", os::self_exe_path());
107109
let options = @session::options {
108110
binary: binary,
111+
maybe_sysroot: Some(@os::self_exe_path().get().pop()),
109112
crate_type: session::bin_crate,
110113
.. copy *session::basic_options()
111114
};
@@ -132,8 +135,7 @@ impl<'self> PkgScript<'self> {
132135
/// Returns a pair of an exit code and list of configs (obtained by
133136
/// calling the package script's configs() function if it exists
134137
// FIXME (#4432): Use workcache to only compile the script when changed
135-
fn run_custom(&self, what: ~str) -> (~[~str], ExitCode) {
136-
debug!("run_custom: %s", what);
138+
fn run_custom(&self, sysroot: @Path) -> (~[~str], ExitCode) {
137139
let sess = self.sess;
138140

139141
debug!("Working directory = %s", self.build_dir.to_str());
@@ -152,9 +154,12 @@ impl<'self> PkgScript<'self> {
152154
sess,
153155
crate,
154156
driver::build_configuration(sess,
155-
binary, &self.input));
156-
debug!("Running program: %s %s %s", exe.to_str(), root.to_str(), what);
157-
let status = run::process_status(exe.to_str(), [root.to_str(), what]);
157+
binary, &self.input),
158+
driver::cu_parse);
159+
debug!("Running program: %s %s %s %s", exe.to_str(),
160+
sysroot.to_str(), root.to_str(), "install");
161+
// FIXME #7401 should support commands besides `install`
162+
let status = run::process_status(exe.to_str(), [sysroot.to_str(), ~"install"]);
158163
if status != 0 {
159164
return (~[], status);
160165
}
@@ -291,10 +296,8 @@ impl Ctx {
291296
let pscript = PkgScript::parse(package_script_path,
292297
workspace,
293298
pkgid);
294-
// Limited right now -- we're only running the post_build
295-
// hook and probably fail otherwise
296-
// also post_build should be called pre_build
297-
let (cfgs, hook_result) = pscript.run_custom(~"post_build");
299+
let sysroot = self.sysroot_opt.expect("custom build needs a sysroot");
300+
let (cfgs, hook_result) = pscript.run_custom(sysroot);
298301
debug!("Command return code = %?", hook_result);
299302
if hook_result != 0 {
300303
fail!("Error running custom build command")
@@ -341,13 +344,17 @@ impl Ctx {
341344
}
342345

343346
fn install(&self, workspace: &Path, id: &PkgId) {
344-
use conditions::copy_failed::cond;
345-
346-
// Should use RUST_PATH in the future.
347+
// FIXME #7402: Use RUST_PATH to determine target dir
347348
// Also should use workcache to not build if not necessary.
348349
self.build(workspace, id);
349350
debug!("install: workspace = %s, id = %s", workspace.to_str(),
350351
id.to_str());
352+
self.install_no_build(workspace, id);
353+
354+
}
355+
356+
fn install_no_build(&self, workspace: &Path, id: &PkgId) {
357+
use conditions::copy_failed::cond;
351358

352359
// Now copy stuff into the install dirs
353360
let maybe_executable = built_executable_in_workspace(id, workspace);

Diff for: src/librustpkg/tests.rs

+16
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,22 @@ fn rustpkg_local_pkg() {
545545
assert_executable_exists(&dir, "foo");
546546
}
547547
548+
#[test]
549+
fn package_script_with_default_build() {
550+
let dir = create_local_package(&PkgId::new("fancy-lib"));
551+
debug!("dir = %s", dir.to_str());
552+
let source = test_sysroot().pop().pop().pop().push("src").push("librustpkg").
553+
push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs");
554+
debug!("package_script_with_default_build: %s", source.to_str());
555+
if !os::copy_file(&source,
556+
& dir.push("src").push("fancy_lib-0.1").push("pkg.rs")) {
557+
fail!("Couldn't copy file");
558+
}
559+
command_line_test([~"install", ~"fancy-lib"], &dir);
560+
assert_lib_exists(&dir, "fancy-lib");
561+
assert!(os::path_exists(&dir.push("build").push("fancy_lib").push("generated.rs")));
562+
}
563+
548564
#[test]
549565
#[ignore (reason = "RUST_PATH not yet implemented -- #5682")]
550566
fn rust_path_test() {

Diff for: src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs

+34-6
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,37 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use core::run;
11+
extern mod rustpkg;
12+
extern mod rustc;
13+
14+
use std::{io, os};
15+
use rustpkg::api;
16+
use rustpkg::version::NoVersion;
17+
18+
use rustc::metadata::filesearch;
1219

1320
pub fn main() {
14-
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
21+
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
22+
let args = os::args();
23+
24+
// by convention, first arg is sysroot
25+
if args.len() < 2 {
26+
fail!("Package script requires a directory where rustc libraries live as the first \
27+
argument");
28+
}
29+
30+
let sysroot_arg = copy args[1];
31+
let sysroot = Path(sysroot_arg);
32+
if !os::path_exists(&sysroot) {
33+
fail!("Package script requires a sysroot that exists; %s doesn't", sysroot.to_str());
34+
}
35+
36+
if args[2] != ~"install" {
37+
io::println(fmt!("Warning: I don't know how to %s", args[2]));
38+
return;
39+
}
1540

16-
let out_path = Path(~"build/fancy_lib");
41+
let out_path = Path("build/fancy_lib");
1742
if !os::path_exists(&out_path) {
1843
assert!(os::make_dir(&out_path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
1944
}
@@ -22,7 +47,10 @@ pub fn main() {
2247
[io::Create]).get();
2348
file.write_str("pub fn wheeeee() { for [1, 2, 3].each() |_| { assert!(true); } }");
2449

25-
// now compile the crate itself
26-
run::process_status("rustc", [~"src/fancy-lib/fancy-lib.rs", ~"--lib", ~"-o",
27-
out_path.push(~"fancy_lib").to_str()]);
50+
51+
debug!("api_____install_____lib, my sysroot:");
52+
debug!(sysroot.to_str());
53+
54+
api::install_lib(@sysroot, os::getcwd(), ~"fancy-lib", Path("lib.rs"),
55+
NoVersion);
2856
}

Diff for: src/librustpkg/util.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ pub fn compile_input(ctxt: &Ctx,
257257

258258
debug!("calling compile_crate_from_input, out_dir = %s,
259259
building_library = %?", out_dir.to_str(), sess.building_library);
260-
compile_crate_from_input(&input, out_dir, sess, crate, copy cfg);
260+
compile_crate_from_input(&input, out_dir, sess, crate, copy cfg, driver::cu_expand);
261261
true
262262
}
263263

@@ -270,7 +270,8 @@ pub fn compile_crate_from_input(input: &driver::input,
270270
build_dir: &Path,
271271
sess: session::Session,
272272
crate: @ast::crate,
273-
cfg: ast::crate_cfg) {
273+
cfg: ast::crate_cfg,
274+
compile_from: driver::compile_phase) {
274275
debug!("Calling build_output_filenames with %s, building library? %?",
275276
build_dir.to_str(), sess.building_library);
276277

@@ -287,7 +288,7 @@ pub fn compile_crate_from_input(input: &driver::input,
287288
driver::compile_rest(sess,
288289
cfg,
289290
compile_upto {
290-
from: driver::cu_expand,
291+
from: compile_from,
291292
to: driver::cu_everything
292293
},
293294
Some(outputs),

0 commit comments

Comments
 (0)