Bug 1253436 - Write out a machine readable file with binaries metadata; r?glandium draft
authorGregory Szorc <gps@mozilla.com>
Thu, 03 Mar 2016 17:14:37 -0800
changeset 336659 af1e2bb0a3ae19eab1d9bad5ecbde3d83e75f858
parent 336610 b0c7a917f844a4abaef0ecb7d910d3864b8629d7
child 515487 60cb232738457e0c64a6906b79ebcf4dda2b83b1
push id12166
push usergszorc@mozilla.com
push dateFri, 04 Mar 2016 01:14:54 +0000
reviewersglandium
bugs1253436
milestone47.0a1
Bug 1253436 - Write out a machine readable file with binaries metadata; r?glandium This will make it easier for binaries only archive generation to consult the list of binaries that are relevant to packaging. This does overlap somewhat with compile databases. Perhaps someday the logic could converge. While I was here, I cleaned up writing of the all-tests.json file to avoid an intermediate string variable. MozReview-Commit-ID: XVnKB1MNqu
python/mozbuild/mozbuild/backend/common.py
python/mozbuild/mozbuild/test/backend/test_recursivemake.py
--- a/python/mozbuild/mozbuild/backend/common.py
+++ b/python/mozbuild/mozbuild/backend/common.py
@@ -15,26 +15,28 @@ from mozbuild.backend.base import BuildB
 
 from mozbuild.frontend.context import (
     Context,
     Path,
     RenamedSourcePath,
     VARIABLES,
 )
 from mozbuild.frontend.data import (
+    BaseProgram,
     ChromeManifestEntry,
     ConfigFileSubstitution,
     ExampleWebIDLInterface,
     IPDLFile,
     FinalTargetPreprocessedFiles,
     FinalTargetFiles,
     GeneratedEventWebIDLFile,
     GeneratedWebIDLFile,
     PreprocessedTestWebIDLFile,
     PreprocessedWebIDLFile,
+    SharedLibrary,
     TestManifest,
     TestWebIDLFile,
     UnifiedSources,
     XPIDLFile,
     WebIDLFile,
 )
 from mozbuild.jar import (
     DeprecatedJarManifest,
@@ -187,23 +189,49 @@ class TestManager(object):
 
         key = path[len(topsrcdir)+1:]
         t['file_relpath'] = key
         t['dir_relpath'] = mozpath.dirname(key)
 
         self.tests_by_path[key].append(t)
 
 
+class BinariesCollection(object):
+    """Tracks state of binaries produced by the build."""
+
+    def __init__(self):
+        self.shared_libraries = []
+        self.programs = []
+
+    def to_dict(self):
+        SHARED_ATTRS = ('basename', 'lib_name', 'import_name', 'soname',
+                        'install_target', 'relobjdir')
+        shared = []
+        for l in self.shared_libraries:
+            shared.append({k: getattr(l, k) for k in SHARED_ATTRS})
+
+        PROGRAM_ATTRS = ('program', 'KIND', 'install_target', 'relobjdir')
+        programs = []
+        for p in self.programs:
+            programs.append({k.lower(): getattr(p, k) for k in PROGRAM_ATTRS})
+
+        return {
+            'shared_libraries': shared,
+            'programs': programs,
+        }
+
+
 class CommonBackend(BuildBackend):
     """Holds logic common to all build backends."""
 
     def _init(self):
         self._idl_manager = XPIDLManager(self.environment)
         self._test_manager = TestManager(self.environment)
         self._webidls = WebIDLCollection()
+        self._binaries = BinariesCollection()
         self._configs = set()
         self._ipdl_sources = set()
 
     def consume_object(self, obj):
         self._configs.add(obj.config)
 
         if isinstance(obj, TestManifest):
             for test in obj.tests:
@@ -290,16 +318,25 @@ class CommonBackend(BuildBackend):
             # Unified sources aren't relevant to artifact builds.
             if self.environment.is_artifact_build:
                 return True
 
             if obj.have_unified_mapping:
                 self._write_unified_files(obj.unified_source_mapping, obj.objdir)
             if hasattr(self, '_process_unified_sources'):
                 self._process_unified_sources(obj)
+
+        elif isinstance(obj, BaseProgram):
+            self._binaries.programs.append(obj)
+            return False
+
+        elif isinstance(obj, SharedLibrary):
+            self._binaries.shared_libraries.append(obj)
+            return False
+
         else:
             return False
 
         return True
 
     def consume_finished(self):
         if len(self._idl_manager.idls):
             self._handle_idl_manager(self._idl_manager)
@@ -330,20 +367,23 @@ class CommonBackend(BuildBackend):
 
         self._write_unified_files(unified_source_mapping, ipdl_dir, poison_windows_h=False)
         self._handle_ipdl_sources(ipdl_dir, sorted_ipdl_sources, unified_source_mapping)
 
         for config in self._configs:
             self.backend_input_files.add(config.source)
 
         # Write out a machine-readable file describing every test.
-        path = mozpath.join(self.environment.topobjdir, 'all-tests.json')
-        with self._write_file(path) as fh:
-            s = json.dumps(self._test_manager.tests_by_path)
-            fh.write(s)
+        topobjdir = self.environment.topobjdir
+        with self._write_file(mozpath.join(topobjdir, 'all-tests.json')) as fh:
+            json.dump(self._test_manager.tests_by_path, fh)
+
+        # Write out a machine-readable file describing binaries.
+        with self._write_file(mozpath.join(topobjdir, 'binaries.json')) as fh:
+            json.dump(self._binaries.to_dict(), fh, sort_keys=True, indent=4)
 
     def _handle_webidl_collection(self, webidls):
         if not webidls.all_stems():
             return
 
         bindings_dir = mozpath.join(self.environment.topobjdir, 'dom', 'bindings')
 
         all_inputs = set(webidls.all_static_sources())
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -854,11 +854,37 @@ class TestRecursiveMakeBackend(BackendTe
             'LIBRARY_NAME := bar\n',
             'FORCE_SHARED_LIB := 1\n',
             'IMPORT_LIBRARY := bar\n',
             'SHARED_LIBRARY := bar\n',
             'IS_COMPONENT := 1\n',
             'DSO_SONAME := bar\n',
         ])
 
+        self.assertTrue(os.path.exists(mozpath.join(env.topobjdir, 'binaries.json')))
+        with open(mozpath.join(env.topobjdir, 'binaries.json'), 'rb') as fh:
+            binaries = json.load(fh)
+
+        self.assertEqual(binaries, {
+            'programs': [],
+            'shared_libraries': [
+                {
+                    'basename': 'foo',
+                    'import_name': 'foo',
+                    'install_target': 'dist/bin',
+                    'lib_name': 'foo',
+                    'relobjdir': 'foo',
+                    'soname': 'foo',
+                },
+                {
+                    'basename': 'bar',
+                    'import_name': 'bar',
+                    'install_target': 'dist/bin',
+                    'lib_name': 'bar',
+                    'relobjdir': 'bar',
+                    'soname': 'bar',
+                }
+            ],
+        })
+
 
 if __name__ == '__main__':
     main()