Bug 1407403 - Handle IPDL code generation in the tup backend; r=gps
authorMike Shal <mshal@mozilla.com>
Mon, 23 Oct 2017 10:44:11 -0400
changeset 388440 bcb6adf5707cde27bd42d8af0a0d470624c16136
parent 388439 4b94d394f4ef9b1d5b6c51751472d80a869cf0d7
child 388441 6f205bfdd1396f43a814c61728bd85659fad72ba
push id32750
push userarchaeopteryx@coole-files.de
push dateThu, 26 Oct 2017 21:56:27 +0000
treeherdermozilla-central@a6d7be4ac1e3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgps
bugs1407403
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1407403 - Handle IPDL code generation in the tup backend; r=gps IPDL generation consists of a single ipdl.py invocation on all the *.ipdl and *.ipdlh files in the tree. Unfortunately the headers that are generated are placed into directories corresponding to the namespaces declared within the IDPL, and can't be determined solely based on the input filename. As such, we have to do a quick parsing of the AST in order to grab the namespaces and calculate the filenames for the .h files. The downside of this approach is that all *.ipdl/*.ipdlh files are considered inputs for the tup backend, so editing one will perform moz.build generation before running ipdl.py. This could be fixed by either standardizing the generated header layout, or fixing tup to somehow allow unspecified outputs. MozReview-Commit-ID: DzF2ryLEsrg
python/mozbuild/mozbuild/backend/tup.py
--- a/python/mozbuild/mozbuild/backend/tup.py
+++ b/python/mozbuild/mozbuild/backend/tup.py
@@ -1,15 +1,16 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 from __future__ import absolute_import, unicode_literals
 
 import os
+import sys
 
 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 mozbuild.util import OrderedDefaultDict
 
@@ -440,19 +441,63 @@ class TupOnly(CommonBackend, PartialBack
             inputs=[input_file],
             display='Preprocess %o',
             cmd=cmd,
             outputs=[output],
         )
 
     def _handle_ipdl_sources(self, ipdl_dir, sorted_ipdl_sources,
                              unified_ipdl_cppsrcs_mapping):
-        # TODO: This isn't implemented yet in the tup backend, but it is called
-        # by the CommonBackend.
-        pass
+        # Preferably we wouldn't have to import ipdl, but we need to parse the
+        # ast in order to determine the namespaces since they are used in the
+        # header output paths.
+        sys.path.append(mozpath.join(self.environment.topsrcdir, 'ipc', 'ipdl'))
+        import ipdl
+
+        backend_file = self._get_backend_file('ipc/ipdl')
+        outheaderdir = '_ipdlheaders'
+        cmd = [
+            '$(PYTHON_PATH)',
+            '$(PLY_INCLUDE)',
+            '%s/ipdl.py' % backend_file.srcdir,
+            '--sync-msg-list=%s/sync-messages.ini' % backend_file.srcdir,
+            '--msg-metadata=%s/message-metadata.ini' % backend_file.srcdir,
+            '--outheaders-dir=%s' % outheaderdir,
+            '--outcpp-dir=.',
+        ]
+        ipdldirs = sorted(set(mozpath.dirname(p) for p in sorted_ipdl_sources))
+        cmd.extend(['-I%s' % d for d in ipdldirs])
+        cmd.extend(sorted_ipdl_sources)
+
+        outputs = ['IPCMessageTypeName.cpp', mozpath.join(outheaderdir, 'IPCMessageStart.h'), 'ipdl_lextab.py', 'ipdl_yacctab.py']
+
+        for filename in sorted_ipdl_sources:
+            filepath, ext = os.path.splitext(filename)
+            dirname, basename = os.path.split(filepath)
+            dirname = mozpath.relpath(dirname, self.environment.topsrcdir)
+
+            extensions = ['']
+            if ext == '.ipdl':
+                extensions.extend(['Child', 'Parent'])
+
+            with open(filename) as f:
+                ast = ipdl.parse(f.read(), filename, includedirs=ipdldirs)
+                self.backend_input_files.add(filename)
+            headerdir = os.path.join(outheaderdir, *([ns.name for ns in ast.namespaces]))
+
+            for extension in extensions:
+                outputs.append("%s%s.cpp" % (basename, extension))
+                outputs.append(mozpath.join(headerdir, '%s%s.h' % (basename, extension)))
+
+        backend_file.rule(
+            display='IPDL code generation',
+            cmd=cmd,
+            outputs=outputs,
+            check_unchanged=True,
+        )
 
     def _handle_webidl_build(self, bindings_dir, unified_source_mapping,
                              webidls, expected_build_output_files,
                              global_define_files):
         backend_file = self._get_backend_file('dom/bindings')
         backend_file.export_shell()
 
         for source in sorted(webidls.all_preprocessed_sources()):