From fa0339048c4dfea4dd5e61ca96428a1d0a611555 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Thu, 25 Mar 2021 22:31:27 -0600 Subject: implement GNUish VPATH --- yapymake/makefile/__init__.py | 27 ++++++++++++++++++++------- 1 file 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? -- cgit v1.2.3