Bug 1437182 - Take IPDL/WebIDL generated sources into account when associating object files with linkables in the emitter. r=gps

MozReview-Commit-ID: BHABdAk3Esm

--HG--
extra : rebase_source : 83e344b3b5ab792731ebc137acf24ec2b40059ee
This commit is contained in:
Chris Manchester 2018-02-12 18:41:43 -08:00
Родитель d0d19d5199
Коммит d9c25ac16f
3 изменённых файлов: 65 добавлений и 39 удалений

Просмотреть файл

@ -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)

Просмотреть файл

@ -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"""

Просмотреть файл

@ -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)