Merge m-c to inbound.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 26 Sep 2012 21:37:18 -0400
changeset 108338 991b5fb6c55aa99fec1cdeaf2a1ca5dba028da0b
parent 108337 7faf6b82017faa0423237cbe1ccacc958ce29b4e (current diff)
parent 108297 d6d935e301cbd0d1fd9cefb0ade3acd49f845298 (diff)
child 108339 44c79a5f7131afd53808430e3d4ccd77bbe09b7e
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
milestone18.0a1
Merge m-c to inbound.
--- a/b2g/config/tooltool-manifests/ics.manifest
+++ b/b2g/config/tooltool-manifests/ics.manifest
@@ -1,16 +1,14 @@
 [
 {
-"size": 195,
-"digest":
-"7236ccc28312303e2f64b0afea767ca29c6c47c4714d727d68c294c898c75d06ba53486bf66cf4d76133fa780b1f5e330204c30a461f43f9b07a3dbfd4f653d4",
-"algorithm": "sha512",
+"size": 195, 
+"digest": "236362c71c433971c36b46d34e8560342435718364bc390df8de6a33249fb1fbf4fc3d0143f1e22bca262a7af7dc1b277a920bfde3ee8197eb07db2e7cef3e1f", 
+"algorithm": "sha512", 
 "filename": "setup.sh"
-},
+}, 
 {
-"size": 62788533,
-"digest":
-"1471e8847c9070d2062419a7be9d8921506b2d8b728d98986059771b8d45b4dba9afe54b25ba5665e4adde847cf4d5574c016c0390741139f6dd1749cd61d263",
-"algorithm": "sha512",
-"filename": "gonk-toolchain-6.tar.bz2"
+"size": 63159127, 
+"digest": "fcf629c815b5cbed7858d7697815f355275dcc6b060ae5455b4b31fde0d78ebc176927564a5353ceacdb9f9c9bfc1357f1341bf6ba844c25153a89664e661510", 
+"algorithm": "sha512", 
+"filename": "gonk-toolchain-7.tar.bz2"
 }
-]
\ No newline at end of file
+]
new file mode 100644
--- /dev/null
+++ b/python/mach/mach/build.py
@@ -0,0 +1,56 @@
+# 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 unicode_literals
+
+import logging
+import os
+
+from mach.base import ArgumentProvider
+from mozbuild.base import MozbuildObject
+
+
+class Build(MozbuildObject, ArgumentProvider):
+    """Interface to build the tree."""
+
+    def build(self):
+        # This code is only meant to be temporary until the more robust tree
+        # building code in bug 780329 lands.
+        from mozbuild.compilation.warnings import WarningsCollector
+        from mozbuild.compilation.warnings import WarningsDatabase
+
+        warnings_path = self._get_state_filename('warnings.json')
+        warnings_database = WarningsDatabase()
+
+        if os.path.exists(warnings_path):
+            warnings_database.load_from_file(warnings_path)
+
+        warnings_collector = WarningsCollector(database=warnings_database,
+            objdir=self.topobjdir)
+
+        def on_line(line):
+            try:
+                warning = warnings_collector.process_line(line)
+                if warning:
+                    self.log(logging.INFO, 'compiler_warning', warning,
+                        'Warning: {flag} in {filename}: {message}')
+            except:
+                # This will get logged in the more robust implementation.
+                pass
+
+            self.log(logging.INFO, 'build_output', {'line': line}, '{line}')
+
+        self._run_make(srcdir=True, filename='client.mk', line_handler=on_line,
+            log=False, print_directory=False)
+
+        self.log(logging.WARNING, 'warning_summary',
+            {'count': len(warnings_collector.database)},
+            '{count} compiler warnings present.')
+
+        warnings_database.save_to_file(warnings_path)
+
+    @staticmethod
+    def populate_argparse(parser):
+        build = parser.add_parser('build', help='Build the tree.')
+        build.set_defaults(cls=Build, method='build')
--- a/python/mach/mach/main.py
+++ b/python/mach/mach/main.py
@@ -14,23 +14,27 @@ import sys
 
 from mozbuild.base import BuildConfig
 from mozbuild.config import ConfigSettings
 from mozbuild.logger import LoggingManager
 
 # Import sub-command modules
 # TODO Bug 794509 do this via auto-discovery. Update README once this is
 # done.
+from mach.build import Build
 from mach.settings import Settings
 from mach.testing import Testing
+from mach.warnings import Warnings
 
 # Classes inheriting from ArgumentProvider that provide commands.
 HANDLERS = [
+    Build,
     Settings,
     Testing,
+    Warnings,
 ]
 
 # Classes inheriting from ConfigProvider that provide settings.
 # TODO this should come from auto-discovery somehow.
 SETTINGS_PROVIDERS = [
     BuildConfig,
 ]
 
new file mode 100644
--- /dev/null
+++ b/python/mach/mach/warnings.py
@@ -0,0 +1,83 @@
+# 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 print_function, unicode_literals
+
+import operator
+import os
+
+from mach.base import ArgumentProvider
+from mozbuild.base import MozbuildObject
+
+
+class Warnings(MozbuildObject, ArgumentProvider):
+    """Provide commands for inspecting warnings."""
+
+    @property
+    def database_path(self):
+        return self._get_state_filename('warnings.json')
+
+    @property
+    def database(self):
+        from mozbuild.compilation.warnings import WarningsDatabase
+
+        path = self.database_path
+
+        database = WarningsDatabase()
+
+        if os.path.exists(path):
+            database.load_from_file(path)
+
+        return database
+
+    def summary(self, report=None):
+        database = self.database
+
+        type_counts = database.type_counts
+        sorted_counts = sorted(type_counts.iteritems(),
+            key=operator.itemgetter(1))
+
+        total = 0
+        for k, v in sorted_counts:
+            print('%d\t%s' % (v, k))
+            total += v
+
+        print('%d\tTotal' % total)
+
+    def list(self, report=None):
+        database = self.database
+
+        by_name = sorted(database.warnings)
+
+        for warning in by_name:
+            filename = warning['filename']
+
+            if filename.startswith(self.topsrcdir):
+                filename = filename[len(self.topsrcdir) + 1:]
+
+            if warning['column'] is not None:
+                print('%s:%d:%d [%s] %s' % (filename, warning['line'],
+                    warning['column'], warning['flag'], warning['message']))
+            else:
+                print('%s:%d [%s] %s' % (filename, warning['line'],
+                    warning['flag'], warning['message']))
+
+    @staticmethod
+    def populate_argparse(parser):
+        summary = parser.add_parser('warnings-summary',
+            help='Show a summary of compiler warnings.')
+
+        summary.add_argument('report', default=None, nargs='?',
+            help='Warnings report to display. If not defined, show '
+                 'the most recent report')
+
+        summary.set_defaults(cls=Warnings, method='summary', report=None)
+
+        lst = parser.add_parser('warnings-list',
+            help='Show a list of compiler warnings')
+        lst.add_argument('report', default=None, nargs='?',
+            help='Warnings report to display. If not defined, show '
+                 'the most recent report.')
+
+        lst.set_defaults(cls=Warnings, method='list', report=None)
--- a/python/mozbuild/mozbuild/base.py
+++ b/python/mozbuild/mozbuild/base.py
@@ -179,25 +179,28 @@ class MozbuildObject(object):
         return os.path.join(self.topsrcdir, path)
 
     def _get_objdir_path(self, path):
         """Convert a relative path in the object directory to a full path."""
         return os.path.join(self.topobjdir, path)
 
     def _run_make(self, directory=None, filename=None, target=None, log=True,
             srcdir=False, allow_parallel=True, line_handler=None, env=None,
-            ignore_errors=False):
+            ignore_errors=False, silent=True, print_directory=True):
         """Invoke make.
 
         directory -- Relative directory to look for Makefile in.
         filename -- Explicit makefile to run.
         target -- Makefile target(s) to make. Can be a string or iterable of
             strings.
         srcdir -- If True, invoke make from the source directory tree.
             Otherwise, make will be invoked from the object directory.
+        silent -- If True (the default), run make in silent mode.
+        print_directory -- If True (the default), have make print directories
+        while doing traversal.
         """
         self._ensure_objdir_exists()
 
         args = [self._make_path]
 
         if directory:
             args.extend(['-C', directory])
 
@@ -205,24 +208,25 @@ class MozbuildObject(object):
             args.extend(['-f', filename])
 
         if allow_parallel:
             args.append('-j%d' % self.settings.build.threads)
 
         if ignore_errors:
             args.append('-k')
 
-        # Silent mode by default.
-        args.append('-s')
+        if silent:
+            args.append('-s')
 
         # Print entering/leaving directory messages. Some consumers look at
         # these to measure progress. Ideally, we'd do everything with pymake
         # and use hooks in its API. Unfortunately, it doesn't provide that
         # feature... yet.
-        args.append('-w')
+        if print_directory:
+            args.append('-w')
 
         if isinstance(target, list):
             args.extend(target)
         elif target:
             args.append(target)
 
         fn = self._run_command_in_objdir