Bug 1304129 - Build GENERATED_FILES in the tup backend; r?gps draft
authorMike Shal <mshal@mozilla.com>
Mon, 19 Sep 2016 13:47:05 -0400
changeset 415642 4a4565e953ae873776995a5a5b20a6cbc30d2f88
parent 415641 b0befac98314b688ad70017e843f9ad0bf117e83
child 415643 fc6982f60d5419151fe0f376f7738c688f86a962
push id29922
push userbmo:mshal@mozilla.com
push dateTue, 20 Sep 2016 19:28:03 +0000
reviewersgps
bugs1304129
milestone52.0a1
Bug 1304129 - Build GENERATED_FILES in the tup backend; r?gps MozReview-Commit-ID: IaVAuRWIjmC
python/mozbuild/mozbuild/backend/tup.py
--- 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