diff --git a/python/mozbuild/mozbuild/backend/common.py b/python/mozbuild/mozbuild/backend/common.py index ad65e24be62b..d00cbbcaf5fb 100644 --- a/python/mozbuild/mozbuild/backend/common.py +++ b/python/mozbuild/mozbuild/backend/common.py @@ -231,16 +231,9 @@ class CommonBackend(BuildBackend): mozpath.join(self.environment.topobjdir, 'dist') ) self._handle_generated_sources(manager.expected_build_output_files()) - # Bindings are compiled in unified mode to speed up compilation and - # to reduce linker memory size. Note that test bindings are separated - # from regular ones so tests bindings aren't shipped. - unified_source_mapping = list(group_unified_files(webidls.all_regular_cpp_basenames(), - unified_prefix='UnifiedBindings', - unified_suffix='cpp', - files_per_unified_file=32)) - self._write_unified_files(unified_source_mapping, bindings_dir, + self._write_unified_files(webidls.unified_source_mapping, bindings_dir, poison_windows_h=True) - self._handle_webidl_build(bindings_dir, unified_source_mapping, + self._handle_webidl_build(bindings_dir, webidls.unified_source_mapping, webidls, manager.expected_build_output_files(), manager.GLOBAL_DEFINE_FILES) diff --git a/python/mozbuild/mozbuild/frontend/data.py b/python/mozbuild/mozbuild/frontend/data.py index 51b368417576..2e5f8779bb0b 100644 --- a/python/mozbuild/mozbuild/frontend/data.py +++ b/python/mozbuild/mozbuild/frontend/data.py @@ -277,7 +277,7 @@ class WebIDLCollection(ContextDerived): return [mozpath.splitext(b)[0] for b in self.all_test_basenames()] def all_test_cpp_basenames(self): - return ['%sBinding.cpp' % s for s in self.all_test_stems()] + return sorted('%sBinding.cpp' % s for s in self.all_test_stems()) def all_static_sources(self): return self.sources | self.generated_events_sources | \ @@ -307,6 +307,21 @@ class WebIDLCollection(ContextDerived): def generated_events_stems(self): return [mozpath.splitext(b)[0] for b in self.generated_events_basenames()] + @property + def unified_source_mapping(self): + # Bindings are compiled in unified mode to speed up compilation and + # to reduce linker memory size. Note that test bindings are separated + # from regular ones so tests bindings aren't shipped. + return list(group_unified_files(self.all_regular_cpp_basenames(), + unified_prefix='UnifiedBindings', + unified_suffix='cpp', + files_per_unified_file=32)) + + def all_source_files(self): + from mozwebidlcodegen import WebIDLCodegenManager + return (sorted(list(WebIDLCodegenManager.GLOBAL_DEFINE_FILES)) + + sorted(set(p for p, _ in self.unified_source_mapping))) + class IPDLCollection(ContextDerived): """Collects IPDL files during the build.""" @@ -349,6 +364,9 @@ class IPDLCollection(ContextDerived): unified_suffix='cpp', files_per_unified_file=16)) + def all_source_files(self): + return sorted(set(p for p, _ in self.unified_source_mapping)) + class LinkageWrongKindError(Exception): """Error thrown when trying to link objects of the wrong kind""" diff --git a/python/mozbuild/mozbuild/frontend/emitter.py b/python/mozbuild/mozbuild/frontend/emitter.py index d0e91bc8a593..9546e41a5b67 100644 --- a/python/mozbuild/mozbuild/frontend/emitter.py +++ b/python/mozbuild/mozbuild/frontend/emitter.py @@ -202,7 +202,42 @@ class TreeMetadataEmitter(LoggingMixin): for o in emit_objs(objs): yield o def _emit_libs_derived(self, contexts): - # First do FINAL_LIBRARY linkage. + + # First aggregate idl sources. + webidl_attrs = [ + ('GENERATED_EVENTS_WEBIDL_FILES', lambda c: c.generated_events_sources), + ('GENERATED_WEBIDL_FILES', lambda c: c.generated_sources), + ('PREPROCESSED_TEST_WEBIDL_FILES', lambda c: c.preprocessed_test_sources), + ('PREPROCESSED_WEBIDL_FILES', lambda c: c.preprocessed_sources), + ('TEST_WEBIDL_FILES', lambda c: c.test_sources), + ('WEBIDL_FILES', lambda c: c.sources), + ('WEBIDL_EXAMPLE_INTERFACES', lambda c: c.example_interfaces), + ] + ipdl_attrs = [ + ('IPDL_SOURCES', lambda c: c.sources), + ('PREPROCESSED_IPDL_SOURCES', lambda c: c.preprocessed_sources), + ] + + idl_sources = {} + for root, cls, attrs in ((self.config.substs.get('WEBIDL_ROOT'), + WebIDLCollection, webidl_attrs), + (self.config.substs.get('IPDL_ROOT'), + IPDLCollection, ipdl_attrs)): + if root: + collection = cls(contexts[root]) + for var, src_getter in attrs: + src_getter(collection).update(self._idls[var]) + + idl_sources[root] = collection.all_source_files() + if isinstance(collection, WebIDLCollection): + # Test webidl sources are added here as a somewhat special + # case. + idl_sources[mozpath.join(root, 'test')] = [s for s in collection.all_test_cpp_basenames()] + + yield collection + + + # Next do FINAL_LIBRARY linkage. for lib in (l for libs in self._libs.values() for l in libs): if not isinstance(lib, (StaticLibrary, RustLibrary)) or not lib.link_into: continue @@ -228,9 +263,9 @@ class TreeMetadataEmitter(LoggingMixin): '\n '.join(l.objdir for l in candidates)), contexts[lib.objdir]) - # Next, USE_LIBS linkage. + # ...and USE_LIBS linkage. for context, obj, variable in self._linkage: - self._link_libraries(context, obj, variable) + self._link_libraries(context, obj, variable, idl_sources) def recurse_refs(lib): for o in lib.refs: @@ -288,31 +323,6 @@ class TreeMetadataEmitter(LoggingMixin): for obj in self._binaries.values(): yield obj - webidl_attrs = [ - ('GENERATED_EVENTS_WEBIDL_FILES', lambda c: c.generated_events_sources), - ('GENERATED_WEBIDL_FILES', lambda c: c.generated_sources), - ('PREPROCESSED_TEST_WEBIDL_FILES', lambda c: c.preprocessed_test_sources), - ('PREPROCESSED_WEBIDL_FILES', lambda c: c.preprocessed_sources), - ('TEST_WEBIDL_FILES', lambda c: c.test_sources), - ('WEBIDL_FILES', lambda c: c.sources), - ('WEBIDL_EXAMPLE_INTERFACES', lambda c: c.example_interfaces), - ] - ipdl_attrs = [ - ('IPDL_SOURCES', lambda c: c.sources), - ('PREPROCESSED_IPDL_SOURCES', lambda c: c.preprocessed_sources), - ] - - for root, cls, attrs in ((self.config.substs.get('WEBIDL_ROOT'), - WebIDLCollection, webidl_attrs), - (self.config.substs.get('IPDL_ROOT'), - IPDLCollection, ipdl_attrs)): - if root: - collection = cls(contexts[root]) - for var, src_getter in attrs: - src_getter(collection).update(self._idls[var]) - - yield collection - LIBRARY_NAME_VAR = { 'host': 'HOST_LIBRARY_NAME', @@ -329,10 +339,15 @@ class TreeMetadataEmitter(LoggingMixin): 'target': 'stdc++compat', } - def _link_libraries(self, context, obj, variable): + def _link_libraries(self, context, obj, variable, extra_sources): """Add linkage declarations to a given object.""" assert isinstance(obj, Linkable) + if context.objdir in extra_sources: + # All "extra sources" are .cpp for the moment, and happen to come + # first in order. + obj.sources['.cpp'] = extra_sources[context.objdir] + obj.sources['.cpp'] + for path in context.get(variable, []): self._link_library(context, obj, variable, path)