aboutsummaryrefslogtreecommitdiff
path: root/src/makefile/target.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/makefile/target.rs')
-rw-r--r--src/makefile/target.rs29
1 files changed, 22 insertions, 7 deletions
diff --git a/src/makefile/target.rs b/src/makefile/target.rs
index 8f56506..c12f666 100644
--- a/src/makefile/target.rs
+++ b/src/makefile/target.rs
@@ -2,6 +2,7 @@ use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::fmt;
use std::fs::metadata;
+use std::mem;
use std::rc::Rc;
use std::time::SystemTime;
@@ -23,13 +24,27 @@ pub struct Target {
impl Target {
pub fn extend(&mut self, other: Target) {
assert_eq!(&self.name, &other.name);
- self.prerequisites.extend(other.prerequisites);
- assert!(self.commands.is_empty() || other.commands.is_empty());
- self.commands.extend(other.commands);
- assert!(self.stem.is_none() || other.stem.is_none());
- self.stem = self.stem.take().or(other.stem);
- let already_updated = self.already_updated.get() || other.already_updated.get();
- self.already_updated.set(already_updated);
+ match (self.commands.is_empty(), other.commands.is_empty()) {
+ (false, false) => {
+ // both targets have commands, so replace this entirely
+ *self = other;
+ }
+ (true, false) => {
+ // this target doesn't have commands, but the other one does,
+ // so it's the real one
+ let mut other = other;
+ mem::swap(self, &mut other);
+ self.extend(other);
+ }
+ (false, true) | (true, true) => {
+ // this target might have commands, but the other one doesn't,
+ // so append non-command stuff
+ self.prerequisites.extend(other.prerequisites);
+ self.stem = self.stem.take().or(other.stem);
+ let already_updated = self.already_updated.get() || other.already_updated.get();
+ self.already_updated.set(already_updated);
+ }
+ }
}
fn modified_time(&self) -> Option<SystemTime> {