aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-03-25 22:31:27 -0600
committerMelody Horn <melody@boringcactus.com>2021-03-25 22:31:27 -0600
commitfa0339048c4dfea4dd5e61ca96428a1d0a611555 (patch)
treea80b3b86c95105562c7251b791877482ec09544b
parent91fa36cf9916388842e33d5b3698d6e7e694b38a (diff)
downloadyapymake-fa0339048c4dfea4dd5e61ca96428a1d0a611555.tar.gz
yapymake-fa0339048c4dfea4dd5e61ca96428a1d0a611555.zip
implement GNUish VPATH
-rw-r--r--yapymake/makefile/__init__.py27
1 files changed, 20 insertions, 7 deletions
diff --git a/yapymake/makefile/__init__.py b/yapymake/makefile/__init__.py
index ee1cb74..a3e65d7 100644
--- a/yapymake/makefile/__init__.py
+++ b/yapymake/makefile/__init__.py
@@ -310,7 +310,12 @@ class Makefile:
def target(self, name: str) -> 'Target':
# TODO implement .DEFAULT
# it's not POSIXful, but GNU make will use inference rules for defined targets with no commands,
+ # and also VPATH is a thing that exists!
follow_gnu = True # TODO implement .POSIX and scope it properly
+ if follow_gnu and 'VPATH' in self._macros:
+ vpath_options = self.expand_macros(tokenize('$(VPATH)')).split(os.pathsep)
+ else:
+ vpath_options = []
if name not in self._targets or (follow_gnu and len(self._targets[name].commands) == 0):
# > When no target rule is found to update a target, the inference rules shall be checked. The suffix of
# > the target (.s1) to be built...
@@ -325,13 +330,21 @@ class Makefile:
if rule.s1 == suffix:
# > whose prerequisite file ($*.s2) exists.
prerequisite_path = PurePath(name).with_suffix(rule.s2)
- if ImpurePath(prerequisite_path).exists():
- if name in self._targets:
- # we got here by following GNU
- self._warn(f'warning: non-POSIX use of inference rule {rule.s1}{rule.s2} on explicit '
- f'target {name}')
- self._targets[name] = Target(name, [str(prerequisite_path)], rule.commands)
- break
+ if prerequisite_path.is_absolute():
+ prerequisite_path_options = [prerequisite_path]
+ else:
+ prerequisite_path_options = [prerequisite_path] + \
+ [PurePath(vpath, prerequisite_path) for vpath in vpath_options]
+ for i, prerequisite in enumerate(prerequisite_path_options):
+ if ImpurePath(prerequisite).exists():
+ if name in self._targets:
+ # we got here by following GNU
+ self._warn(f'warning: non-POSIX use of inference rule {rule.s1}{rule.s2} on '
+ f'explicit target {name}')
+ if i > 0:
+ self._warn('warning: non-POSIX use of VPATH fallback')
+ self._targets[name] = Target(name, [str(prerequisite)], rule.commands)
+ break
if name not in self._targets:
# we tried inference, it didn't work
# is there a default?