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)]
|
#[deriving(Eq)]
|
||||||
pub enum compile_phase {
|
pub enum compile_phase {
|
||||||
cu_parse,
|
cu_parse,
|
||||||
cu_expand,
|
cu_expand, // means "it's already expanded"
|
||||||
cu_typeck,
|
cu_typeck,
|
||||||
cu_no_trans,
|
cu_no_trans,
|
||||||
cu_everything,
|
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 context::Ctx;
|
|||||||
use package_id::PkgId;
|
use package_id::PkgId;
|
||||||
use package_source::PkgSrc;
|
use package_source::PkgSrc;
|
||||||
|
|
||||||
|
pub mod api;
|
||||||
mod conditions;
|
mod conditions;
|
||||||
mod context;
|
mod context;
|
||||||
mod crate;
|
mod crate;
|
||||||
@ -104,8 +105,10 @@ impl<'self> PkgScript<'self> {
|
|||||||
let binary = os::args()[0].to_managed();
|
let binary = os::args()[0].to_managed();
|
||||||
// Build the rustc session data structures to pass
|
// Build the rustc session data structures to pass
|
||||||
// to the compiler
|
// to the compiler
|
||||||
|
debug!("pkgscript parse: %?", os::self_exe_path());
|
||||||
let options = @session::options {
|
let options = @session::options {
|
||||||
binary: binary,
|
binary: binary,
|
||||||
|
maybe_sysroot: Some(@os::self_exe_path().get().pop()),
|
||||||
crate_type: session::bin_crate,
|
crate_type: session::bin_crate,
|
||||||
.. copy *session::basic_options()
|
.. copy *session::basic_options()
|
||||||
};
|
};
|
||||||
@ -132,8 +135,7 @@ impl<'self> PkgScript<'self> {
|
|||||||
/// Returns a pair of an exit code and list of configs (obtained by
|
/// Returns a pair of an exit code and list of configs (obtained by
|
||||||
/// calling the package script's configs() function if it exists
|
/// calling the package script's configs() function if it exists
|
||||||
// FIXME (#4432): Use workcache to only compile the script when changed
|
// FIXME (#4432): Use workcache to only compile the script when changed
|
||||||
fn run_custom(&self, what: ~str) -> (~[~str], ExitCode) {
|
fn run_custom(&self, sysroot: @Path) -> (~[~str], ExitCode) {
|
||||||
debug!("run_custom: %s", what);
|
|
||||||
let sess = self.sess;
|
let sess = self.sess;
|
||||||
|
|
||||||
debug!("Working directory = %s", self.build_dir.to_str());
|
debug!("Working directory = %s", self.build_dir.to_str());
|
||||||
@ -152,9 +154,12 @@ impl<'self> PkgScript<'self> {
|
|||||||
sess,
|
sess,
|
||||||
crate,
|
crate,
|
||||||
driver::build_configuration(sess,
|
driver::build_configuration(sess,
|
||||||
binary, &self.input));
|
binary, &self.input),
|
||||||
debug!("Running program: %s %s %s", exe.to_str(), root.to_str(), what);
|
driver::cu_parse);
|
||||||
let status = run::process_status(exe.to_str(), [root.to_str(), what]);
|
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 {
|
if status != 0 {
|
||||||
return (~[], status);
|
return (~[], status);
|
||||||
}
|
}
|
||||||
@ -291,10 +296,8 @@ impl Ctx {
|
|||||||
let pscript = PkgScript::parse(package_script_path,
|
let pscript = PkgScript::parse(package_script_path,
|
||||||
workspace,
|
workspace,
|
||||||
pkgid);
|
pkgid);
|
||||||
// Limited right now -- we're only running the post_build
|
let sysroot = self.sysroot_opt.expect("custom build needs a sysroot");
|
||||||
// hook and probably fail otherwise
|
let (cfgs, hook_result) = pscript.run_custom(sysroot);
|
||||||
// also post_build should be called pre_build
|
|
||||||
let (cfgs, hook_result) = pscript.run_custom(~"post_build");
|
|
||||||
debug!("Command return code = %?", hook_result);
|
debug!("Command return code = %?", hook_result);
|
||||||
if hook_result != 0 {
|
if hook_result != 0 {
|
||||||
fail!("Error running custom build command")
|
fail!("Error running custom build command")
|
||||||
@ -341,13 +344,17 @@ impl Ctx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn install(&self, workspace: &Path, id: &PkgId) {
|
fn install(&self, workspace: &Path, id: &PkgId) {
|
||||||
use conditions::copy_failed::cond;
|
// FIXME #7402: Use RUST_PATH to determine target dir
|
||||||
|
|
||||||
// Should use RUST_PATH in the future.
|
|
||||||
// Also should use workcache to not build if not necessary.
|
// Also should use workcache to not build if not necessary.
|
||||||
self.build(workspace, id);
|
self.build(workspace, id);
|
||||||
debug!("install: workspace = %s, id = %s", workspace.to_str(),
|
debug!("install: workspace = %s, id = %s", workspace.to_str(),
|
||||||
id.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
|
// Now copy stuff into the install dirs
|
||||||
let maybe_executable = built_executable_in_workspace(id, workspace);
|
let maybe_executable = built_executable_in_workspace(id, workspace);
|
||||||
|
@ -545,6 +545,22 @@ fn rustpkg_local_pkg() {
|
|||||||
assert_executable_exists(&dir, "foo");
|
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]
|
#[test]
|
||||||
#[ignore (reason = "RUST_PATH not yet implemented -- #5682")]
|
#[ignore (reason = "RUST_PATH not yet implemented -- #5682")]
|
||||||
fn rust_path_test() {
|
fn rust_path_test() {
|
||||||
|
@ -8,12 +8,37 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// 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() {
|
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) {
|
if !os::path_exists(&out_path) {
|
||||||
assert!(os::make_dir(&out_path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
|
assert!(os::make_dir(&out_path, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
|
||||||
}
|
}
|
||||||
@ -22,7 +47,10 @@ pub fn main() {
|
|||||||
[io::Create]).get();
|
[io::Create]).get();
|
||||||
file.write_str("pub fn wheeeee() { for [1, 2, 3].each() |_| { assert!(true); } }");
|
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",
|
debug!("api_____install_____lib, my sysroot:");
|
||||||
out_path.push(~"fancy_lib").to_str()]);
|
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,
|
debug!("calling compile_crate_from_input, out_dir = %s,
|
||||||
building_library = %?", out_dir.to_str(), sess.building_library);
|
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
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +270,8 @@ pub fn compile_crate_from_input(input: &driver::input,
|
|||||||
build_dir: &Path,
|
build_dir: &Path,
|
||||||
sess: session::Session,
|
sess: session::Session,
|
||||||
crate: @ast::crate,
|
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? %?",
|
debug!("Calling build_output_filenames with %s, building library? %?",
|
||||||
build_dir.to_str(), sess.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,
|
driver::compile_rest(sess,
|
||||||
cfg,
|
cfg,
|
||||||
compile_upto {
|
compile_upto {
|
||||||
from: driver::cu_expand,
|
from: compile_from,
|
||||||
to: driver::cu_everything
|
to: driver::cu_everything
|
||||||
},
|
},
|
||||||
Some(outputs),
|
Some(outputs),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user