Bug 1319222 - Add an SFLAGS ComputedFlags variable for compiling *.S; r=chmanchester draft
authorMike Shal <mshal@mozilla.com>
Wed, 22 Nov 2017 15:27:52 -0500
changeset 707633 970c31d7d35d491a533991821a9dbccc2e373704
parent 707632 69fbea3ee15901f98f594366414106bdede8983d
child 707634 a390faab307e201b73cce0070f07ba40f15b8ab6
push id92183
push userbmo:mshal@mozilla.com
push dateTue, 05 Dec 2017 16:33:02 +0000
reviewerschmanchester
bugs1319222
milestone59.0a1
Bug 1319222 - Add an SFLAGS ComputedFlags variable for compiling *.S; r=chmanchester Both SFLAGS and ASFLAGS are used to compile assembly, but SFLAGS include DEFINES and LOCAL_INCLUDES whereas ASFLAGS do not. It seems easiest to just separate them into two different ComputedFlags values so that the backend can distinguish between the two types. MozReview-Commit-ID: Bkm3621ImJG
config/config.mk
config/rules.mk
python/mozbuild/mozbuild/frontend/context.py
python/mozbuild/mozbuild/frontend/emitter.py
python/mozbuild/mozbuild/test/frontend/test_emitter.py
--- a/config/config.mk
+++ b/config/config.mk
@@ -200,16 +200,17 @@ include $(MOZILLA_DIR)/config/static-che
 
 LDFLAGS		= $(COMPUTED_LDFLAGS) $(PGO_LDFLAGS) $(MK_LDFLAGS)
 
 COMPILE_CFLAGS	= $(COMPUTED_CFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
 COMPILE_CXXFLAGS = $(COMPUTED_CXXFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
 COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS)
 COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS)
 ASFLAGS = $(COMPUTED_ASFLAGS)
+SFLAGS = $(COMPUTED_SFLAGS)
 
 HOST_CFLAGS = $(COMPUTED_HOST_CFLAGS) $(_DEPEND_CFLAGS)
 HOST_CXXFLAGS = $(COMPUTED_HOST_CXXFLAGS) $(_DEPEND_CFLAGS)
 
 # We only add color flags if neither the flag to disable color
 # (e.g. "-fno-color-diagnostics" nor a flag to control color
 # (e.g. "-fcolor-diagnostics=never") is present.
 define colorize_flags
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1017,17 +1017,17 @@ force-cargo-host-program-check:
 	$(call CARGO_CHECK) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
 else
 force-cargo-host-program-check:
 	@true
 endif # HOST_RUST_PROGRAMS
 
 $(SOBJS):
 	$(REPORT_BUILD)
-	$(AS) -o $@ $(DEFINES) $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) -c $<
+	$(AS) -o $@ $(SFLAGS) $($(notdir $<)_FLAGS) -c $<
 
 $(CPPOBJS):
 	$(REPORT_BUILD_VERBOSE)
 	$(call BUILDSTATUS,OBJECT_FILE $@)
 	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(_VPATH_SRCS)
 
 $(CMMOBJS):
 	$(REPORT_BUILD_VERBOSE)
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -343,19 +343,22 @@ class HostCompileFlags(BaseCompileFlags)
             optimize_flags += self._context.config.substs.get('MOZ_OPTIMIZE_FLAGS')
         return optimize_flags
 
 
 class AsmFlags(BaseCompileFlags):
     def __init__(self, context):
         self._context = context
         self.flag_variables = (
-            ('OS', context.config.substs.get('ASFLAGS'), ('ASFLAGS',)),
-            ('DEBUG', self._debug_flags(), ('ASFLAGS',)),
-            ('MOZBUILD', None, ('ASFLAGS',)),
+            ('DEFINES', None, ('SFLAGS',)),
+            ('LIBRARY_DEFINES', None, ('SFLAGS',)),
+            ('OS', context.config.substs.get('ASFLAGS'), ('ASFLAGS', 'SFLAGS')),
+            ('DEBUG', self._debug_flags(), ('ASFLAGS', 'SFLAGS')),
+            ('LOCAL_INCLUDES', None, ('SFLAGS',)),
+            ('MOZBUILD', None, ('ASFLAGS', 'SFLAGS')),
         )
         BaseCompileFlags.__init__(self, context)
 
     def _debug_flags(self):
         debug_flags = []
         if (self._context.config.substs.get('MOZ_DEBUG') or
             self._context.config.substs.get('MOZ_DEBUG_SYMBOLS')):
             if self._context.get('USE_YASM'):
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -132,16 +132,17 @@ class TreeMetadataEmitter(LoggingMixin):
 
         self._libs = OrderedDefaultDict(list)
         self._binaries = OrderedDict()
         self._compile_dirs = set()
         self._host_compile_dirs = set()
         self._rust_compile_dirs = set()
         self._asm_compile_dirs = set()
         self._compile_flags = dict()
+        self._compile_as_flags = dict()
         self._linkage = []
         self._static_linking_shared = set()
         self._crate_verified_local = set()
         self._crate_directories = dict()
 
         # Keep track of external paths (third party build systems), starting
         # from what we run a subconfigure in. We'll eliminate some directories
         # as we traverse them with moz.build (e.g. js/src).
@@ -273,19 +274,26 @@ class TreeMetadataEmitter(LoggingMixin):
 
 
         for lib in (l for libs in self._libs.values() for l in libs):
             lib_defines = list(lib.lib_defines.get_defines())
             if lib_defines:
                 objdir_flags = self._compile_flags[lib.objdir]
                 objdir_flags.resolve_flags('LIBRARY_DEFINES', lib_defines)
 
+                objdir_flags = self._compile_as_flags.get(lib.objdir)
+                if objdir_flags:
+                    objdir_flags.resolve_flags('LIBRARY_DEFINES', lib_defines)
+
         for flags_obj in self._compile_flags.values():
             yield flags_obj
 
+        for flags_obj in self._compile_as_flags.values():
+            yield flags_obj
+
         for obj in self._binaries.values():
             yield obj
 
     LIBRARY_NAME_VAR = {
         'host': 'HOST_LIBRARY_NAME',
         'target': 'LIBRARY_NAME',
     }
 
@@ -1020,33 +1028,34 @@ class TreeMetadataEmitter(LoggingMixin):
             yield obj
 
         for path in context['CONFIGURE_SUBST_FILES']:
             sub = self._create_substitution(ConfigFileSubstitution, context,
                 path)
             generated_files.add(str(sub.relpath))
             yield sub
 
-        for defines_var, cls, backend_flags in (('DEFINES', Defines, computed_flags),
-                                                ('HOST_DEFINES', HostDefines, computed_host_flags)):
+        for defines_var, cls, backend_flags in (('DEFINES', Defines, (computed_flags, computed_as_flags)),
+                                                ('HOST_DEFINES', HostDefines, (computed_host_flags,))):
             defines = context.get(defines_var)
             if defines:
                 defines_obj = cls(context, defines)
                 if isinstance(defines_obj, Defines):
                     # DEFINES have consumers outside the compile command line,
                     # HOST_DEFINES do not.
                     yield defines_obj
             else:
                 # If we don't have explicitly set defines we need to make sure
                 # initialized values if present end up in computed flags.
                 defines_obj = cls(context, context[defines_var])
 
             defines_from_obj = list(defines_obj.get_defines())
             if defines_from_obj:
-                backend_flags.resolve_flags(defines_var, defines_from_obj)
+                for flags in backend_flags:
+                    flags.resolve_flags(defines_var, defines_from_obj)
 
         simple_lists = [
             ('GENERATED_EVENTS_WEBIDL_FILES', GeneratedEventWebIDLFile),
             ('GENERATED_WEBIDL_FILES', GeneratedWebIDLFile),
             ('IPDL_SOURCES', IPDLFile),
             ('PREPROCESSED_TEST_WEBIDL_FILES', PreprocessedTestWebIDLFile),
             ('PREPROCESSED_WEBIDL_FILES', PreprocessedWebIDLFile),
             ('TEST_WEBIDL_FILES', TestWebIDLFile),
@@ -1064,16 +1073,17 @@ class TreeMetadataEmitter(LoggingMixin):
                 raise SandboxValidationError('Path specified in LOCAL_INCLUDES '
                     'does not exist: %s (resolved to %s)' % (local_include,
                     local_include.full_path), context)
             include_obj = LocalInclude(context, local_include)
             local_includes.append(include_obj.path.full_path)
             yield include_obj
 
         computed_flags.resolve_flags('LOCAL_INCLUDES', ['-I%s' % p for p in local_includes])
+        computed_as_flags.resolve_flags('LOCAL_INCLUDES', ['-I%s' % p for p in local_includes])
 
         for obj in self._handle_linkables(context, passthru, generated_files):
             yield obj
 
         generated_files.update(['%s%s' % (k, self.config.substs.get('BIN_SUFFIX', '')) for k in self._binaries.keys()])
 
         components = []
         for var, cls in (
@@ -1225,17 +1235,17 @@ class TreeMetadataEmitter(LoggingMixin):
 
         if context.objdir in self._compile_dirs:
             self._compile_flags[context.objdir] = computed_flags
             yield computed_link_flags
         elif context.objdir in self._rust_compile_dirs:
             yield computed_link_flags
 
         if context.objdir in self._asm_compile_dirs:
-            yield computed_as_flags
+            self._compile_as_flags[context.objdir] = computed_as_flags
 
         if context.objdir in self._host_compile_dirs:
             yield computed_host_flags
 
 
     def _create_substitution(self, cls, context, path):
         sub = cls(context)
         sub.input_path = '%s.in' % path.full_path
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -210,17 +210,17 @@ class TestEmitterBasic(unittest.TestCase
         self.assertEqual(flags.flags['WARNINGS_AS_ERRORS'], ['-Werror'])
         self.assertEqual(flags.flags['MOZBUILD_CFLAGS'], ['-Wall', '-funroll-loops'])
         self.assertEqual(flags.flags['MOZBUILD_CXXFLAGS'], ['-funroll-loops', '-Wall'])
 
     def test_asflags(self):
         reader = self.reader('asflags', extra_substs={
             'ASFLAGS': ['-safeseh'],
         })
-        as_sources, sources, ldflags, asflags, lib, flags = self.read_topsrcdir(reader)
+        as_sources, sources, ldflags, lib, flags, asflags = self.read_topsrcdir(reader)
         self.assertIsInstance(asflags, ComputedFlags)
         self.assertEqual(asflags.flags['OS'], reader.config.substs['ASFLAGS'])
         self.assertEqual(asflags.flags['MOZBUILD'], ['-no-integrated-as'])
 
     def test_debug_flags(self):
         reader = self.reader('compile-flags', extra_substs={
             'MOZ_DEBUG_FLAGS': '-g',
             'MOZ_DEBUG_SYMBOLS': '1',
@@ -432,22 +432,22 @@ class TestEmitterBasic(unittest.TestCase
 
         # When yasm is available, this should work.
         reader = self.reader('use-yasm',
                              extra_substs=dict(
                                  YASM='yasm',
                                  YASM_ASFLAGS='-foo',
                              ))
 
-        sources, passthru, ldflags, asflags, lib, flags = self.read_topsrcdir(reader)
+        sources, passthru, ldflags, lib, flags, asflags = self.read_topsrcdir(reader)
 
         self.assertIsInstance(passthru, VariablePassthru)
         self.assertIsInstance(ldflags, ComputedFlags)
+        self.assertIsInstance(flags, ComputedFlags)
         self.assertIsInstance(asflags, ComputedFlags)
-        self.assertIsInstance(flags, ComputedFlags)
 
         self.assertEqual(asflags.flags['OS'], reader.config.substs['YASM_ASFLAGS'])
 
         maxDiff = self.maxDiff
         self.maxDiff = None
         self.assertEqual(passthru.variables,
                          {'AS': 'yasm',
                           'AS_DASH_C_FLAG': ''})
@@ -1022,23 +1022,23 @@ class TestEmitterBasic(unittest.TestCase
             defines_in_flags[flags.relobjdir] = ' '.join(flags.flags['LIBRARY_DEFINES'] or [])
         self.assertEqual(expected, defines_in_flags)
 
     def test_sources(self):
         """Test that SOURCES works properly."""
         reader = self.reader('sources')
         objs = self.read_topsrcdir(reader)
 
+        as_flags = objs.pop()
+        self.assertIsInstance(as_flags, ComputedFlags)
         computed_flags = objs.pop()
         self.assertIsInstance(computed_flags, ComputedFlags)
-        # The second to last object is a Linkable.
+        # The third to last object is a Linkable.
         linkable = objs.pop()
         self.assertTrue(linkable.cxx_link)
-        as_flags = objs.pop()
-        self.assertIsInstance(as_flags, ComputedFlags)
         ld_flags = objs.pop()
         self.assertIsInstance(ld_flags, ComputedFlags)
         self.assertEqual(len(objs), 6)
         for o in objs:
             self.assertIsInstance(o, Sources)
 
         suffix_map = {obj.canonical_suffix: obj for obj in objs}
         self.assertEqual(len(suffix_map), 6)
@@ -1057,19 +1057,21 @@ class TestEmitterBasic(unittest.TestCase
                 sources.files,
                 [mozpath.join(reader.config.topsrcdir, f) for f in files])
 
     def test_sources_just_c(self):
         """Test that a linkable with no C++ sources doesn't have cxx_link set."""
         reader = self.reader('sources-just-c')
         objs = self.read_topsrcdir(reader)
 
+        as_flags = objs.pop()
+        self.assertIsInstance(as_flags, ComputedFlags)
         flags = objs.pop()
         self.assertIsInstance(flags, ComputedFlags)
-        # The second to last object is a Linkable.
+        # The third to last object is a Linkable.
         linkable = objs.pop()
         self.assertFalse(linkable.cxx_link)
 
     def test_linkables_cxx_link(self):
         """Test that linkables transitively set cxx_link properly."""
         reader = self.reader('test-linkables-cxx-link')
         got_results = 0
         for obj in self.read_topsrcdir(reader):
@@ -1082,24 +1084,26 @@ class TestEmitterBasic(unittest.TestCase
                     got_results += 1
         self.assertEqual(got_results, 2)
 
     def test_generated_sources(self):
         """Test that GENERATED_SOURCES works properly."""
         reader = self.reader('generated-sources')
         objs = self.read_topsrcdir(reader)
 
+        as_flags = objs.pop()
+        self.assertIsInstance(as_flags, ComputedFlags)
         flags = objs.pop()
         self.assertIsInstance(flags, ComputedFlags)
-        # The second to last object is a Linkable.
+        # The third to last object is a Linkable.
         linkable = objs.pop()
         self.assertTrue(linkable.cxx_link)
         flags = objs.pop()
         self.assertIsInstance(flags, ComputedFlags)
-        self.assertEqual(len(objs), 7)
+        self.assertEqual(len(objs), 6)
 
         generated_sources = [o for o in objs if isinstance(o, GeneratedSources)]
         self.assertEqual(len(generated_sources), 6)
 
         suffix_map = {obj.canonical_suffix: obj for obj in generated_sources}
         self.assertEqual(len(suffix_map), 6)
 
         expected = {