Bug 1362612 - Add classes to handle computed flags, convert 'DISABLE_STL_WRAPPING' to use them. draft
authorChris Manchester <cmanchester@mozilla.com>
Fri, 28 Apr 2017 16:35:19 -0700
changeset 573644 a69cfb0b9ead4a1cac022214ad287d9c70e96f9b
parent 573359 23fe0b76a018a5077a0f7234cff91c41e4b6af64
child 573645 009372c94f464ecebe46adf58f8eb787a77293eb
push id57446
push usercmanchester@mozilla.com
push dateSat, 06 May 2017 00:45:11 +0000
bugs1362612
milestone55.0a1
Bug 1362612 - Add classes to handle computed flags, convert 'DISABLE_STL_WRAPPING' to use them. MozReview-Commit-ID: DuaQVibPenC
config/config.mk
python/mozbuild/mozbuild/backend/recursivemake.py
python/mozbuild/mozbuild/compilation/database.py
python/mozbuild/mozbuild/frontend/data.py
python/mozbuild/mozbuild/frontend/emitter.py
python/mozbuild/mozbuild/test/backend/test_recursivemake.py
python/mozbuild/mozbuild/test/frontend/test_emitter.py
--- a/config/config.mk
+++ b/config/config.mk
@@ -321,17 +321,17 @@ endif # CLANG_CL
 # Use warnings-as-errors if ALLOW_COMPILER_WARNINGS is not set to 1 (which
 # includes the case where it's undefined).
 ifneq (1,$(ALLOW_COMPILER_WARNINGS))
 CXXFLAGS += $(WARNINGS_AS_ERRORS)
 CFLAGS   += $(WARNINGS_AS_ERRORS)
 endif # ALLOW_COMPILER_WARNINGS
 
 COMPILE_CFLAGS	= $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CFLAGS) $(_DEPEND_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS)
-COMPILE_CXXFLAGS = $(if $(DISABLE_STL_WRAPPING),,$(STL_FLAGS)) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) $(_DEPEND_CFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS)
+COMPILE_CXXFLAGS = $(COMPUTED_CXXFLAGS) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) $(_DEPEND_CFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS)
 COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS)
 COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS)
 ASFLAGS += $(MOZBUILD_ASFLAGS)
 
 ifndef CROSS_COMPILE
 HOST_CFLAGS += $(RTL_FLAGS)
 endif
 
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -32,16 +32,17 @@ from ..frontend.data import (
     AndroidAssetsDirs,
     AndroidResDirs,
     AndroidExtraResDirs,
     AndroidExtraPackages,
     AndroidEclipseProjectData,
     BaseLibrary,
     BaseProgram,
     ChromeManifestEntry,
+    ComputedFlags,
     ConfigFileSubstitution,
     ContextDerived,
     ContextWrapped,
     Defines,
     DirectoryTraversal,
     ExternalLibrary,
     FinalTargetFiles,
     FinalTargetPreprocessedFiles,
@@ -585,16 +586,19 @@ class RecursiveMakeBackend(CommonBackend
             self._process_linked_libraries(obj, backend_file)
 
         elif isinstance(obj, LocalInclude):
             self._process_local_include(obj.path, backend_file)
 
         elif isinstance(obj, PerSourceFlag):
             self._process_per_source_flag(obj, backend_file)
 
+        elif isinstance(obj, ComputedFlags):
+            self._process_computed_flags(obj, backend_file)
+
         elif isinstance(obj, InstallationTarget):
             self._process_installation_target(obj, backend_file)
 
         elif isinstance(obj, ContextWrapped):
             # Process a rich build system object from the front-end
             # as-is.  Please follow precedent and handle CamelCaseData
             # in a function named _process_camel_case_data.  At some
             # point in the future, this unwrapping process may be
@@ -1185,16 +1189,20 @@ class RecursiveMakeBackend(CommonBackend
         else:
             path = d + path
         backend_file.write('LOCAL_INCLUDES += -I%s\n' % path)
 
     def _process_per_source_flag(self, per_source_flag, backend_file):
         for flag in per_source_flag.flags:
             backend_file.write('%s_FLAGS += %s\n' % (mozpath.basename(per_source_flag.file_name), flag))
 
+    def _process_computed_flags(self, computed_flags, backend_file):
+        for var, flags in computed_flags.flags.items():
+            backend_file.write('COMPUTED_%s += %s\n' % (var, make_quote(' '.join(flags))))
+
     def _process_java_jar_data(self, jar, backend_file):
         target = jar.name
         backend_file.write('JAVA_JAR_TARGETS += %s\n' % target)
         backend_file.write('%s_DEST := %s.jar\n' % (target, jar.name))
         if jar.sources:
             backend_file.write('%s_JAVAFILES := %s\n' %
                 (target, ' '.join(jar.sources)))
         if jar.generated_sources:
--- a/python/mozbuild/mozbuild/compilation/database.py
+++ b/python/mozbuild/mozbuild/compilation/database.py
@@ -5,16 +5,17 @@
 # This modules provides functionality for dealing with code completion.
 
 import os
 import types
 
 from mozbuild.compilation import util
 from mozbuild.backend.common import CommonBackend
 from mozbuild.frontend.data import (
+    ComputedFlags,
     Sources,
     GeneratedSources,
     DirectoryTraversal,
     Defines,
     Linkable,
     LocalInclude,
     PerSourceFlag,
     VariablePassthru,
@@ -65,17 +66,17 @@ class CompileDBBackend(CommonBackend):
 
         consumed = CommonBackend.consume_object(self, obj)
 
         if consumed:
             return True
 
         if isinstance(obj, DirectoryTraversal):
             self._envs[obj.objdir] = obj.config
-            for var in ('STL_FLAGS', 'VISIBILITY_FLAGS', 'WARNINGS_AS_ERRORS'):
+            for var in ('VISIBILITY_FLAGS', 'WARNINGS_AS_ERRORS'):
                 value = obj.config.substs.get(var)
                 if value:
                     self._local_flags[obj.objdir][var] = value
 
         elif isinstance(obj, (Sources, GeneratedSources)):
             # For other sources, include each source file.
             for f in obj.files:
                 self._build_db_line(obj.objdir, obj.relativedir, obj.config, f,
@@ -100,26 +101,27 @@ class CompileDBBackend(CommonBackend):
         elif isinstance(obj, VariablePassthru):
             if obj.variables.get('IS_GYP_DIR'):
                 self._gyp_dirs.add(obj.objdir)
             for var in ('MOZBUILD_CFLAGS', 'MOZBUILD_CXXFLAGS',
                         'MOZBUILD_CMFLAGS', 'MOZBUILD_CMMFLAGS',
                         'RTL_FLAGS', 'VISIBILITY_FLAGS'):
                 if var in obj.variables:
                     self._local_flags[obj.objdir][var] = obj.variables[var]
-            if (obj.variables.get('DISABLE_STL_WRAPPING') and
-                    'STL_FLAGS' in self._local_flags[obj.objdir]):
-                del self._local_flags[obj.objdir]['STL_FLAGS']
             if (obj.variables.get('ALLOW_COMPILER_WARNINGS') and
                     'WARNINGS_AS_ERRORS' in self._local_flags[obj.objdir]):
                 del self._local_flags[obj.objdir]['WARNINGS_AS_ERRORS']
 
         elif isinstance(obj, PerSourceFlag):
             self._per_source_flags[obj.file_name].extend(obj.flags)
 
+        elif isinstance(obj, ComputedFlags):
+            for var, flags in obj.flags.items():
+                self._local_flags[obj.objdir]['COMPUTED_%s' % var] = flags
+
         return True
 
     def consume_finished(self):
         CommonBackend.consume_finished(self)
 
         db = []
 
         for (directory, filename, unified), cmd in self._db.iteritems():
@@ -230,17 +232,17 @@ class CompileDBBackend(CommonBackend):
             value = cenv.substs.get(name)
             if not value:
                 return
             if isinstance(value, types.StringTypes):
                 value = value.split()
             db.extend(value)
 
         if canonical_suffix in ('.mm', '.cpp'):
-            db.append('$(STL_FLAGS)')
+            db.append('$(COMPUTED_CXXFLAGS)')
 
         db.extend((
             '$(VISIBILITY_FLAGS)',
             '$(DEFINES)',
             '-I%s' % mozpath.join(cenv.topsrcdir, reldir),
             '-I%s' % objdir,
             '$(LOCAL_INCLUDES)',
             '-I%s/dist/include' % cenv.topobjdir,
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -18,16 +18,18 @@ structures.
 from __future__ import absolute_import, unicode_literals
 
 from mozbuild.util import StrictOrderingOnAppendList
 from mozpack.chrome.manifest import ManifestEntry
 
 import mozpack.path as mozpath
 from .context import FinalTargetValue
 
+from collections import defaultdict
+
 from ..util import (
     group_unified_files,
 )
 
 from ..testing import (
     all_test_flavors,
 )
 
@@ -152,16 +154,27 @@ class VariablePassthru(ContextDerived):
     in our build backends since we will continue to be tied to our rules.mk.
     """
     __slots__ = ('variables')
 
     def __init__(self, context):
         ContextDerived.__init__(self, context)
         self.variables = {}
 
+
+class ComputedFlags(ContextDerived):
+    """Computed flags for convenient consumption by various backends.
+    """
+    __slots__ = ('flags')
+
+    def __init__(self, context):
+        ContextDerived.__init__(self, context)
+        self.flags = defaultdict(list)
+
+
 class XPIDLFile(ContextDerived):
     """Describes an XPIDL file to be compiled."""
 
     __slots__ = (
         'source_path',
         'basename',
         'module',
         'add_to_manifest',
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -25,16 +25,17 @@ import pytoml
 from .data import (
     AndroidAssetsDirs,
     AndroidExtraPackages,
     AndroidExtraResDirs,
     AndroidResDirs,
     BaseSources,
     BrandingFiles,
     ChromeManifestEntry,
+    ComputedFlags,
     ConfigFileSubstitution,
     ContextWrapped,
     Defines,
     DirectoryTraversal,
     Exports,
     FinalTargetFiles,
     FinalTargetPreprocessedFiles,
     GeneratedEventWebIDLFile,
@@ -921,17 +922,16 @@ class TreeMetadataEmitter(LoggingMixin):
         # them. We should aim to keep this set small because it violates the
         # desired abstraction of the build definition away from makefiles.
         passthru = VariablePassthru(context)
         varlist = [
             'ALLOW_COMPILER_WARNINGS',
             'ANDROID_APK_NAME',
             'ANDROID_APK_PACKAGE',
             'ANDROID_GENERATED_RESFILES',
-            'DISABLE_STL_WRAPPING',
             'EXTRA_DSO_LDOPTS',
             'RCFILE',
             'RESFILE',
             'RCINCLUDE',
             'DEFFILE',
             'WIN32_EXE_LDFLAGS',
             'LD_VERSION_SCRIPT',
             'USE_EXTENSION_MANIFEST',
@@ -961,16 +961,23 @@ class TreeMetadataEmitter(LoggingMixin):
             passthru.variables['IS_GYP_DIR'] = True
 
         dist_install = context['DIST_INSTALL']
         if dist_install is True:
             passthru.variables['DIST_INSTALL'] = True
         elif dist_install is False:
             passthru.variables['NO_DIST_INSTALL'] = True
 
+        computed_flags = ComputedFlags(context)
+        # Compute flags based on some vars.
+        if not context['DISABLE_STL_WRAPPING']:
+            stl_flags = context.config.substs.get('STL_FLAGS')
+            if stl_flags:
+                computed_flags.flags['CXXFLAGS'].append(stl_flags)
+
         # Ideally, this should be done in templates, but this is difficult at
         # the moment because USE_STATIC_LIBS can be set after a template
         # returns. Eventually, with context-based templates, it will be
         # possible.
         if (context.config.substs.get('OS_ARCH') == 'WINNT' and
                 not context.config.substs.get('GNU_CC')):
             use_static_lib = (context.get('USE_STATIC_LIBS') and
                               not context.config.substs.get('MOZ_ASAN'))
@@ -1152,16 +1159,19 @@ class TreeMetadataEmitter(LoggingMixin):
 
         android_extra_packages = context.get('ANDROID_EXTRA_PACKAGES')
         if android_extra_packages:
             yield AndroidExtraPackages(context, android_extra_packages)
 
         if passthru.variables:
             yield passthru
 
+        if computed_flags.flags:
+            yield computed_flags
+
     def _create_substitution(self, cls, context, path):
         sub = cls(context)
         sub.input_path = '%s.in' % path.full_path
         sub.output_path = path.translated
         sub.relpath = path
 
         return sub
 
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -314,19 +314,16 @@ class TestRecursiveMakeBackend(BackendTe
 
         backend_path = mozpath.join(env.topobjdir, 'backend.mk')
         lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
 
         expected = {
             'ALLOW_COMPILER_WARNINGS': [
                 'ALLOW_COMPILER_WARNINGS := 1',
             ],
-            'DISABLE_STL_WRAPPING': [
-                'DISABLE_STL_WRAPPING := 1',
-            ],
             'VISIBILITY_FLAGS': [
                 'VISIBILITY_FLAGS :=',
             ],
             'RCFILE': [
                 'RCFILE := foo.rc',
             ],
             'RESFILE': [
                 'RESFILE := bar.res',
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -175,17 +175,16 @@ class TestEmitterBasic(unittest.TestCase
         reader = self.reader('variable-passthru')
         objs = self.read_topsrcdir(reader)
 
         self.assertEqual(len(objs), 1)
         self.assertIsInstance(objs[0], VariablePassthru)
 
         wanted = {
             'ALLOW_COMPILER_WARNINGS': True,
-            'DISABLE_STL_WRAPPING': True,
             'NO_DIST_INSTALL': True,
             'VISIBILITY_FLAGS': '',
             'RCFILE': 'foo.rc',
             'RESFILE': 'bar.res',
             'RCINCLUDE': 'bar.rc',
             'DEFFILE': 'baz.def',
             'MOZBUILD_CFLAGS': ['-fno-exceptions', '-w'],
             'MOZBUILD_CXXFLAGS': ['-fcxx-exceptions', '-include foo.h'],