mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 912914 - Preserve targets and dependencies order when creating Makefiles with makeutil.py. r=gps
Also allow to add random statements (like variable assignment)
This commit is contained in:
parent
ab53a10348
commit
6889ad2ada
@ -15,7 +15,7 @@ class Makefile(object):
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
self._rules = []
|
||||
self._statements = []
|
||||
|
||||
def create_rule(self, targets=[]):
|
||||
'''
|
||||
@ -23,9 +23,16 @@ class Makefile(object):
|
||||
Returns the corresponding Rule instance.
|
||||
'''
|
||||
rule = Rule(targets)
|
||||
self._rules.append(rule)
|
||||
self._statements.append(rule)
|
||||
return rule
|
||||
|
||||
def add_statement(self, statement):
|
||||
'''
|
||||
Add a raw statement in the makefile. Meant to be used for
|
||||
simple variable assignments.
|
||||
'''
|
||||
self._statements.append(statement)
|
||||
|
||||
def dump(self, fh, removal_guard=True):
|
||||
'''
|
||||
Dump all the rules to the given file handle. Optionally (and by
|
||||
@ -34,12 +41,15 @@ class Makefile(object):
|
||||
'''
|
||||
all_deps = set()
|
||||
all_targets = set()
|
||||
for rule in self._rules:
|
||||
rule.dump(fh)
|
||||
all_deps.update(rule.dependencies())
|
||||
all_targets.update(rule.targets())
|
||||
for statement in self._statements:
|
||||
if isinstance(statement, Rule):
|
||||
statement.dump(fh)
|
||||
all_deps.update(statement.dependencies())
|
||||
all_targets.update(statement.targets())
|
||||
else:
|
||||
fh.write('%s\n' % statement)
|
||||
if removal_guard:
|
||||
guard = Rule(all_deps - all_targets)
|
||||
guard = Rule(sorted(all_deps - all_targets))
|
||||
guard.dump(fh)
|
||||
|
||||
|
||||
@ -51,21 +61,23 @@ class Rule(object):
|
||||
...
|
||||
'''
|
||||
def __init__(self, targets=[]):
|
||||
self._targets = set()
|
||||
self._dependencies = set()
|
||||
self._targets = []
|
||||
self._dependencies = []
|
||||
self._commands = []
|
||||
self.add_targets(targets)
|
||||
|
||||
def add_targets(self, targets):
|
||||
'''Add additional targets to the rule.'''
|
||||
assert isinstance(targets, Iterable) and not isinstance(targets, StringTypes)
|
||||
self._targets.update(t.replace(os.sep, '/') for t in targets)
|
||||
self._targets.extend(t.replace(os.sep, '/') for t in targets
|
||||
if not t in self._targets)
|
||||
return self
|
||||
|
||||
def add_dependencies(self, deps):
|
||||
'''Add dependencies to the rule.'''
|
||||
assert isinstance(deps, Iterable) and not isinstance(deps, StringTypes)
|
||||
self._dependencies.update(d.replace(os.sep, '/') for d in deps)
|
||||
self._dependencies.extend(d.replace(os.sep, '/') for d in deps
|
||||
if not d in self._dependencies)
|
||||
return self
|
||||
|
||||
def add_commands(self, commands):
|
||||
@ -94,9 +106,9 @@ class Rule(object):
|
||||
'''
|
||||
if not self._targets:
|
||||
return
|
||||
fh.write('%s:' % ' '.join(sorted(self._targets)))
|
||||
fh.write('%s:' % ' '.join(self._targets))
|
||||
if self._dependencies:
|
||||
fh.write(' %s' % ' '.join(sorted(self._dependencies)))
|
||||
fh.write(' %s' % ' '.join(self._dependencies))
|
||||
fh.write('\n')
|
||||
for cmd in self._commands:
|
||||
fh.write('\t%s\n' % cmd)
|
||||
|
@ -22,19 +22,13 @@ class TestMakefile(unittest.TestCase):
|
||||
|
||||
rule.add_targets(['foo', 'bar'])
|
||||
rule.dump(out)
|
||||
self.assertEqual(out.getvalue(), 'bar foo:\n')
|
||||
self.assertEqual(out.getvalue(), 'foo bar:\n')
|
||||
out.truncate(0)
|
||||
|
||||
rule.add_targets(['baz'])
|
||||
rule.add_dependencies(['qux', 'hoge', 'piyo'])
|
||||
rule.dump(out)
|
||||
self.assertEqual(out.getvalue(), 'bar baz foo: hoge piyo qux\n')
|
||||
out.truncate(0)
|
||||
|
||||
rule.add_targets(['baz'])
|
||||
rule.add_dependencies(['qux', 'hoge', 'piyo'])
|
||||
rule.dump(out)
|
||||
self.assertEqual(out.getvalue(), 'bar baz foo: hoge piyo qux\n')
|
||||
self.assertEqual(out.getvalue(), 'foo bar baz: qux hoge piyo\n')
|
||||
out.truncate(0)
|
||||
|
||||
rule = Rule(['foo', 'bar'])
|
||||
@ -43,7 +37,7 @@ class TestMakefile(unittest.TestCase):
|
||||
rule.add_commands(['$(BAZ) -o $@ $<', '$(TOUCH) $@'])
|
||||
rule.dump(out)
|
||||
self.assertEqual(out.getvalue(),
|
||||
'bar foo: baz\n' +
|
||||
'foo bar: baz\n' +
|
||||
'\techo $@\n' +
|
||||
'\t$(BAZ) -o $@ $<\n' +
|
||||
'\t$(TOUCH) $@\n')
|
||||
@ -73,6 +67,21 @@ class TestMakefile(unittest.TestCase):
|
||||
'\techo $@\n' +
|
||||
'hoge qux:\n')
|
||||
|
||||
def test_statement(self):
|
||||
out = StringIO()
|
||||
mk = Makefile()
|
||||
mk.create_rule(['foo']).add_dependencies(['bar']) \
|
||||
.add_commands(['echo foo'])
|
||||
mk.add_statement('BAR = bar')
|
||||
mk.create_rule(['$(BAR)']).add_commands(['echo $@'])
|
||||
mk.dump(out, removal_guard=False)
|
||||
self.assertEqual(out.getvalue(),
|
||||
'foo: bar\n' +
|
||||
'\techo foo\n' +
|
||||
'BAR = bar\n' +
|
||||
'$(BAR):\n' +
|
||||
'\techo $@\n')
|
||||
|
||||
@unittest.skipIf(os.name != 'nt', 'Test only applicable on Windows.')
|
||||
def test_path_normalization(self):
|
||||
out = StringIO()
|
||||
|
Loading…
Reference in New Issue
Block a user