From 3789433b4f588301140c97bb5b67094a8c8576cc Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Tue, 25 Jun 2013 22:26:22 -0700 Subject: [PATCH] rustpkg: Begin allowing package scripts to call the default build logic 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 --- src/librustc/driver/driver.rs | 2 +- src/librustpkg/api.rs | 92 +++++++++++++++++++ src/librustpkg/rustpkg.rs | 31 ++++--- src/librustpkg/tests.rs | 16 ++++ .../src/fancy-lib/{fancy-lib.rs => lib.rs} | 0 .../testsuite/pass/src/fancy-lib/pkg.rs | 40 ++++++-- src/librustpkg/util.rs | 7 +- 7 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 src/librustpkg/api.rs rename src/librustpkg/testsuite/pass/src/fancy-lib/{fancy-lib.rs => lib.rs} (100%) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index fbb273450df29..88134b9ea3d6a 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -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, diff --git a/src/librustpkg/api.rs b/src/librustpkg/api.rs new file mode 100644 index 0000000000000..9f8e925fa0759 --- /dev/null +++ b/src/librustpkg/api.rs @@ -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 or the MIT license +// , 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: ~[] } +} \ No newline at end of file diff --git a/src/librustpkg/rustpkg.rs b/src/librustpkg/rustpkg.rs index 9242e450e2499..d70428e733858 100644 --- a/src/librustpkg/rustpkg.rs +++ b/src/librustpkg/rustpkg.rs @@ -46,6 +46,7 @@ use context::Ctx; use package_id::PkgId; use package_source::PkgSrc; +pub mod api; mod conditions; mod context; mod crate; @@ -104,8 +105,10 @@ impl<'self> PkgScript<'self> { 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 @@ impl<'self> PkgScript<'self> { /// 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 @@ impl<'self> PkgScript<'self> { 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 @@ impl Ctx { 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 @@ impl Ctx { } 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); diff --git a/src/librustpkg/tests.rs b/src/librustpkg/tests.rs index 973b960008be4..65c9c67f3f5fe 100644 --- a/src/librustpkg/tests.rs +++ b/src/librustpkg/tests.rs @@ -546,6 +546,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() { diff --git a/src/librustpkg/testsuite/pass/src/fancy-lib/fancy-lib.rs b/src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs similarity index 100% rename from src/librustpkg/testsuite/pass/src/fancy-lib/fancy-lib.rs rename to src/librustpkg/testsuite/pass/src/fancy-lib/lib.rs diff --git a/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs b/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs index 2d3a75d9197bf..009f37c8a49e7 100644 --- a/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs +++ b/src/librustpkg/testsuite/pass/src/fancy-lib/pkg.rs @@ -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(); + +// 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"); + 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); } \ No newline at end of file diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 6d39495002a4e..92cc5bbd2c1db 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -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),