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
This commit is contained in:
commit
c440743dcc
@ -161,7 +161,7 @@ pub struct compile_upto {
|
||||
#[deriving(Eq)]
|
||||
pub enum compile_phase {
|
||||
cu_parse,
|
||||
cu_expand,
|
||||
cu_expand, // means "it's already expanded"
|
||||
cu_typeck,
|
||||
cu_no_trans,
|
||||
cu_everything,
|
||||
|
92
src/librustpkg/api.rs
Normal file
92
src/librustpkg/api.rs
Normal file
@ -0,0 +1,92 @@
|
||||
// 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.
|
||||
|
||||
use context::*;
|
||||
use crate::*;
|
||||
use package_id::*;
|
||||
use package_source::*;
|
||||
use version::Version;
|
||||
|
||||
use core::option::*;
|
||||
use core::os;
|
||||
use core::hashmap::*;
|
||||
use core::path::*;
|
||||
|
||||
/// Convenience functions intended for calling from pkg.rs
|
||||
|
||||
fn default_ctxt(p: @Path) -> Ctx {
|
||||
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,
|
||||
lib: Path) {
|
||||
|
||||
let pkg_src = PkgSrc {
|
||||
root: root,
|
||||
dst_dir: dest,
|
||||
id: PkgId{ version: version, ..PkgId::new(name)},
|
||||
libs: ~[mk_crate(lib)],
|
||||
mains: ~[],
|
||||
tests: ~[],
|
||||
benchs: ~[]
|
||||
};
|
||||
pkg_src.build(&default_ctxt(sysroot), pkg_src.dst_dir, ~[]);
|
||||
}
|
||||
|
||||
pub fn build_exe(sysroot: @Path, root: Path, dest: Path, name: ~str, version: Version,
|
||||
main: Path) {
|
||||
let pkg_src = PkgSrc {
|
||||
root: root,
|
||||
dst_dir: dest,
|
||||
id: PkgId{ version: version, ..PkgId::new(name)},
|
||||
libs: ~[],
|
||||
mains: ~[mk_crate(main)],
|
||||
tests: ~[],
|
||||
benchs: ~[]
|
||||
};
|
||||
pkg_src.build(&default_ctxt(sysroot), pkg_src.dst_dir, ~[]);
|
||||
|
||||
}
|
||||
|
||||
pub fn install_lib(sysroot: @Path,
|
||||
workspace: Path,
|
||||
name: ~str,
|
||||
lib_path: Path,
|
||||
version: Version) {
|
||||
debug!("self_exe: %?", os::self_exe_path());
|
||||
debug!("sysroot = %s", sysroot.to_str());
|
||||
debug!("workspace = %s", workspace.to_str());
|
||||
// make a PkgSrc
|
||||
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 {
|
||||
root: copy workspace,
|
||||
dst_dir: copy dst_dir,
|
||||
id: copy pkg_id,
|
||||
libs: ~[mk_crate(lib_path)],
|
||||
mains: ~[],
|
||||
tests: ~[],
|
||||
benchs: ~[]
|
||||
};
|
||||
let cx = default_ctxt(sysroot);
|
||||
pkg_src.build(&cx, dst_dir, ~[]);
|
||||
cx.install_no_build(&workspace, &pkg_id);
|
||||
}
|
||||
|
||||
pub fn install_exe(sysroot: @Path, workspace: Path, name: ~str, version: Version) {
|
||||
default_ctxt(sysroot).install(&workspace, &PkgId{ version: version,
|
||||
..PkgId::new(name)});
|
||||
|
||||
}
|
||||
|
||||
fn mk_crate(p: Path) -> Crate {
|
||||
Crate { file: p, flags: ~[], cfgs: ~[] }
|
||||
}
|
@ -46,6 +46,7 @@
|
||||
use package_id::PkgId;
|
||||
use package_source::PkgSrc;
|
||||
|
||||
pub mod api;
|
||||
mod conditions;
|
||||
mod context;
|
||||
mod crate;
|
||||
@ -104,8 +105,10 @@ fn parse<'a>(script: Path, workspace: &Path, id: &'a PkgId) -> PkgScript<'a> {
|
||||
let binary = os::args()[0].to_managed();
|
||||
// Build the rustc session data structures to pass
|
||||
// to the compiler
|
||||
debug!("pkgscript parse: %?", os::self_exe_path());
|
||||
let options = @session::options {
|
||||
binary: binary,
|
||||
maybe_sysroot: Some(@os::self_exe_path().get().pop()),
|
||||
crate_type: session::bin_crate,
|
||||
.. copy *session::basic_options()
|
||||
};
|
||||
@ -132,8 +135,7 @@ fn parse<'a>(script: Path, workspace: &Path, id: &'a PkgId) -> PkgScript<'a> {
|
||||
/// Returns a pair of an exit code and list of configs (obtained by
|
||||
/// calling the package script's configs() function if it exists
|
||||
// FIXME (#4432): Use workcache to only compile the script when changed
|
||||
fn run_custom(&self, what: ~str) -> (~[~str], ExitCode) {
|
||||
debug!("run_custom: %s", what);
|
||||
fn run_custom(&self, sysroot: @Path) -> (~[~str], ExitCode) {
|
||||
let sess = self.sess;
|
||||
|
||||
debug!("Working directory = %s", self.build_dir.to_str());
|
||||
@ -152,9 +154,12 @@ fn run_custom(&self, what: ~str) -> (~[~str], ExitCode) {
|
||||
sess,
|
||||
crate,
|
||||
driver::build_configuration(sess,
|
||||
binary, &self.input));
|
||||
debug!("Running program: %s %s %s", exe.to_str(), root.to_str(), what);
|
||||
let status = run::process_status(exe.to_str(), [root.to_str(), what]);
|
||||
binary, &self.input),
|
||||
driver::cu_parse);
|
||||
debug!("Running program: %s %s %s %s", exe.to_str(),
|
||||
sysroot.to_str(), root.to_str(), "install");
|
||||
// FIXME #7401 should support commands besides `install`
|
||||
let status = run::process_status(exe.to_str(), [sysroot.to_str(), ~"install"]);
|
||||
if status != 0 {
|
||||
return (~[], status);
|
||||
}
|
||||
@ -291,10 +296,8 @@ fn build(&self, workspace: &Path, pkgid: &PkgId) {
|
||||
let pscript = PkgScript::parse(package_script_path,
|
||||
workspace,
|
||||
pkgid);
|
||||
// Limited right now -- we're only running the post_build
|
||||
// hook and probably fail otherwise
|
||||
// also post_build should be called pre_build
|
||||
let (cfgs, hook_result) = pscript.run_custom(~"post_build");
|
||||
let sysroot = self.sysroot_opt.expect("custom build needs a sysroot");
|
||||
let (cfgs, hook_result) = pscript.run_custom(sysroot);
|
||||
debug!("Command return code = %?", hook_result);
|
||||
if hook_result != 0 {
|
||||
fail!("Error running custom build command")
|
||||
@ -341,13 +344,17 @@ fn info(&self) {
|
||||
}
|
||||
|
||||
fn install(&self, workspace: &Path, id: &PkgId) {
|
||||
use conditions::copy_failed::cond;
|
||||
|
||||
// Should use RUST_PATH in the future.
|
||||
// FIXME #7402: Use RUST_PATH to determine target dir
|
||||
// Also should use workcache to not build if not necessary.
|
||||
self.build(workspace, id);
|
||||
debug!("install: workspace = %s, id = %s", workspace.to_str(),
|
||||
id.to_str());
|
||||
self.install_no_build(workspace, id);
|
||||
|
||||
}
|
||||
|
||||
fn install_no_build(&self, workspace: &Path, id: &PkgId) {
|
||||
use conditions::copy_failed::cond;
|
||||
|
||||
// Now copy stuff into the install dirs
|
||||
let maybe_executable = built_executable_in_workspace(id, workspace);
|
||||
|
@ -545,6 +545,22 @@ fn rustpkg_local_pkg() {
|
||||
assert_executable_exists(&dir, "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn package_script_with_default_build() {
|
||||
let dir = create_local_package(&PkgId::new("fancy-lib"));
|
||||
debug!("dir = %s", dir.to_str());
|
||||
let source = test_sysroot().pop().pop().pop().push("src").push("librustpkg").
|
||||
push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs");
|
||||
debug!("package_script_with_default_build: %s", source.to_str());
|
||||
if !os::copy_file(&source,
|
||||
& dir.push("src").push("fancy_lib-0.1").push("pkg.rs")) {
|
||||
fail!("Couldn't copy file");
|
||||
}
|
||||
command_line_test([~"install", ~"fancy-lib"], &dir);
|
||||
assert_lib_exists(&dir, "fancy-lib");
|
||||
assert!(os::path_exists(&dir.push("build").push("fancy_lib").push("generated.rs")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore (reason = "RUST_PATH not yet implemented -- #5682")]
|
||||
fn rust_path_test() {
|
||||
|
@ -8,12 +8,37 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use core::run;
|
||||
extern mod rustpkg;
|
||||
extern mod rustc;
|
||||
|
||||
use std::{io, os};
|
||||
use rustpkg::api;
|
||||
use rustpkg::version::NoVersion;
|
||||
|
||||
use rustc::metadata::filesearch;
|
||||
|
||||
pub fn main() {
|
||||
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
|
||||
let args = os::args();
|
||||
|
||||
let out_path = Path(~"build/fancy_lib");
|
||||
// by convention, first arg is sysroot
|
||||
if args.len() < 2 {
|
||||
fail!("Package script requires a directory where rustc libraries live as the first \
|
||||
argument");
|
||||
}
|
||||
|
||||
let sysroot_arg = copy args[1];
|
||||
let sysroot = Path(sysroot_arg);
|
||||
if !os::path_exists(&sysroot) {
|
||||
fail!("Package script requires a sysroot that exists; %s doesn't", sysroot.to_str());
|
||||
}
|
||||
|
||||
if args[2] != ~"install" {
|
||||
io::println(fmt!("Warning: I don't know how to %s", args[2]));
|
||||
return;
|
||||
}
|
||||
|
||||
let out_path = Path("build/fancy_lib");
|
||||
if !os::path_exists(&out_path) {
|
||||
assert!(os::make_dir(&out_path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
|
||||
}
|
||||
@ -22,7 +47,10 @@ pub fn main() {
|
||||
[io::Create]).get();
|
||||
file.write_str("pub fn wheeeee() { for [1, 2, 3].each() |_| { assert!(true); } }");
|
||||
|
||||
// now compile the crate itself
|
||||
run::process_status("rustc", [~"src/fancy-lib/fancy-lib.rs", ~"--lib", ~"-o",
|
||||
out_path.push(~"fancy_lib").to_str()]);
|
||||
|
||||
debug!("api_____install_____lib, my sysroot:");
|
||||
debug!(sysroot.to_str());
|
||||
|
||||
api::install_lib(@sysroot, os::getcwd(), ~"fancy-lib", Path("lib.rs"),
|
||||
NoVersion);
|
||||
}
|
@ -257,7 +257,7 @@ pub fn compile_input(ctxt: &Ctx,
|
||||
|
||||
debug!("calling compile_crate_from_input, out_dir = %s,
|
||||
building_library = %?", out_dir.to_str(), sess.building_library);
|
||||
compile_crate_from_input(&input, out_dir, sess, crate, copy cfg);
|
||||
compile_crate_from_input(&input, out_dir, sess, crate, copy cfg, driver::cu_expand);
|
||||
true
|
||||
}
|
||||
|
||||
@ -270,7 +270,8 @@ pub fn compile_crate_from_input(input: &driver::input,
|
||||
build_dir: &Path,
|
||||
sess: session::Session,
|
||||
crate: @ast::crate,
|
||||
cfg: ast::crate_cfg) {
|
||||
cfg: ast::crate_cfg,
|
||||
compile_from: driver::compile_phase) {
|
||||
debug!("Calling build_output_filenames with %s, building library? %?",
|
||||
build_dir.to_str(), sess.building_library);
|
||||
|
||||
@ -287,7 +288,7 @@ pub fn compile_crate_from_input(input: &driver::input,
|
||||
driver::compile_rest(sess,
|
||||
cfg,
|
||||
compile_upto {
|
||||
from: driver::cu_expand,
|
||||
from: compile_from,
|
||||
to: driver::cu_everything
|
||||
},
|
||||
Some(outputs),
|
||||
|
Loading…
Reference in New Issue
Block a user