--- a/python/mozbuild/mozbuild/backend/tup.py
+++ b/python/mozbuild/mozbuild/backend/tup.py
@@ -10,16 +10,17 @@ import mozpack.path as mozpath
from mozbuild.base import MozbuildObject
from mozbuild.backend.base import PartialBackend, HybridBackend
from mozbuild.backend.recursivemake import RecursiveMakeBackend
from mozbuild.shellutil import quote as shell_quote
from .common import CommonBackend
from ..frontend.data import (
ContextDerived,
+ GeneratedFile,
)
from ..util import (
FileAvoidWrite,
)
class BackendTupfile(object):
"""Represents a generated Tupfile.
@@ -28,16 +29,17 @@ class BackendTupfile(object):
def __init__(self, srcdir, objdir, environment, topsrcdir, topobjdir):
self.topsrcdir = topsrcdir
self.srcdir = srcdir
self.objdir = objdir
self.relobjdir = mozpath.relpath(objdir, topobjdir)
self.environment = environment
self.name = mozpath.join(objdir, 'Tupfile')
self.rules_included = False
+ self.shell_exported = False
self.fh = FileAvoidWrite(self.name, capture_diff=True)
self.fh.write('# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.\n')
self.fh.write('\n')
def write(self, buf):
self.fh.write(buf)
@@ -53,16 +55,24 @@ class BackendTupfile(object):
self.write(': %(inputs)s |> %(display)s%(cmd)s |> %(outputs)s%(extra_outputs)s\n' % {
'inputs': ' '.join(inputs),
'display': '^ %s^ ' % display if display else '',
'cmd': ' '.join(cmd),
'outputs': ' '.join(outputs),
'extra_outputs': ' | ' + ' '.join(extra_outputs) if extra_outputs else '',
})
+ def export_shell(self):
+ if not self.shell_exported:
+ # These are used by mach/mixin/process.py to determine the current
+ # shell.
+ for var in ('SHELL', 'MOZILLABUILD', 'COMSPEC'):
+ self.write('export %s\n' % var)
+ self.shell_exported = True
+
def close(self):
return self.fh.close()
@property
def diff(self):
return self.fh.diff
@@ -80,29 +90,73 @@ class TupOnly(CommonBackend, PartialBack
objdir = mozpath.join(self.environment.topobjdir, relativedir)
srcdir = mozpath.join(self.environment.topsrcdir, relativedir)
if objdir not in self._backend_files:
self._backend_files[objdir] = \
BackendTupfile(srcdir, objdir, self.environment,
self.environment.topsrcdir, self.environment.topobjdir)
return self._backend_files[objdir]
+ def _get_backend_file_for(self, obj):
+ return self._get_backend_file(obj.relativedir)
+
+ def _py_action(self, action):
+ cmd = [
+ '$(PYTHON)',
+ '-m',
+ 'mozbuild.action.%s' % action,
+ ]
+ return cmd
+
def consume_object(self, obj):
"""Write out build files necessary to build with tup."""
if not isinstance(obj, ContextDerived):
return False
consumed = CommonBackend.consume_object(self, obj)
# Even if CommonBackend acknowledged the object, we still need to let
# the RecursiveMake backend also handle these objects.
if consumed:
return False
+ backend_file = self._get_backend_file_for(obj)
+
+ if isinstance(obj, GeneratedFile):
+ # TODO: These are directories that don't work in the tup backend
+ # yet, because things they depend on aren't built yet.
+ skip_directories = (
+ 'build', # FinalTargetPreprocessedFiles
+ 'layout/style/test', # HostSimplePrograms
+ 'toolkit/library', # libxul.so
+ )
+ if obj.script and obj.method and obj.relobjdir not in skip_directories:
+ backend_file.export_shell()
+ cmd = self._py_action('file_generate')
+ cmd.extend([
+ obj.script,
+ obj.method,
+ obj.outputs[0],
+ '%s.pp' % obj.outputs[0], # deps file required
+ ])
+ full_inputs = [f.full_path for f in obj.inputs]
+ cmd.extend(full_inputs)
+
+ outputs = []
+ outputs.extend(obj.outputs)
+ outputs.append('%s.pp' % obj.outputs[0])
+
+ backend_file.rule(
+ display='python {script}:{method} -> [%o]'.format(script=obj.script, method=obj.method),
+ cmd=cmd,
+ inputs=full_inputs,
+ outputs=outputs,
+ )
+
return True
def consume_finished(self):
CommonBackend.consume_finished(self)
for objdir, backend_file in sorted(self._backend_files.items()):
with self._write_file(fh=backend_file):
pass