aboutsummaryrefslogtreecommitdiff
path: root/src/makefile
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-04-04 15:17:12 -0600
committerMelody Horn <melody@boringcactus.com>2021-04-04 15:17:12 -0600
commit050a3b166123be17c8dfdbd47e1b439040101884 (patch)
tree412642ec257792972868d8638ef023a1caf32682 /src/makefile
parent8d990bbdcb51a97b3f9430f57f947507b138b488 (diff)
downloadmakers-050a3b166123be17c8dfdbd47e1b439040101884.tar.gz
makers-050a3b166123be17c8dfdbd47e1b439040101884.zip
don't assume something's an inference rule unless it's on the suffix list
Diffstat (limited to 'src/makefile')
-rw-r--r--src/makefile/input.rs39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/makefile/input.rs b/src/makefile/input.rs
index b02cdb6..5afecc6 100644
--- a/src/makefile/input.rs
+++ b/src/makefile/input.rs
@@ -63,10 +63,16 @@ impl LineType {
}
}
+#[derive(Debug)]
+struct InferenceMatch<'a> {
+ s1: &'a str,
+ s2: &'a str,
+}
+
fn inference_match<'a>(
targets: &[&'a str],
prerequisites: &[String],
-) -> Option<regex::Captures<'a>> {
+) -> Option<InferenceMatch<'a>> {
lazy_static! {
static ref INFERENCE_RULE: Regex =
Regex::new(r"^(?P<s2>(\.[^/.]+)?)(?P<s1>\.[^/.]+)$").unwrap();
@@ -81,7 +87,10 @@ fn inference_match<'a>(
&& inference_match.is_some()
&& special_target_match.is_none();
if inference_rule {
- inference_match
+ inference_match.map(|x| InferenceMatch {
+ s1: x.name("s1").unwrap().as_str(),
+ s2: x.name("s2").unwrap().as_str(),
+ })
} else {
None
}
@@ -343,6 +352,15 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {
}
}
+ fn special_target_has_prereq(&self, target: &str, name: &str) -> bool {
+ match self.targets.get(target) {
+ Some(target) => {
+ target.prerequisites.is_empty() || target.prerequisites.iter().any(|e| e == name)
+ }
+ None => false,
+ }
+ }
+
fn read_rule(&mut self, line_tokens: &TokenString, line_number: usize) -> Result<()> {
let (targets, not_targets) = line_tokens
.split_once(':')
@@ -407,10 +425,23 @@ impl<'a, 'parent, R: BufRead> MakefileReader<'a, 'parent, R> {
return Ok(());
}
+ // don't interpret things like `.tmp: ; mkdir -p $@` as single-suffix rules
+ let inference_match = inference_match.and_then(|inference| {
+ if (inference.s1.is_empty()
+ || self.special_target_has_prereq(".SUFFIXES", inference.s1))
+ && (inference.s2.is_empty()
+ || self.special_target_has_prereq(".SUFFIXES", inference.s2))
+ {
+ Some(inference)
+ } else {
+ None
+ }
+ });
+
if let Some(inference_match) = inference_match {
let new_rule = InferenceRule::new_suffix(
- inference_match.name("s1").unwrap().as_str().to_owned(),
- inference_match.name("s2").unwrap().as_str().to_owned(),
+ inference_match.s1.to_owned(),
+ inference_match.s2.to_owned(),
commands,
);
log::trace!(