aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-04-14 19:25:35 -0600
committerMelody Horn <melody@boringcactus.com>2021-04-14 19:25:53 -0600
commiteb61a461411d54b08562ce04878ace57836f2a61 (patch)
tree7016f2cf166c51e2e6056ce1b96d1add1c5a4eaf
parent7ac635054c43f28bf73233925ae13120b9ad86b8 (diff)
downloadmakers-eb61a461411d54b08562ce04878ace57836f2a61.tar.gz
makers-eb61a461411d54b08562ce04878ace57836f2a61.zip
always give a target with commands the first prereqs
-rw-r--r--src/makefile/input.rs2
-rw-r--r--src/makefile/target.rs29
2 files changed, 23 insertions, 8 deletions
diff --git a/src/makefile/input.rs b/src/makefile/input.rs
index 03e7f18..5dda538 100644
--- a/src/makefile/input.rs
+++ b/src/makefile/input.rs
@@ -1163,8 +1163,8 @@ cursed:
#[test]
fn dependency_prepending_appending() -> R {
let file = "
-test: a
test: b
+test: a
\techo hi
test: c
";
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> {