--- a/python/mozbuild/mozbuild/backend/common.py
+++ b/python/mozbuild/mozbuild/backend/common.py
@@ -226,26 +226,19 @@ class CommonBackend(BuildBackend):
import mozwebidlcodegen
manager = mozwebidlcodegen.create_build_system_manager(
self.environment.topsrcdir,
self.environment.topobjdir,
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)
def _write_unified_file(self, unified_file, source_filenames,
output_directory, poison_windows_h=False):
with self._write_file(mozpath.join(output_directory, unified_file)) as f:
f.write('#define MOZ_UNIFIED_BUILD\n')
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -272,17 +272,17 @@ class WebIDLCollection(ContextDerived):
def all_test_basenames(self):
return [mozpath.basename(source) for source in self.all_test_sources()]
def all_test_stems(self):
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 | \
self.test_sources
def all_non_static_sources(self):
return self.generated_sources | self.all_preprocessed_sources()
@@ -302,16 +302,31 @@ class WebIDLCollection(ContextDerived):
return [mozpath.splitext(b)[0] for b in self.all_basenames()]
def generated_events_basenames(self):
return [mozpath.basename(s) for s in self.generated_events_sources]
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."""
def __init__(self, context):
ContextDerived.__init__(self, context)
self.sources = set()
self.preprocessed_sources = set()
@@ -344,16 +359,19 @@ class IPDLCollection(ContextDerived):
@property
def unified_source_mapping(self):
return list(group_unified_files(self.all_generated_sources(),
unified_prefix='UnifiedProtocols',
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"""
class LinkageMultipleRustLibrariesError(Exception):
"""Error thrown when trying to link multiple Rust libraries to an object"""
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -197,17 +197,52 @@ class TreeMetadataEmitter(LoggingMixin):
if self.config.substs.get('COMPILE_ENVIRONMENT'):
start = time.time()
objs = list(self._emit_libs_derived(contexts))
self._emitter_time += time.time() - start
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
if lib.link_into not in self._libs:
raise SandboxValidationError(
'FINAL_LIBRARY ("%s") does not match any LIBRARY_NAME'
% lib.link_into, contexts[lib.objdir])
candidates = self._libs[lib.link_into]
@@ -223,19 +258,19 @@ class TreeMetadataEmitter(LoggingMixin):
c.link_library(lib)
else:
raise SandboxValidationError(
'FINAL_LIBRARY ("%s") matches a LIBRARY_NAME defined in '
'multiple places:\n %s' % (lib.link_into,
'\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:
yield o
if isinstance(o, StaticLibrary):
for q in recurse_refs(o):
yield q
@@ -283,61 +318,41 @@ class TreeMetadataEmitter(LoggingMixin):
yield flags_obj
for flags_obj in self._compile_as_flags.values():
yield flags_obj
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',
'target': 'LIBRARY_NAME',
}
LIBSTDCXX_VAR = {
'host': 'MOZ_LIBSTDCXX_HOST_VERSION',
'target': 'MOZ_LIBSTDCXX_TARGET_VERSION',
}
STDCXXCOMPAT_NAME = {
'host': 'host_stdc++compat',
'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)
# Link system libraries from OS_LIBS/HOST_OS_LIBS.
for lib in context.get(variable.replace('USE', 'OS'), []):
obj.link_system_library(lib)
# We have to wait for all the self._link_library calls above to have