More fixes found while building Mozilla:
authorBenjamin Smedberg <benjamin@smedbergs.us>
Tue, 10 Feb 2009 22:31:52 -0500
changeset 91 3a4d76dcfbc1b194b445901ab615ac82746c7bc6
parent 90 510ec41867cca3b6604dc2f16382024bd536e17f
child 92 7950a2d51eda46ac6f48e567eca11e8e7254d8e9
push id48
push userbsmedberg@mozilla.com
push dateWed, 11 Feb 2009 03:32:02 +0000
More fixes found while building Mozilla: * rules can have no prerequisites.. in this case we just throw the rule away * double-colon rules needed love * default verbosity should be warning, not debug ;-)
make.py
pymake/data.py
pymake/parser.py
--- a/make.py
+++ b/make.py
@@ -57,20 +57,23 @@ op.add_option('-C', '--directory',
               dest="directory", default=None)
 
 arglist = sys.argv[1:] + parsemakeflags()
 
 options, arguments = op.parse_args(arglist)
 
 makeflags = ''
 
+loglevel = logging.WARNING
 if options.verbose:
-    logging.basicConfig(level=logging.DEBUG)
+    loglevel = logging.DEBUG
     makeflags += 'v'
 
+logging.basicConfig(level=loglevel)
+
 if options.directory:
     log.info("Switching to directory: %s" % options.directory)
     os.chdir(options.directory)
 
 if len(options.makefiles) == 0:
     if os.path.exists('Makefile'):
         options.makefiles.append('Makefile')
     else:
--- a/pymake/data.py
+++ b/pymake/data.py
@@ -397,17 +397,17 @@ class Target(object):
         assert isinstance(target, str)
         self.target = target
         self.vpathtarget = None
         self.rules = []
         self.variables = Variables(makefile.variables)
         self.explicit = False
 
     def addrule(self, rule):
-        if len(self.rules) and rule.doublecolon != rules[0].doublecolon:
+        if len(self.rules) and rule.doublecolon != self.rules[0].doublecolon:
             # TODO: better location for this error
             raise DataError("Cannot have single- and double-colon rules for the same target.")
 
         if isinstance(rule, PatternRule):
             if len(rule.targetpatterns) != 1:
                 # TODO: better location
                 raise DataError("Static pattern rules must only have one target pattern")
             if rule.targetpatterns[0].match(self.target) is None:
@@ -614,17 +614,17 @@ class Target(object):
                 for p in r.prerequisitesfor(self.target):
                     dep = makefile.gettarget(p)
                     didanything = dep.make(makefile) or didanything
                     if not remake and mtimeislater(dep.mtime, self.mtime):
                         log.info("Remaking %s using rule at %s because %s is newer." % (self.target, r.loc, p))
                         remake = True
                 if remake:
                     self.remake()
-                    rule.execute(self, makefile)
+                    r.execute(self, makefile)
                     didanything = True
         else:
             commandrule = None
             remake = False
             if self.mtime is None:
                 log.info("Remaking %s because it doesn't exist or is a forced target" % (self.target,))
                 remake = True
 
@@ -691,16 +691,17 @@ class Rule(object):
     A rule contains a list of prerequisites and a list of commands. It may also
     contain rule-specific variables. This rule may be associated with multiple targets.
     """
 
     def __init__(self, prereqs, doublecolon, loc):
         self.prerequisites = prereqs
         self.doublecolon = doublecolon
         self.commands = []
+        self.loc = loc
 
     def addcommand(self, c):
         """Append a command expansion."""
         assert(isinstance(c, Expansion))
         self.commands.append(c)
 
     def prerequisitesfor(self, t):
         return self.prerequisites
--- a/pymake/parser.py
+++ b/pymake/parser.py
@@ -644,37 +644,39 @@ def parsestream(fd, filename, makefile):
                 # * a rule
                 # * an implicit rule
                 # * a static pattern rule
                 # * a target-specific variable definition
                 # * a pattern-specific variable definition
                 # any of the rules may have order-only prerequisites
                 # delimited by |, and a command delimited by ;
                 targets = map(data.Pattern, data.splitwords(e.resolve(makefile.variables)))
-                if len(targets) == 0:
-                    raise SyntaxError("No targets in rule", g.getloc(offset))
 
-                ispatterns = set((t.ispattern() for t in targets))
-                if len(ispatterns) == 2:
-                    raise SyntaxError("Mixed implicit and normal rule", d.getloc(offset))
-                ispattern, = ispatterns
+                if len(targets):
+                    ispatterns = set((t.ispattern() for t in targets))
+                    if len(ispatterns) == 2:
+                        raise SyntaxError("Mixed implicit and normal rule", d.getloc(offset))
+                    ispattern, = ispatterns
+                else:
+                    ispattern = False
 
                 e, token, offset = parsemakesyntax(d, offset,
                                                    varsettokens + (':', '|', ';'),
                                                    itermakefilechars)
                 if token in (None, ';'):
                     prereqs = data.splitwords(e.resolve(makefile.variables))
                     if ispattern:
                         currule = data.PatternRule(targets, map(data.Pattern, prereqs), doublecolon, loc=d.getloc(0))
                         makefile.appendimplicitrule(currule)
                     else:
                         currule = data.Rule(prereqs, doublecolon, loc=d.getloc(0))
                         for t in targets:
                             makefile.gettarget(t.gettarget()).addrule(currule)
-                        makefile.foundtarget(targets[0].gettarget())
+                        if len(targets):
+                            makefile.foundtarget(targets[0].gettarget())
 
                     if token == ';':
                         offset = d.skipwhitespace(offset)
                         e, t, offset = parsemakesyntax(d, offset, (), itercommandchars)
                         currule.addcommand(e)
                 elif token in varsettokens:
                     e.lstrip()
                     e.rstrip()
@@ -708,17 +710,18 @@ def parsestream(fd, filename, makefile):
                     pattern = data.Pattern(patterns[0])
 
                     e, token, offset = parsemakesyntax(d, offset, (';',), itermakefilechars)
                     prereqs = map(data.Pattern, data.splitwords(e.resolve(makefile.variables)))
                     currule = data.PatternRule([pattern], prereqs, doublecolon, loc=d.getloc(0))
                     for t in targets:
                         makefile.gettarget(t.gettarget()).addrule(currule)
 
-                    makefile.foundtarget(targets[0].gettarget())
+                    if len(targets):
+                        makefile.foundtarget(targets[0].gettarget())
 
                     if token == ';':
                         offset = d.skipwhitespace(offset)
                         e, token, offset = parsemakesyntax(d, offset, (), itercommandchars)
                         currule.addcommand(e)
 
     if len(condstack):
         raise SyntaxError("Condition never terminated with endif", condstack[-1].loc)