Bug 1437182 - Note object files associated with linkables in the emitter. r=gps

MozReview-Commit-ID: 3IR8TolZpKs

--HG--
extra : rebase_source : 48063f31cec6f4ca40f699f038cfc76b3095c995
This commit is contained in:
Chris Manchester 2018-02-09 14:28:02 -08:00
parent 3d2179915d
commit fe4e66cbd1
6 changed files with 93 additions and 9 deletions

View File

@ -365,6 +365,7 @@ class Linkable(ContextDerived):
'lib_defines',
'linked_libraries',
'linked_system_libs',
'sources',
)
def __init__(self, context):
@ -373,6 +374,7 @@ class Linkable(ContextDerived):
self.linked_libraries = []
self.linked_system_libs = []
self.lib_defines = Defines(context, {})
self.sources = defaultdict(list)
def link_library(self, obj):
assert isinstance(obj, BaseLibrary)
@ -404,6 +406,26 @@ class Linkable(ContextDerived):
)
self.linked_system_libs.append(lib)
def source_files(self):
all_sources = []
# This is ordered for reproducibility and consistently w/
# config/rules.mk
for suffix in ('.c', '.S', '.cpp', '.m', '.mm', '.s'):
all_sources += self.sources.get(suffix, [])
return all_sources
@property
def objs(self):
obj_prefix = ''
if self.KIND == 'host':
obj_prefix = 'host_'
return [mozpath.join(self.objdir, '%s%s.%s' % (obj_prefix,
mozpath.splitext(mozpath.basename(f))[0],
self.config.substs.get('OBJ_SUFFIX', '')))
for f in self.source_files()]
class BaseProgram(Linkable):
"""Context derived container object for programs, which is a unicode
string.
@ -453,6 +475,13 @@ class SimpleProgram(BaseProgram):
SUFFIX_VAR = 'BIN_SUFFIX'
KIND = 'target'
def source_files(self):
for srcs in self.sources.values():
for f in srcs:
if mozpath.basename(mozpath.splitext(f)[0]) == mozpath.splitext(self.program)[0]:
return [f]
return []
class HostSimpleProgram(HostMixin, BaseProgram):
"""Context derived container object for each program in

View File

@ -947,6 +947,9 @@ class TreeMetadataEmitter(LoggingMixin):
# a directory with mixed C and C++ source, but it's not that important.
cxx_sources = defaultdict(bool)
# Source files to track for linkables associated with this context.
ctxt_sources = defaultdict(lambda: defaultdict(list))
for variable, (klass, gen_klass, suffixes) in varmap.items():
allowed_suffixes = set().union(*[suffix_map[s] for s in suffixes])
@ -972,8 +975,21 @@ class TreeMetadataEmitter(LoggingMixin):
if variable.startswith('UNIFIED_'):
arglist.append(context.get('FILES_PER_UNIFIED_FILE', 16))
obj = cls(*arglist)
srcs = obj.files
if isinstance(obj, UnifiedSources) and obj.have_unified_mapping:
srcs = dict(obj.unified_source_mapping).keys()
ctxt_sources[variable][canonical_suffix] += sorted(srcs)
yield obj
if ctxt_sources:
for linkable in linkables:
for target_var in ('SOURCES', 'UNIFIED_SOURCES'):
for suffix, srcs in ctxt_sources[target_var].items():
linkable.sources[suffix] += srcs
for host_linkable in host_linkables:
for suffix, srcs in ctxt_sources['HOST_SOURCES'].items():
host_linkable.sources[suffix] += srcs
for f, flags in all_flags.iteritems():
if flags.flags:
ext = mozpath.splitext(f)[1]

View File

@ -7,8 +7,9 @@ def Program(name):
@template
def SimplePrograms(names):
def SimplePrograms(names, ext='.cpp'):
SIMPLE_PROGRAMS += names
SOURCES += ['%s%s' % (name, ext) for name in names]
Program('test_program')

View File

@ -81,6 +81,7 @@ class TestEmitterBasic(unittest.TestCase):
STL_FLAGS=['-I/path/to/topobjdir/dist/stl_wrappers'],
VISIBILITY_FLAGS=['-include',
'$(topsrcdir)/config/gcc_hidden.h'],
OBJ_SUFFIX='obj',
)
if extra_substs:
substs.update(extra_substs)
@ -642,16 +643,26 @@ class TestEmitterBasic(unittest.TestCase):
reader = self.reader('program')
objs = self.read_topsrcdir(reader)
self.assertEqual(len(objs), 5)
self.assertIsInstance(objs[0], ComputedFlags)
self.assertEqual(len(objs), 6)
self.assertIsInstance(objs[0], Sources)
self.assertIsInstance(objs[1], ComputedFlags)
self.assertIsInstance(objs[2], Program)
self.assertIsInstance(objs[3], SimpleProgram)
self.assertIsInstance(objs[2], ComputedFlags)
self.assertIsInstance(objs[3], Program)
self.assertIsInstance(objs[4], SimpleProgram)
self.assertIsInstance(objs[5], SimpleProgram)
self.assertEqual(objs[2].program, 'test_program.prog')
self.assertEqual(objs[3].program, 'test_program1.prog')
self.assertEqual(objs[4].program, 'test_program2.prog')
self.assertEqual(objs[3].program, 'test_program.prog')
self.assertEqual(objs[4].program, 'test_program1.prog')
self.assertEqual(objs[5].program, 'test_program2.prog')
self.assertEqual(objs[4].objs,
[mozpath.join(reader.config.topobjdir,
'test_program1.%s' %
reader.config.substs['OBJ_SUFFIX'])])
self.assertEqual(objs[5].objs,
[mozpath.join(reader.config.topobjdir,
'test_program2.%s' %
reader.config.substs['OBJ_SUFFIX'])])
def test_test_manifest_missing_manifest(self):
"""A missing manifest file should result in an error."""
@ -1132,6 +1143,12 @@ class TestEmitterBasic(unittest.TestCase):
sources.files,
[mozpath.join(reader.config.topsrcdir, f) for f in files])
for f in files:
self.assertIn(mozpath.join(reader.config.topobjdir,
'%s.%s' % (mozpath.splitext(f)[0],
reader.config.substs['OBJ_SUFFIX'])),
linkable.objs)
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')
@ -1195,6 +1212,12 @@ class TestEmitterBasic(unittest.TestCase):
sources.files,
[mozpath.join(reader.config.topobjdir, f) for f in files])
for f in files:
self.assertIn(mozpath.join(reader.config.topobjdir,
'%s.%s' % (mozpath.splitext(f)[0],
reader.config.substs['OBJ_SUFFIX'])),
linkable.objs)
def test_host_sources(self):
"""Test that HOST_SOURCES works properly."""
reader = self.reader('host-sources')
@ -1230,13 +1253,21 @@ class TestEmitterBasic(unittest.TestCase):
sources.files,
[mozpath.join(reader.config.topsrcdir, f) for f in files])
for f in files:
self.assertIn(mozpath.join(reader.config.topobjdir,
'host_%s.%s' % (mozpath.splitext(f)[0],
reader.config.substs['OBJ_SUFFIX'])),
linkable.objs)
def test_unified_sources(self):
"""Test that UNIFIED_SOURCES works properly."""
reader = self.reader('unified-sources')
objs = self.read_topsrcdir(reader)
# The last object is a Linkable, the second to last ComputedFlags,
# The last object is a ComputedFlags, the second to last a Linkable,
# followed by ldflags, ignore them.
linkable = objs[-2]
objs = objs[:-3]
self.assertEqual(len(objs), 3)
for o in objs:
@ -1257,6 +1288,13 @@ class TestEmitterBasic(unittest.TestCase):
[mozpath.join(reader.config.topsrcdir, f) for f in files])
self.assertTrue(sources.have_unified_mapping)
for f in dict(sources.unified_source_mapping).keys():
self.assertIn(mozpath.join(reader.config.topobjdir,
'%s.%s' % (mozpath.splitext(f)[0],
reader.config.substs['OBJ_SUFFIX'])),
linkable.objs)
def test_unified_sources_non_unified(self):
"""Test that UNIFIED_SOURCES with FILES_PER_UNIFIED_FILE=1 works properly."""
reader = self.reader('unified-sources-non-unified')