--- a/config/config.mk
+++ b/config/config.mk
@@ -319,18 +319,18 @@ endif # CLANG_CL
# Use warnings-as-errors if ALLOW_COMPILER_WARNINGS is not set to 1 (which
# includes the case where it's undefined).
ifneq (1,$(ALLOW_COMPILER_WARNINGS))
CXXFLAGS += $(WARNINGS_AS_ERRORS)
CFLAGS += $(WARNINGS_AS_ERRORS)
endif # ALLOW_COMPILER_WARNINGS
-COMPILE_CFLAGS = $(COMPUTED_CFLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CFLAGS) $(_DEPEND_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) $(MK_COMPILE_DEFINES)
-COMPILE_CXXFLAGS = $(COMPUTED_CXXFLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) $(_DEPEND_CFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) $(MK_COMPILE_DEFINES)
+COMPILE_CFLAGS = $(COMPUTED_CFLAGS) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CFLAGS) $(_DEPEND_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) $(MK_COMPILE_DEFINES)
+COMPILE_CXXFLAGS = $(COMPUTED_CXXFLAGS) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) $(_DEPEND_CFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) $(MK_COMPILE_DEFINES)
COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS)
COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS)
ASFLAGS += $(MOZBUILD_ASFLAGS)
ifndef CROSS_COMPILE
HOST_CFLAGS += $(RTL_FLAGS)
endif
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -1215,17 +1215,18 @@ class RecursiveMakeBackend(CommonBackend
backend_file.write('LOCAL_INCLUDES += -I%s\n' % path)
def _process_per_source_flag(self, per_source_flag, backend_file):
for flag in per_source_flag.flags:
backend_file.write('%s_FLAGS += %s\n' % (mozpath.basename(per_source_flag.file_name), flag))
def _process_computed_flags(self, computed_flags, backend_file):
for var, flags in computed_flags.get_flags():
- backend_file.write('COMPUTED_%s += %s\n' % (var, make_quote(' '.join(flags))))
+ backend_file.write('COMPUTED_%s += %s\n' % (var,
+ ' '.join(make_quote(shell_quote(f)) for f in flags)))
def _process_java_jar_data(self, jar, backend_file):
target = jar.name
backend_file.write('JAVA_JAR_TARGETS += %s\n' % target)
backend_file.write('%s_DEST := %s.jar\n' % (target, jar.name))
if jar.sources:
backend_file.write('%s_JAVAFILES := %s\n' %
(target, ' '.join(jar.sources)))
--- a/python/mozbuild/mozbuild/compilation/database.py
+++ b/python/mozbuild/mozbuild/compilation/database.py
@@ -9,17 +9,16 @@ import types
from mozbuild.compilation import util
from mozbuild.backend.common import CommonBackend
from mozbuild.frontend.data import (
ComputedFlags,
Sources,
GeneratedSources,
DirectoryTraversal,
- Defines,
Linkable,
LocalInclude,
PerSourceFlag,
VariablePassthru,
SimpleProgram,
)
from mozbuild.shellutil import (
quote as shell_quote,
@@ -41,17 +40,16 @@ class CompileDBBackend(CommonBackend):
# The database we're going to dump out to.
self._db = OrderedDict()
# The cache for per-directory flags
self._flags = {}
self._envs = {}
self._includes = defaultdict(list)
- self._defines = defaultdict(list)
self._local_flags = defaultdict(dict)
self._per_source_flags = defaultdict(list)
self._extra_includes = defaultdict(list)
self._gyp_dirs = set()
self._dist_include_testing = '-I%s' % mozpath.join(
self.environment.topobjdir, 'dist', 'include', 'testing')
def consume_object(self, obj):
@@ -82,21 +80,16 @@ class CompileDBBackend(CommonBackend):
self._build_db_line(obj.objdir, obj.relativedir, obj.config, f,
obj.canonical_suffix)
elif isinstance(obj, LocalInclude):
self._includes[obj.objdir].append('-I%s' % mozpath.normpath(
obj.path.full_path))
elif isinstance(obj, Linkable):
- if isinstance(obj.defines, Defines): # As opposed to HostDefines
- for d in obj.defines.get_defines():
- if d not in self._defines[obj.objdir]:
- self._defines[obj.objdir].append(d)
- self._defines[obj.objdir].extend(obj.lib_defines.get_defines())
if isinstance(obj, SimpleProgram) and obj.is_unit_test:
if (self._dist_include_testing not in
self._extra_includes[obj.objdir]):
self._extra_includes[obj.objdir].append(
self._dist_include_testing)
elif isinstance(obj, VariablePassthru):
if obj.variables.get('IS_GYP_DIR'):
@@ -141,17 +134,16 @@ class CompileDBBackend(CommonBackend):
'MOZ_ZLIB_CFLAGS',
'MOZ_PIXMAN_CFLAGS',
):
f = env.substs.get(var)
if f:
local_extra.extend(f)
variables = {
'LOCAL_INCLUDES': self._includes[directory],
- 'DEFINES': self._defines[directory],
'EXTRA_INCLUDES': local_extra,
'DIST': mozpath.join(env.topobjdir, 'dist'),
'DEPTH': env.topobjdir,
'MOZILLA_DIR': env.topsrcdir,
'topsrcdir': env.topsrcdir,
'topobjdir': env.topobjdir,
}
variables.update(self._local_flags[directory])
@@ -234,17 +226,16 @@ class CompileDBBackend(CommonBackend):
return
if isinstance(value, types.StringTypes):
value = value.split()
db.extend(value)
db.append('$(COMPUTED_%s)' % self.CFLAGS[canonical_suffix])
db.extend((
- '$(DEFINES)',
'-I%s' % mozpath.join(cenv.topsrcdir, reldir),
'-I%s' % objdir,
'$(LOCAL_INCLUDES)',
'-I%s/dist/include' % cenv.topobjdir,
'$(EXTRA_INCLUDES)',
))
append_var('DSO_CFLAGS')
append_var('DSO_PIC_CFLAGS')
--- a/python/mozbuild/mozbuild/frontend/context.py
+++ b/python/mozbuild/mozbuild/frontend/context.py
@@ -298,33 +298,39 @@ class InitializedDefines(ContextDerivedV
class CompileFlags(ContextDerivedValue, dict):
def __init__(self, context):
self.flag_variables = (
('STL', context.config.substs.get('STL_FLAGS'), ('CXXFLAGS',)),
('VISIBILITY', context.config.substs.get('VISIBILITY_FLAGS'),
('CXXFLAGS', 'CFLAGS')),
+ ('DEFINES', None, ('CXXFLAGS', 'CFLAGS')),
+ ('LIBRARY_DEFINES', None, ('CXXFLAGS', 'CFLAGS')),
)
self._known_keys = set(k for k, v, _ in self.flag_variables)
# Providing defaults here doesn't play well with multiple templates
# modifying COMPILE_FLAGS from the same moz.build, because the merge
# done after the template runs can't tell which values coming from
# a template were set and which were provided as defaults.
template_name = getattr(context, 'template', None)
if template_name in (None, 'Gyp'):
- dict.__init__(self, ((k, TypedList(unicode)(v)) for k, v, _ in self.flag_variables))
+ dict.__init__(self, ((k, v if v is None else TypedList(unicode)(v))
+ for k, v, _ in self.flag_variables))
else:
dict.__init__(self)
def __setitem__(self, key, value):
if key not in self._known_keys:
raise ValueError('Invalid value. `%s` is not a compile flags '
'category.' % key)
+ if key in self and self[key] is None:
+ raise ValueError('`%s` may not be set in COMPILE_FLAGS from moz.build, this '
+ 'value is resolved from the emitter.' % key)
if not (isinstance(value, list) and all(isinstance(v, unicode) for v in value)):
raise ValueError('A list of strings must be provided as a value for a '
'compile flags category.')
dict.__setitem__(self, key, value)
class FinalTargetValue(ContextDerivedValue, unicode):
def __new__(cls, context, value=""):
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -164,16 +164,21 @@ class ComputedFlags(ContextDerived):
"""Aggregate flags for consumption by various backends.
"""
__slots__ = ('flags',)
def __init__(self, context, reader_flags):
ContextDerived.__init__(self, context)
self.flags = reader_flags
+ def resolve_flags(self, key, value):
+ # Bypass checks done by CompileFlags that would keep us from
+ # setting a value here.
+ dict.__setitem__(self.flags, key, value)
+
def get_flags(self):
flags = defaultdict(list)
for key, _, dest_vars in self.flags.flag_variables:
value = self.flags.get(key)
if value:
for dest_var in dest_vars:
flags[dest_var].extend(value)
return flags.items()
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -125,16 +125,17 @@ class TreeMetadataEmitter(LoggingMixin):
for k, v in mozinfo.info.items():
if isinstance(k, unicode):
k = k.encode('ascii')
self.info[k] = v
self._libs = OrderedDefaultDict(list)
self._binaries = OrderedDict()
self._compile_dirs = set()
+ self._compile_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).
@@ -259,16 +260,26 @@ class TreeMetadataEmitter(LoggingMixin):
lib.link_into == outerlib.basename):
propagate_defines(lib, defines)
for lib in (l for libs in self._libs.values() for l in libs):
if isinstance(lib, Library):
propagate_defines(lib, lib.lib_defines)
yield lib
+
+ 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)
+
+ for flags_obj in self._compile_flags.values():
+ yield flags_obj
+
for obj in self._binaries.values():
yield obj
LIBRARY_NAME_VAR = {
'host': 'HOST_LIBRARY_NAME',
'target': 'LIBRARY_NAME',
}
@@ -971,23 +982,35 @@ 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
- defines = context.get('DEFINES')
- if defines:
- yield Defines(context, defines)
+ computed_flags = ComputedFlags(context, context['COMPILE_FLAGS'])
- host_defines = context.get('HOST_DEFINES')
- if host_defines:
- yield HostDefines(context, host_defines)
+ for defines_var, cls in (('DEFINES', Defines),
+ ('HOST_DEFINES', HostDefines)):
+ defines = context.get(defines_var)
+ if defines:
+ defines_obj = cls(context, defines)
+ 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])
+
+ if isinstance(defines_obj, Defines):
+ defines_from_obj = list(defines_obj.get_defines())
+ if defines_from_obj:
+ computed_flags.resolve_flags('DEFINES',
+ 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),
@@ -1133,17 +1156,18 @@ class TreeMetadataEmitter(LoggingMixin):
android_extra_packages = context.get('ANDROID_EXTRA_PACKAGES')
if android_extra_packages:
yield AndroidExtraPackages(context, android_extra_packages)
if passthru.variables:
yield passthru
if context.objdir in self._compile_dirs:
- yield ComputedFlags(context, context['COMPILE_FLAGS'])
+ self._compile_flags[context.objdir] = computed_flags
+
def _create_substitution(self, cls, context, path):
sub = cls(context)
sub.input_path = '%s.in' % path.full_path
sub.output_path = path.translated
sub.relpath = path
return sub
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/compile-defines/moz.build
@@ -0,0 +1,14 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+@template
+def Library(name):
+ '''Template for libraries.'''
+ LIBRARY_NAME = name
+
+Library('dummy')
+
+UNIFIED_SOURCES += ['test1.c']
+
+DEFINES['MOZ_TEST_DEFINE'] = True
+LIBRARY_DEFINES['MOZ_LIBRARY_DEFINE'] = 'MOZ_TEST'
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/resolved-flags-error/moz.build
@@ -0,0 +1,15 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+@template
+def Library(name):
+ '''Template for libraries.'''
+ LIBRARY_NAME = name
+
+Library('dummy')
+
+UNIFIED_SOURCES += ['test1.c']
+
+DEFINES['MOZ_TEST_DEFINE'] = True
+LIBRARY_DEFINES['MOZ_LIBRARY_DEFINE'] = 'MOZ_TEST'
+COMPILE_FLAGS['DEFINES'] = ['-DFOO']
\ No newline at end of file
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -202,17 +202,17 @@ class TestEmitterBasic(unittest.TestCase
variables = objs[0].variables
maxDiff = self.maxDiff
self.maxDiff = None
self.assertEqual(wanted, variables)
self.maxDiff = maxDiff
def test_compile_flags(self):
reader = self.reader('compile-flags')
- sources, flags, lib = self.read_topsrcdir(reader)
+ sources, lib, flags = self.read_topsrcdir(reader)
self.assertIsInstance(flags, ComputedFlags)
self.assertEqual(flags.flags['STL'], reader.config.substs['STL_FLAGS'])
self.assertEqual(flags.flags['VISIBILITY'], reader.config.substs['VISIBILITY_FLAGS'])
def test_compile_flags_validation(self):
reader = self.reader('compile-flags-field-validation')
with self.assertRaisesRegexp(BuildReaderError, 'Invalid value.'):
@@ -220,33 +220,48 @@ class TestEmitterBasic(unittest.TestCase
reader = self.reader('compile-flags-type-validation')
with self.assertRaisesRegexp(BuildReaderError,
'A list of strings must be provided'):
self.read_topsrcdir(reader)
def test_compile_flags_templates(self):
reader = self.reader('compile-flags-templates')
- sources, flags, lib = self.read_topsrcdir(reader)
+ sources, lib, flags = self.read_topsrcdir(reader)
self.assertIsInstance(flags, ComputedFlags)
self.assertEqual(flags.flags['STL'], [])
self.assertEqual(flags.flags['VISIBILITY'], [])
def test_disable_stl_wrapping(self):
reader = self.reader('disable-stl-wrapping')
- sources, flags, lib = self.read_topsrcdir(reader)
+ sources, lib, flags = self.read_topsrcdir(reader)
self.assertIsInstance(flags, ComputedFlags)
self.assertEqual(flags.flags['STL'], [])
def test_visibility_flags(self):
reader = self.reader('visibility-flags')
- sources, flags, lib = self.read_topsrcdir(reader)
+ sources, lib, flags = self.read_topsrcdir(reader)
self.assertIsInstance(flags, ComputedFlags)
self.assertEqual(flags.flags['VISIBILITY'], [])
+ def test_defines_in_flags(self):
+ reader = self.reader('compile-defines')
+ defines, sources, lib, flags = self.read_topsrcdir(reader)
+ self.assertIsInstance(flags, ComputedFlags)
+ self.assertEqual(flags.flags['LIBRARY_DEFINES'],
+ ['-DMOZ_LIBRARY_DEFINE=MOZ_TEST'])
+ self.assertEqual(flags.flags['DEFINES'],
+ ['-DMOZ_TEST_DEFINE'])
+
+ def test_resolved_flags_error(self):
+ reader = self.reader('resolved-flags-error')
+ with self.assertRaisesRegexp(BuildReaderError,
+ "`DEFINES` may not be set in COMPILE_FLAGS from moz.build"):
+ self.read_topsrcdir(reader)
+
def test_use_yasm(self):
# When yasm is not available, this should raise.
reader = self.reader('use-yasm')
with self.assertRaisesRegexp(SandboxValidationError,
'yasm is not available'):
self.read_topsrcdir(reader)
# When yasm is available, this should work.
@@ -832,37 +847,42 @@ class TestEmitterBasic(unittest.TestCase
self.read_topsrcdir(reader)
def test_library_defines(self):
"""Test that LIBRARY_DEFINES is propagated properly."""
reader = self.reader('library-defines')
objs = self.read_topsrcdir(reader)
libraries = [o for o in objs if isinstance(o,StaticLibrary)]
+ library_flags = [o for o in objs if isinstance(o, ComputedFlags)]
expected = {
'liba': '-DIN_LIBA',
'libb': '-DIN_LIBA -DIN_LIBB',
'libc': '-DIN_LIBA -DIN_LIBB',
'libd': ''
}
defines = {}
for lib in libraries:
defines[lib.basename] = ' '.join(lib.lib_defines.get_defines())
self.assertEqual(expected, defines)
+ defines_in_flags = {}
+ for flags in library_flags:
+ 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)
- # The last object is a Linkable.
+ computed_flags = objs.pop()
+ self.assertIsInstance(computed_flags, ComputedFlags)
+ # The second to last object is a Linkable.
linkable = objs.pop()
self.assertTrue(linkable.cxx_link)
- computed_flags = objs.pop()
- self.assertIsInstance(computed_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)
expected = {
@@ -879,17 +899,19 @@ 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)
- # The last object is a Linkable.
+ flags = objs.pop()
+ self.assertIsInstance(flags, ComputedFlags)
+ # The second 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):
@@ -902,20 +924,22 @@ 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)
- # The last object is a Linkable.
+ flags = objs.pop()
+ self.assertIsInstance(flags, ComputedFlags)
+ # The second to last object is a Linkable.
linkable = objs.pop()
self.assertTrue(linkable.cxx_link)
- 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 = {
@@ -932,21 +956,21 @@ class TestEmitterBasic(unittest.TestCase
sources.files,
[mozpath.join(reader.config.topobjdir, f) for f in files])
def test_host_sources(self):
"""Test that HOST_SOURCES works properly."""
reader = self.reader('host-sources')
objs = self.read_topsrcdir(reader)
- # The last object is a Linkable
+ flags = objs.pop()
+ self.assertIsInstance(flags, ComputedFlags)
+ # The second to last object is a Linkable
linkable = objs.pop()
self.assertTrue(linkable.cxx_link)
- computed_flags = objs.pop()
- self.assertIsInstance(computed_flags, ComputedFlags)
self.assertEqual(len(objs), 3)
for o in objs:
self.assertIsInstance(o, HostSources)
suffix_map = {obj.canonical_suffix: obj for obj in objs}
self.assertEqual(len(suffix_map), 3)
expected = {
@@ -1215,38 +1239,38 @@ class TestEmitterBasic(unittest.TestCase
self.assertEquals([p.full_path for p in objs[0].paths], expected)
def test_install_shared_lib(self):
"""Test that we can install a shared library with TEST_HARNESS_FILES"""
reader = self.reader('test-install-shared-lib')
objs = self.read_topsrcdir(reader)
self.assertIsInstance(objs[0], TestHarnessFiles)
self.assertIsInstance(objs[1], VariablePassthru)
- self.assertIsInstance(objs[2], ComputedFlags)
- self.assertIsInstance(objs[3], SharedLibrary)
+ self.assertIsInstance(objs[2], SharedLibrary)
+ self.assertIsInstance(objs[3], ComputedFlags)
for path, files in objs[0].files.walk():
for f in files:
self.assertEqual(str(f), '!libfoo.so')
self.assertEqual(path, 'foo/bar')
def test_symbols_file(self):
"""Test that SYMBOLS_FILE works"""
reader = self.reader('test-symbols-file')
- genfile, flags, shlib = self.read_topsrcdir(reader)
+ genfile, shlib, flags = self.read_topsrcdir(reader)
self.assertIsInstance(genfile, GeneratedFile)
self.assertIsInstance(flags, ComputedFlags)
self.assertIsInstance(shlib, SharedLibrary)
# This looks weird but MockConfig sets DLL_{PREFIX,SUFFIX} and
# the reader method in this class sets OS_TARGET=WINNT.
self.assertEqual(shlib.symbols_file, 'libfoo.so.def')
def test_symbols_file_objdir(self):
"""Test that a SYMBOLS_FILE in the objdir works"""
reader = self.reader('test-symbols-file-objdir')
- genfile, flags, shlib = self.read_topsrcdir(reader)
+ genfile, shlib, flags = self.read_topsrcdir(reader)
self.assertIsInstance(genfile, GeneratedFile)
self.assertEqual(genfile.script,
mozpath.join(reader.config.topsrcdir, 'foo.py'))
self.assertIsInstance(flags, ComputedFlags)
self.assertIsInstance(shlib, SharedLibrary)
self.assertEqual(shlib.symbols_file, 'foo.symbols')
def test_symbols_file_objdir_missing_generated(self):