summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/bar.yml2
-rw-r--r--examples/binutils.yml2
-rw-r--r--examples/foo.yml2
-rw-r--r--examples/gcc-libs.yml2
-rw-r--r--examples/gcc.yml4
-rw-r--r--examples/glibc.yml2
-rw-r--r--examples/libgcc-initial.yml2
-rw-r--r--examples/linux-uapi-headers.yml2
-rw-r--r--examples/ls.yml2
-rw-r--r--src/executor.rs21
-rw-r--r--src/resolve.rs30
-rw-r--r--src/types.rs17
12 files changed, 74 insertions, 14 deletions
diff --git a/examples/bar.yml b/examples/bar.yml
index ca01afa..ece6fd1 100644
--- a/examples/bar.yml
+++ b/examples/bar.yml
@@ -1,5 +1,7 @@
tasks:
build:
+ output:
+ default: {}
run: |
findmnt -o +PROPAGATION
mkdir -p "${DESTDIR}"
diff --git a/examples/binutils.yml b/examples/binutils.yml
index 56342f7..c05d965 100644
--- a/examples/binutils.yml
+++ b/examples/binutils.yml
@@ -41,6 +41,8 @@ tasks:
install:
inherit:
task: 'binutils:compile'
+ output:
+ default: {}
run: |
cd binutils-build
make DESTDIR="$DESTDIR" install
diff --git a/examples/foo.yml b/examples/foo.yml
index 6b50c07..6b82812 100644
--- a/examples/foo.yml
+++ b/examples/foo.yml
@@ -1,5 +1,7 @@
tasks:
build:
+ output:
+ default: {}
run: |
ls -lha
ls -lha /proc/self/fd
diff --git a/examples/gcc-libs.yml b/examples/gcc-libs.yml
index ccd6ebf..8eda21b 100644
--- a/examples/gcc-libs.yml
+++ b/examples/gcc-libs.yml
@@ -19,6 +19,8 @@ tasks:
target_depends:
- task: 'linux-uapi-headers:install'
- task: 'glibc:install'
+ output:
+ default: {}
run: |
cd gcc-build
make DESTDIR="$DESTDIR" install-target-libgcc install-target-libstdc++-v3 install-target-libgomp install-target-libquadmath install-target-libatomic
diff --git a/examples/gcc.yml b/examples/gcc.yml
index 8c938e5..7a215a9 100644
--- a/examples/gcc.yml
+++ b/examples/gcc.yml
@@ -9,6 +9,8 @@ tasks:
sed -i -e 's@^MULTILIB_OSDIRNAMES@# &@' gcc-11.2.0/gcc/config/*/t-*
header-stubs:
+ output:
+ default: {}
run: |
mkdir -p "${DESTDIR}${PREFIX}/include"
touch "${DESTDIR}${PREFIX}/include/limits.h"
@@ -80,6 +82,8 @@ tasks:
install:
inherit:
task: 'gcc:compile'
+ output:
+ default: {}
run: |
cd gcc-build
make DESTDIR="$DESTDIR" install-host
diff --git a/examples/glibc.yml b/examples/glibc.yml
index 19d5f85..d98a1fa 100644
--- a/examples/glibc.yml
+++ b/examples/glibc.yml
@@ -73,6 +73,8 @@ tasks:
- task: 'libgcc-initial:install'
target_depends:
- task: 'linux-uapi-headers:install'
+ output:
+ default: {}
run: |
cd glibc-build
make install_root="${DESTDIR}" install
diff --git a/examples/libgcc-initial.yml b/examples/libgcc-initial.yml
index 35f1bd5..086f9ee 100644
--- a/examples/libgcc-initial.yml
+++ b/examples/libgcc-initial.yml
@@ -39,6 +39,8 @@ tasks:
task: 'libgcc-initial:compile'
build_depends:
- task: 'binutils:install'
+ output:
+ default: {}
run: |
cd gcc-build
make DESTDIR="$DESTDIR" install-target-libgcc
diff --git a/examples/linux-uapi-headers.yml b/examples/linux-uapi-headers.yml
index 02b58b3..95f6d11 100644
--- a/examples/linux-uapi-headers.yml
+++ b/examples/linux-uapi-headers.yml
@@ -9,6 +9,8 @@ tasks:
install:
inherit:
task: 'linux-uapi-headers:unpack'
+ output:
+ default: {}
run: |
TARGET_ARCH=arm64
diff --git a/examples/ls.yml b/examples/ls.yml
index b2cc678..63816a0 100644
--- a/examples/ls.yml
+++ b/examples/ls.yml
@@ -3,6 +3,8 @@ tasks:
target_depends:
- task: 'foo:build'
- task: 'bar:build'
+ output:
+ default: {}
run: |
ls -lh /
ls -lhR "${SYSROOT}"
diff --git a/src/executor.rs b/src/executor.rs
index 1e76fea..d9cde15 100644
--- a/src/executor.rs
+++ b/src/executor.rs
@@ -25,6 +25,7 @@ struct TaskInput<'a> {
pub id: &'a TaskRef,
pub inherit: Option<InputHash>,
pub depends: &'a HashMap<DependencyHash, Dependency>,
+ pub output: &'a HashMap<String, Output>,
pub action: &'a Action,
pub env: &'a HashMap<String, String>,
}
@@ -96,15 +97,18 @@ impl<'a> Executor<'a> {
for task in taskset {
let task_def = tasks.get(&task.id).expect("Invalid TaskRef");
- if task_def.get_depends().next().is_none() {
- exc.tasks_runnable.push(task);
- } else {
- for dep in task_def.get_depends() {
- let rdep = exc.rdeps.entry(dep.clone()).or_default();
- rdep.push(task.clone());
- }
+ let mut has_depends = false;
+ for dep in task_def.get_depend_tasks() {
+ let rdep = exc.rdeps.entry(dep.clone()).or_default();
+ rdep.push(task.clone());
+ has_depends = true;
+ }
+
+ if has_depends {
exc.tasks_blocked.insert(task);
+ } else {
+ exc.tasks_runnable.push(task);
}
}
@@ -117,7 +121,7 @@ impl<'a> Executor<'a> {
fn deps_satisfied(&self, task_ref: &TaskRef) -> bool {
let task = self.tasks.get(&task_ref.id).expect("Invalid TaskRef");
- task.get_depends()
+ task.get_depend_tasks()
.all(|dep| self.tasks_done.contains_key(dep))
}
@@ -162,6 +166,7 @@ impl<'a> Executor<'a> {
id: &task_ref,
inherit: inherit_hash,
depends: &task_deps,
+ output: &task_def.output,
action: &task_def.action,
env: &env,
}
diff --git a/src/resolve.rs b/src/resolve.rs
index 5811446..14294d1 100644
--- a/src/resolve.rs
+++ b/src/resolve.rs
@@ -25,6 +25,7 @@ impl fmt::Display for DepChain {
#[derive(Debug)]
pub enum Error {
TaskNotFound(DepChain),
+ OutputNotFound(DepChain, String),
DependencyCycle(DepChain),
}
@@ -32,6 +33,7 @@ impl Error {
fn extend(&mut self, task: TaskRef) {
let tasks = match self {
Error::TaskNotFound(ref mut tasks) => tasks,
+ Error::OutputNotFound(ref mut tasks, _) => tasks,
Error::DependencyCycle(ref mut tasks) => tasks,
};
tasks.0.push(task);
@@ -44,6 +46,9 @@ impl fmt::Display for Error {
Error::TaskNotFound(tasks) => {
write!(f, "Task not found: {}", tasks)
}
+ Error::OutputNotFound(tasks, output) => {
+ write!(f, "Output '{}' not found: {}", output, tasks)
+ }
Error::DependencyCycle(tasks) => {
write!(f, "Dependency Cycle: {}", tasks)
}
@@ -79,7 +84,7 @@ impl<'a> Resolver<'a> {
.all(|resolved| *resolved == ResolveState::Resolved)
}
- pub fn add_task(&mut self, task: &TaskRef) -> Vec<Error> {
+ fn add_task(&mut self, task: &TaskRef, output: Option<&str>) -> Vec<Error> {
match self.resolve_state.get(task) {
Some(ResolveState::Resolving) => {
return vec![Error::DependencyCycle(DepChain(vec![task.clone()]))]
@@ -93,17 +98,32 @@ impl<'a> Resolver<'a> {
Some(task_def) => task_def,
};
+ if let Some(task_output) = output {
+ if !task_def.output.contains_key(task_output) {
+ return vec![Error::OutputNotFound(
+ DepChain(vec![task.clone()]),
+ task_output.to_string(),
+ )];
+ }
+ }
+
self.resolve_state
.insert(task.clone(), ResolveState::Resolving);
let mut ret = Vec::new();
-
- for dep in task_def.get_depends() {
- let errors = self.add_task(dep);
+ let mut handle_errors = |errors: Vec<Error>| {
for mut error in errors {
error.extend(task.clone());
ret.push(error);
}
+ };
+
+ if let Some(inherit) = &task_def.inherit {
+ handle_errors(self.add_task(inherit, None));
+ }
+
+ for dep in task_def.get_depend_outputs() {
+ handle_errors(self.add_task(&dep.task, Some(&dep.output)));
}
if ret.is_empty() {
@@ -119,7 +139,7 @@ impl<'a> Resolver<'a> {
}
pub fn add_goal(&mut self, task: &TaskRef) -> Vec<Error> {
- let ret = self.add_task(task);
+ let ret = self.add_task(task, None);
debug_assert!(self.tasks_resolved());
ret
}
diff --git a/src/types.rs b/src/types.rs
index a6a7fee..af0fb92 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -104,6 +104,11 @@ fn default_output_name() -> String {
"default".to_string()
}
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub struct Output {
+ pub path: Option<String>,
+}
+
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct OutputRef {
#[serde(flatten)]
@@ -122,12 +127,14 @@ pub struct Task {
pub build_depends: HashSet<OutputRef>,
#[serde(default)]
pub target_depends: HashSet<OutputRef>,
+ #[serde(default)]
+ pub output: HashMap<String, Output>,
#[serde(flatten)]
pub action: Action,
}
impl Task {
- pub fn get_depends(&self) -> impl Iterator<Item = &TaskRef> {
+ pub fn get_depend_tasks(&self) -> impl Iterator<Item = &TaskRef> {
self.inherit
.iter()
.chain(
@@ -139,6 +146,14 @@ impl Task {
.collect::<HashSet<_>>()
.into_iter()
}
+
+ pub fn get_depend_outputs(&self) -> impl Iterator<Item = &OutputRef> {
+ self.build_depends
+ .iter()
+ .chain(self.target_depends.iter())
+ .collect::<HashSet<_>>()
+ .into_iter()
+ }
}
pub type TaskMap = HashMap<String, Task>;