Skip to content

Commit

Permalink
rustpkg: Support arbitrary dependencies in the install API
Browse files Browse the repository at this point in the history
api::install_pkg now accepts an argument that's a list of
(kind, path) dependency pairs. This allows custom package scripts to
declare C dependencies, as is demonstrated in
rustpkg::tests::test_c_dependency_ok.

Closes #6403
  • Loading branch information
catamorphism committed Oct 23, 2013
1 parent 22a5ebd commit c979575
Show file tree
Hide file tree
Showing 16 changed files with 514 additions and 104 deletions.
1 change: 1 addition & 0 deletions mk/tests.mk
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ $(3)/stage$(1)/test/rustpkgtest-$(2)$$(X_$(2)): \
$$(SREQ$(1)_T_$(2)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC_$(2)) \
$$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(2)) \
$$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$$(X_$(2)) \
$$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(2))
@$$(call E, compile_and_link: $$@)
Expand Down
96 changes: 86 additions & 10 deletions src/librustpkg/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,35 @@ use context::*;
use crate::*;
use package_id::*;
use package_source::*;
use path_util::{platform_library_name, target_build_dir};
use target::*;
use version::Version;
use workspace::pkg_parent_workspaces;
use workcache_support::*;
pub use path_util::default_workspace;

pub use source_control::{safe_git_clone, git_clone_url};

use std::os;
use std::{os, run};
use extra::arc::{Arc,RWArc};
use extra::workcache;
use extra::workcache::{Database, Logger, FreshnessMap};
use extra::treemap::TreeMap;

// A little sad -- duplicated from rustc::back::*
#[cfg(target_arch = "arm")]
fn cc_args() -> ~[~str] { ~[~"-marm"] }
#[cfg(target_arch = "mips")]
fn cc_args() -> ~[~str] { ~[] }
#[cfg(target_arch = "x86")]
fn cc_args() -> ~[~str] { ~[~"-m32"] }
#[cfg(target_arch = "x86_64")]
fn cc_args() -> ~[~str] { ~[~"-m64"] }

/// Convenience functions intended for calling from pkg.rs
/// p is where to put the cache file for dependencies
pub fn default_context(p: Path) -> BuildContext {
new_default_context(new_workcache_context(&p), p)
pub fn default_context(sysroot: Path, p: Path) -> BuildContext {
new_default_context(new_workcache_context(&p), sysroot)
}

pub fn new_default_context(c: workcache::Context, p: Path) -> BuildContext {
Expand Down Expand Up @@ -68,7 +81,7 @@ pub fn new_workcache_context(p: &Path) -> workcache::Context {

pub fn build_lib(sysroot: Path, root: Path, name: ~str, version: Version,
lib: Path) {
let cx = default_context(sysroot);
let cx = default_context(sysroot, root.clone());
let pkg_src = PkgSrc {
source_workspace: root.clone(),
build_in_destination: false,
Expand All @@ -81,12 +94,12 @@ pub fn build_lib(sysroot: Path, root: Path, name: ~str, version: Version,
tests: ~[],
benchs: ~[]
};
pkg_src.build(&cx, ~[]);
pkg_src.build(&cx, ~[], []);
}

pub fn build_exe(sysroot: Path, root: Path, name: ~str, version: Version,
main: Path) {
let cx = default_context(sysroot);
let cx = default_context(sysroot, root.clone());
let pkg_src = PkgSrc {
source_workspace: root.clone(),
build_in_destination: false,
Expand All @@ -100,13 +113,76 @@ pub fn build_exe(sysroot: Path, root: Path, name: ~str, version: Version,
benchs: ~[]
};

pkg_src.build(&cx, ~[]);
pkg_src.build(&cx, ~[], []);
}

pub fn install_pkg(sysroot: Path, workspace: Path, name: ~str, version: Version) {
let cx = default_context(sysroot);
pub fn install_pkg(cx: &BuildContext,
workspace: Path,
name: ~str,
version: Version,
// For now, these inputs are assumed to be inputs to each of the crates
more_inputs: ~[(~str, Path)]) { // pairs of Kind and Path
let pkgid = PkgId{ version: version, ..PkgId::new(name)};
cx.install(PkgSrc::new(workspace.clone(), workspace, false, pkgid), &Everything);
cx.install(PkgSrc::new(workspace.clone(), workspace, false, pkgid),
&WhatToBuild{ build_type: Inferred,
inputs_to_discover: more_inputs,
sources: Everything });
}

/// Builds an arbitrary library whose short name is `output`,
/// by invoking `tool` with arguments `args` plus "-o %s", where %s
/// is the platform-specific library name for `output`.
/// Returns that platform-specific name.
pub fn build_library_in_workspace(exec: &mut workcache::Exec,
context: &mut Context,
package_name: &str,
tool: &str,
flags: &[~str],
paths: &[~str],
output: &str) -> ~str {
use command_failed = conditions::command_failed::cond;

let workspace = my_workspace(context, package_name);
let workspace_build_dir = target_build_dir(&workspace);
let out_name = workspace_build_dir.join_many([package_name.to_str(),
platform_library_name(output)]);
// make paths absolute
let pkgid = PkgId::new(package_name);
let absolute_paths = paths.map(|s| {
let whatever = workspace.join_many([~"src",
pkgid.to_str(),
s.to_owned()]);
whatever.as_str().unwrap().to_owned()
});

let cc_args = cc_args();

let all_args = flags + absolute_paths + cc_args +
~[~"-o", out_name.as_str().unwrap().to_owned()];
let exit_code = run::process_status(tool, all_args);
if exit_code != 0 {
command_failed.raise((tool.to_owned(), all_args, exit_code))
}
else {
let out_name_str = out_name.as_str().unwrap().to_owned();
exec.discover_output("binary",
out_name_str,
digest_only_date(&out_name));
context.add_library_path(out_name.dir_path());
out_name_str
}
}

pub fn my_workspace(context: &Context, package_name: &str) -> Path {
use bad_pkg_id = conditions::bad_pkg_id::cond;

// (this assumes no particular version is requested)
let pkgid = PkgId::new(package_name);
let workspaces = pkg_parent_workspaces(context, &pkgid);
if workspaces.is_empty() {
bad_pkg_id.raise((Path::new(package_name), package_name.to_owned()));
}
workspaces[0]
}

fn mk_crate(p: Path) -> Crate {
Expand Down
6 changes: 6 additions & 0 deletions src/librustpkg/conditions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,9 @@ condition! {
condition! {
pub git_checkout_failed: (~str, Path) -> ();
}

condition! {
// str is output of applying the command (first component)
// to the args (second component)
pub command_failed: (~str, ~[~str], int) -> ~str;
}
18 changes: 18 additions & 0 deletions src/librustpkg/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ impl BuildContext {
pub fn compile_upto(&self) -> StopBefore {
self.context.compile_upto()
}

pub fn add_library_path(&mut self, p: Path) {
debug!("Adding library path: {}", p.display());
self.context.add_library_path(p);
}

pub fn additional_library_paths(&self) -> ~[Path] {
self.context.rustc_flags.additional_library_paths.clone()
}
}

/*
Expand Down Expand Up @@ -85,6 +94,9 @@ pub struct RustcFlags {
target: Option<~str>,
// Target CPU (defaults to rustc's default target CPU)
target_cpu: Option<~str>,
// Additional library directories, which get passed with the -L flag
// This can't be set with a rustpkg flag, only from package scripts
additional_library_paths: ~[Path],
// Any -Z features
experimental_features: Option<~[~str]>
}
Expand All @@ -99,6 +111,7 @@ impl Clone for RustcFlags {
save_temps: self.save_temps,
target: self.target.clone(),
target_cpu: self.target_cpu.clone(),
additional_library_paths: self.additional_library_paths.clone(),
experimental_features: self.experimental_features.clone()
}
}
Expand Down Expand Up @@ -148,6 +161,10 @@ impl Context {
pub fn compile_upto(&self) -> StopBefore {
self.rustc_flags.compile_upto
}

pub fn add_library_path(&mut self, p: Path) {
self.rustc_flags.additional_library_paths.push(p);
}
}

/// We assume that if ../../rustc exists, then we're running
Expand Down Expand Up @@ -210,6 +227,7 @@ impl RustcFlags {
save_temps: false,
target: None,
target_cpu: None,
additional_library_paths: ~[],
experimental_features: None
}
}
Expand Down
52 changes: 43 additions & 9 deletions src/librustpkg/package_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use path_util::{find_dir_using_rust_path_hack, make_dir_rwx_recursive, default_w
use path_util::{target_build_dir, versionize, dir_has_crate_file};
use util::{compile_crate, DepMap};
use workcache_support;
use workcache_support::crate_tag;
use workcache_support::{digest_only_date, digest_file_with_date, crate_tag};
use extra::workcache;
use extra::treemap::TreeMap;

Expand Down Expand Up @@ -390,7 +390,8 @@ impl PkgSrc {
deps: &mut DepMap,
crates: &[Crate],
cfgs: &[~str],
what: OutputType) {
what: OutputType,
inputs_to_discover: &[(~str, Path)]) {
for crate in crates.iter() {
let path = self.start_dir.join(&crate.file);
debug!("build_crates: compiling {}", path.display());
Expand All @@ -408,7 +409,19 @@ impl PkgSrc {
let sub_dir = self.build_workspace().clone();
let sub_flags = crate.flags.clone();
let sub_deps = deps.clone();
let inputs = inputs_to_discover.map(|&(ref k, ref p)|
(k.clone(), p.as_str().unwrap().to_owned()));
do prep.exec |exec| {
for &(ref kind, ref p) in inputs.iter() {
let pth = Path::new(p.clone());
exec.discover_input(*kind, *p, if *kind == ~"file" {
digest_file_with_date(&pth)
} else if *kind == ~"binary" {
digest_only_date(&Path::new(p.clone()))
} else {
fail!("Bad kind in build_crates")
});
}
let result = compile_crate(&subcx,
exec,
&id,
Expand Down Expand Up @@ -452,22 +465,43 @@ impl PkgSrc {
build_context: &BuildContext,
// DepMap is a map from str (crate name) to (kind, name) --
// it tracks discovered dependencies per-crate
cfgs: ~[~str]) -> DepMap {
cfgs: ~[~str],
inputs_to_discover: &[(~str, Path)]) -> DepMap {
let mut deps = TreeMap::new();

let libs = self.libs.clone();
let mains = self.mains.clone();
let tests = self.tests.clone();
let benchs = self.benchs.clone();
debug!("Building libs in {}, destination = {}",
self.source_workspace.display(), self.build_workspace().display());
self.build_crates(build_context, &mut deps, libs, cfgs, Lib);
self.destination_workspace.display(),
self.destination_workspace.display());
self.build_crates(build_context,
&mut deps,
libs,
cfgs,
Lib,
inputs_to_discover);
debug!("Building mains");
self.build_crates(build_context, &mut deps, mains, cfgs, Main);
self.build_crates(build_context,
&mut deps,
mains,
cfgs,
Main,
inputs_to_discover);
debug!("Building tests");
self.build_crates(build_context, &mut deps, tests, cfgs, Test);
self.build_crates(build_context,
&mut deps,
tests,
cfgs,
Test,
inputs_to_discover);
debug!("Building benches");
self.build_crates(build_context, &mut deps, benchs, cfgs, Bench);
self.build_crates(build_context,
&mut deps,
benchs,
cfgs,
Bench,
inputs_to_discover);
deps
}

Expand Down
4 changes: 3 additions & 1 deletion src/librustpkg/path_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,6 @@ pub fn versionize(p: &Path, v: &Version) -> Path {
p.with_filename(q)
}


#[cfg(target_os = "win32")]
pub fn chmod_read_only(p: &Path) -> bool {
#[fixed_stack_segment];
Expand All @@ -483,3 +482,6 @@ pub fn chmod_read_only(p: &Path) -> bool {
}
}

pub fn platform_library_name(s: &str) -> ~str {
format!("{}{}{}", os::consts::DLL_PREFIX, s, os::consts::DLL_SUFFIX)
}
Loading

5 comments on commit c979575

@bors
Copy link
Contributor

@bors bors commented on c979575 Oct 23, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from brson
at catamorphism@c979575

@bors
Copy link
Contributor

@bors bors commented on c979575 Oct 23, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging catamorphism/rust/rustpkg-c-dependencies = c979575 into auto

@bors
Copy link
Contributor

@bors bors commented on c979575 Oct 23, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

catamorphism/rust/rustpkg-c-dependencies = c979575 merged ok, testing candidate = 4cbc8ad

@bors
Copy link
Contributor

@bors bors commented on c979575 Oct 23, 2013

@bors
Copy link
Contributor

@bors bors commented on c979575 Oct 23, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 4cbc8ad

Please sign in to comment.