Skip to content

Commit

Permalink
Merge pull request rust-lang#22 from alexcrichton/make
Browse files Browse the repository at this point in the history
Allow executing an arbitrary command before building
  • Loading branch information
wycats committed Jun 19, 2014
2 parents 96ab5d7 + 27274b1 commit 745b76d
Show file tree
Hide file tree
Showing 12 changed files with 348 additions and 42 deletions.
21 changes: 21 additions & 0 deletions .travis.install.deps.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
set -ex

# Install a 32-bit compiler for linux
sudo apt-get update
sudo apt-get install gcc-multilib
target=unknown-linux-gnu

# Install both 64 and 32 bit libraries. Apparently travis barfs if you try to
# just install the right ones? This should enable cross compilation in the
# future anyway.
curl -O http://static.rust-lang.org/dist/rust-nightly-x86_64-$target.tar.gz
curl -O http://static.rust-lang.org/dist/rust-nightly-i686-$target.tar.gz
tar xfz rust-nightly-x86_64-$target.tar.gz
tar xfz rust-nightly-i686-$target.tar.gz
cp -r rust-nightly-i686-$target/lib/rustlib/i686-$target \
rust-nightly-x86_64-$target/lib/rustlib
(cd rust-nightly-x86_64-$target && \
find lib/rustlib/i686-$target/lib -type f >> \
lib/rustlib/manifest.in)
sudo ./rust-nightly-x86_64-$target/install.sh

16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
language: rust

install:
- ./.travis.install.deps.sh

script:
- make CC="$CC" RUSTC="$RUSTC" -j4
- make CC="$CC" RUSTC="$RUSTC" test -j4

env:
- ARCH=i686 CC='cc -m32' RUSTC='rustc --target=i686-unknown-linux-gnu'
- ARCH=x86_64 CC=cc RUSTC='rustc --target=x86_64-unknown-linux-gnu'

os:
- linux
- osx
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ all: $(BIN_TARGETS)
# === Dependencies

$(HAMMER): $(wildcard libs/hammer.rs/src/*.rs)
cd libs/hammer.rs && make
$(MAKE) -C libs/hammer.rs

$(TOML): $(wildcard libs/rust-toml/src/toml/*.rs)
cd libs/rust-toml && make
$(MAKE) -C libs/rust-toml

$(HAMCREST): $(shell find libs/hamcrest-rust/src/hamcrest -name '*.rs')
cd libs/hamcrest-rust && make
$(MAKE) -C libs/hamcrest-rust

# === Cargo

$(LIBCARGO): $(SRC) $(HAMMER)
$(LIBCARGO): $(SRC) $(HAMMER) $(TOML)
mkdir -p target
$(RUSTC) $(RUSTC_FLAGS) $(DEPS) --out-dir target src/cargo/lib.rs
touch $(LIBCARGO)
Expand Down Expand Up @@ -61,7 +61,7 @@ test-unit: target/tests/test-unit
target/tests/test-unit $(only)

test-integration: target/tests/test-integration
RUST_TEST_TASKS=1 CARGO_BIN_PATH=$(PWD)/target/ $< $(only)
$< $(only)

test: test-unit test-integration

Expand Down
2 changes: 1 addition & 1 deletion libs/hammer.rs
Submodule hammer.rs updated 1 files
+3 −2 Makefile
25 changes: 19 additions & 6 deletions src/cargo/core/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ pub struct Manifest {
authors: Vec<String>,
targets: Vec<Target>,
target_dir: Path,
sources: Vec<SourceId>
sources: Vec<SourceId>,
build: Option<String>,
}

impl Show for Manifest {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Manifest({}, authors={}, targets={}, target_dir={})", self.summary, self.authors, self.targets, self.target_dir.display())
write!(f, "Manifest({}, authors={}, targets={}, target_dir={}, \
build={})",
self.summary, self.authors, self.targets,
self.target_dir.display(), self.build)
}
}

Expand All @@ -34,7 +38,8 @@ pub struct SerializedManifest {
dependencies: Vec<SerializedDependency>,
authors: Vec<String>,
targets: Vec<Target>,
target_dir: String
target_dir: String,
build: Option<String>,
}

impl<E, S: Encoder<E>> Encodable<S, E> for Manifest {
Expand All @@ -45,7 +50,8 @@ impl<E, S: Encoder<E>> Encodable<S, E> for Manifest {
dependencies: self.summary.get_dependencies().iter().map(|d| SerializedDependency::from_dependency(d)).collect(),
authors: self.authors.clone(),
targets: self.targets.clone(),
target_dir: self.target_dir.display().to_str()
target_dir: self.target_dir.display().to_str(),
build: self.build.clone(),
}.encode(s)
}
}
Expand Down Expand Up @@ -125,13 +131,16 @@ impl Show for Target {
}

impl Manifest {
pub fn new(summary: &Summary, targets: &[Target], target_dir: &Path, sources: Vec<SourceId>) -> Manifest {
pub fn new(summary: &Summary, targets: &[Target],
target_dir: &Path, sources: Vec<SourceId>,
build: Option<String>) -> Manifest {
Manifest {
summary: summary.clone(),
authors: Vec::new(),
targets: Vec::from_slice(targets),
target_dir: target_dir.clone(),
sources: sources
sources: sources,
build: build,
}
}

Expand Down Expand Up @@ -170,6 +179,10 @@ impl Manifest {
pub fn get_source_ids<'a>(&'a self) -> &'a [SourceId] {
self.sources.as_slice()
}

pub fn get_build<'a>(&'a self) -> Option<&'a str> {
self.build.as_ref().map(|s| s.as_slice())
}
}

impl Target {
Expand Down
27 changes: 24 additions & 3 deletions src/cargo/ops/cargo_rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io;
use std::path::Path;
use core::{Package,PackageSet,Target};
use util;
use util::{CargoResult, ChainError, ProcessBuilder, internal, human};
use util::{CargoResult, ChainError, ProcessBuilder, internal, human, CargoError};

type Args = Vec<String>;

Expand Down Expand Up @@ -33,6 +33,11 @@ pub fn compile_packages(pkg: &Package, deps: &PackageSet) -> CargoResult<()> {
fn compile_pkg(pkg: &Package, dest: &Path, deps_dir: &Path, primary: bool) -> CargoResult<()> {
debug!("compile_pkg; pkg={}; targets={}", pkg, pkg.get_targets());

match pkg.get_manifest().get_build() {
Some(cmd) => try!(compile_custom(pkg, cmd, dest, deps_dir, primary)),
None => {}
}

// compile
for target in pkg.get_targets().iter() {
// Only compile lib targets for dependencies
Expand All @@ -48,6 +53,20 @@ fn mk_target(target: &Path) -> CargoResult<()> {
io::fs::mkdir_recursive(target, io::UserRWX).chain_error(|| internal("could not create target directory"))
}

fn compile_custom(pkg: &Package, cmd: &str, dest: &Path, deps_dir: &Path,
_primary: bool) -> CargoResult<()> {
// FIXME: this needs to be smarter about splitting
let mut cmd = cmd.split(' ');
let mut p = util::process(cmd.next().unwrap())
.cwd(pkg.get_root())
.env("OUT_DIR", Some(dest.as_str().unwrap()))
.env("DEPS_DIR", Some(dest.join(deps_dir).as_str().unwrap()));
for arg in cmd {
p = p.arg(arg);
}
p.exec_with_output().map(|_| ()).map_err(|e| e.mark_human())
}

fn rustc(root: &Path, target: &Target, dest: &Path, deps: &Path, verbose: bool) -> CargoResult<()> {

let crate_types = target.rustc_crate_types();
Expand All @@ -72,7 +91,7 @@ fn prepare_rustc(root: &Path, target: &Target, crate_type: &'static str, dest: &
let mut args = Vec::new();

build_base_args(&mut args, target, crate_type, dest);
build_deps_args(&mut args, deps);
build_deps_args(&mut args, dest, deps);

util::process("rustc")
.cwd(root.clone())
Expand All @@ -89,9 +108,11 @@ fn build_base_args(into: &mut Args, target: &Target, crate_type: &'static str, d
into.push(dest.display().to_str());
}

fn build_deps_args(dst: &mut Args, deps: &Path) {
fn build_deps_args(dst: &mut Args, deps: &Path, dest: &Path) {
dst.push("-L".to_str());
dst.push(deps.display().to_str());
dst.push("-L".to_str());
dst.push(dest.display().to_str());
}

fn topsort(deps: &PackageSet) -> CargoResult<PackageSet> {
Expand Down
29 changes: 21 additions & 8 deletions src/cargo/util/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::io::process::{Command,ProcessOutput,ProcessExit,ExitStatus,ExitSignal};
use std::io::IoError;
use std::fmt;
use std::fmt::{Show, Formatter};
use std::str;

use TomlError = toml::Error;

Expand Down Expand Up @@ -143,18 +144,30 @@ impl Show for ProcessError {
Some(ExitStatus(i)) | Some(ExitSignal(i)) => i.to_str(),
None => "never executed".to_str()
};
write!(f, "{} (status={})", self.msg, exit)
try!(write!(f, "{} (status={})", self.msg, exit));
match self.output {
Some(ref out) => {
match str::from_utf8(out.output.as_slice()) {
Some(s) if s.trim().len() > 0 => {
try!(write!(f, "\n--- stdout\n{}", s));
}
Some(..) | None => {}
}
match str::from_utf8(out.error.as_slice()) {
Some(s) if s.trim().len() > 0 => {
try!(write!(f, "\n--- stderr\n{}", s));
}
Some(..) | None => {}
}
}
None => {}
}
Ok(())
}
}

impl CargoError for ProcessError {
fn description(&self) -> String {
let exit = match self.exit {
Some(ExitStatus(i)) | Some(ExitSignal(i)) => i.to_str(),
None => "never executed".to_str()
};
format!("{} (status={})", self.msg, exit)
}
fn description(&self) -> String { self.to_str() }

fn detail(&self) -> Option<String> {
self.detail.clone()
Expand Down
17 changes: 13 additions & 4 deletions src/cargo/util/process_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ impl Show for ProcessBuilder {
static PATH_SEP : &'static str = ":";

impl ProcessBuilder {
pub fn args<T: Show>(mut self, arguments: &[T]) -> ProcessBuilder {
self.args = arguments.iter().map(|a| a.to_str()).collect();
pub fn arg<T: Str>(mut self, arg: T) -> ProcessBuilder {
self.args.push(arg.as_slice().to_str());
self
}

pub fn args<T: Str>(mut self, arguments: &[T]) -> ProcessBuilder {
self.args = arguments.iter().map(|a| a.as_slice().to_str()).collect();
self
}

Expand Down Expand Up @@ -98,14 +103,18 @@ impl ProcessBuilder {
}
}

fn build_command(&self) -> Command {
pub fn build_command(&self) -> Command {
let mut command = Command::new(self.program.as_slice());
command.args(self.args.as_slice()).cwd(&self.cwd);
command
}

fn debug_string(&self) -> String {
format!("{} {}", self.program, self.args.connect(" "))
if self.args.len() == 0 {
self.program.to_str()
} else {
format!("{} {}", self.program, self.args.connect(" "))
}
}

fn build_env(&self) -> Vec<(String, String)> {
Expand Down
10 changes: 7 additions & 3 deletions src/cargo/util/toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ pub struct TomlManifest {
pub struct TomlProject {
pub name: String,
pub version: String,
pub authors: Vec<String>
pub authors: Vec<String>,
build: Option<String>,
}

impl TomlProject {
Expand Down Expand Up @@ -159,10 +160,13 @@ impl TomlManifest {
}

Ok((Manifest::new(
&Summary::new(&self.project.to_package_id(source_id.get_url()), deps.as_slice()),
&Summary::new(&self.project.to_package_id(source_id.get_url()),
deps.as_slice()),
targets.as_slice(),
&Path::new("target"),
sources), nested_paths))
sources,
self.project.build.clone()),
nested_paths))
}
}

Expand Down
23 changes: 14 additions & 9 deletions tests/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std;
use std::io;
use std::io::fs;
use std::io::process::{ProcessOutput,ProcessExit};
use std::io::process::{ProcessOutput};
use std::os;
use std::path::{Path,BytesContainer};
use std::str;
Expand Down Expand Up @@ -80,7 +80,7 @@ impl ProjectBuilder {
.extra_path(cargo_dir())
}

pub fn file<B: BytesContainer, S: Str>(mut self, path: B, body: S) -> ProjectBuilder {
pub fn file<B: BytesContainer, S: Str>(mut self, path: B, body: S) -> ProjectBuilder {
self.files.push(FileBuilder::new(self.root.join(path), body.as_slice()));
self
}
Expand Down Expand Up @@ -163,9 +163,11 @@ impl<T, E: Show> ErrMsg<T> for Result<T, E> {

// Path to cargo executables
pub fn cargo_dir() -> Path {
os::getenv("CARGO_BIN_PATH")
.map(|s| Path::new(s))
.unwrap_or_else(|| fail!("CARGO_BIN_PATH wasn't set. Cannot continue running test"))
os::getenv("CARGO_BIN_PATH").map(Path::new)
.or_else(|| os::self_exe_path().map(|p| p.dir_path()))
.unwrap_or_else(|| {
fail!("CARGO_BIN_PATH wasn't set. Cannot continue running test")
})
}

/// Returns an absolute path in the filesystem that `path` points to. The
Expand Down Expand Up @@ -202,18 +204,21 @@ impl Execs {
}

fn match_output(&self, actual: &ProcessOutput) -> ham::MatchResult {
self.match_status(actual.status)
self.match_status(actual)
.and(self.match_stdout(actual))
.and(self.match_stderr(actual))
}

fn match_status(&self, actual: ProcessExit) -> ham::MatchResult {
fn match_status(&self, actual: &ProcessOutput) -> ham::MatchResult {
match self.expect_exit_code {
None => ham::success(),
Some(code) => {
ham::expect(
actual.matches_exit_status(code),
format!("exited with {}", actual))
actual.status.matches_exit_status(code),
format!("exited with {}\n--- stdout\n{}\n--- stderr\n{}",
actual.status,
str::from_utf8(actual.output.as_slice()),
str::from_utf8(actual.error.as_slice())))
}
}
}
Expand Down
Loading

0 comments on commit 745b76d

Please sign in to comment.