зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1405811 - Move host compilation flags to mozbuild. r=mshal
MozReview-Commit-ID: 7I5IHM65eaU --HG-- extra : rebase_source : b33bb2f0f6a9cb36961586ad475cf36f8bbcd091
This commit is contained in:
Родитель
1f6173e37c
Коммит
92ca8066af
|
@ -255,30 +255,14 @@ ifdef MOZ_OPTIMIZE
|
|||
LDFLAGS += $(MOZ_OPTIMIZE_LDFLAGS)
|
||||
endif # MOZ_OPTIMIZE
|
||||
|
||||
HOST_CFLAGS += $(_DEPEND_CFLAGS)
|
||||
HOST_CXXFLAGS += $(_DEPEND_CFLAGS)
|
||||
ifdef CROSS_COMPILE
|
||||
HOST_CFLAGS += $(HOST_OPTIMIZE_FLAGS)
|
||||
HOST_CXXFLAGS += $(HOST_OPTIMIZE_FLAGS)
|
||||
else
|
||||
ifdef MOZ_OPTIMIZE
|
||||
HOST_CFLAGS += $(MOZ_OPTIMIZE_FLAGS)
|
||||
HOST_CXXFLAGS += $(MOZ_OPTIMIZE_FLAGS)
|
||||
endif # MOZ_OPTIMIZE
|
||||
endif # CROSS_COMPILE
|
||||
|
||||
COMPILE_CFLAGS = $(COMPUTED_CFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(MK_COMPILE_DEFINES)
|
||||
COMPILE_CXXFLAGS = $(COMPUTED_CXXFLAGS) $(PGO_CFLAGS) $(_DEPEND_CFLAGS) $(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
|
||||
|
||||
HOST_CFLAGS += $(HOST_DEFINES) $(MOZBUILD_HOST_CFLAGS)
|
||||
HOST_CXXFLAGS += $(HOST_DEFINES) $(MOZBUILD_HOST_CXXFLAGS)
|
||||
HOST_CFLAGS = $(COMPUTED_HOST_CFLAGS) $(_DEPEND_CFLAGS)
|
||||
HOST_CXXFLAGS = $(COMPUTED_HOST_CXXFLAGS) $(_DEPEND_CFLAGS)
|
||||
|
||||
# We only add color flags if neither the flag to disable color
|
||||
# (e.g. "-fno-color-diagnostics" nor a flag to control color
|
||||
|
|
|
@ -300,7 +300,51 @@ class InitializedDefines(ContextDerivedValue, OrderedDict):
|
|||
self.update(value)
|
||||
|
||||
|
||||
class CompileFlags(ContextDerivedValue, dict):
|
||||
class BaseCompileFlags(ContextDerivedValue, dict):
|
||||
def __init__(self, context):
|
||||
self._context = context
|
||||
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, v if v is None else TypedList(unicode)(v))
|
||||
for k, v, _ in self.flag_variables))
|
||||
else:
|
||||
dict.__init__(self)
|
||||
|
||||
|
||||
class HostCompileFlags(BaseCompileFlags):
|
||||
def __init__(self, context):
|
||||
self._context = context
|
||||
|
||||
self.flag_variables = (
|
||||
('HOST_CXXFLAGS', context.config.substs.get('HOST_CXXFLAGS'),
|
||||
('HOST_CXXFLAGS',)),
|
||||
('HOST_CFLAGS', context.config.substs.get('HOST_CFLAGS'),
|
||||
('HOST_CFLAGS',)),
|
||||
('HOST_OPTIMIZE', self._optimize_flags(),
|
||||
('HOST_CFLAGS', 'HOST_CXXFLAGS')),
|
||||
('RTL', None, ('HOST_CFLAGS',)),
|
||||
('HOST_DEFINES', None, ('HOST_CFLAGS', 'HOST_CXXFLAGS')),
|
||||
('MOZBUILD_HOST_CFLAGS', [], ('HOST_CFLAGS',)),
|
||||
('MOZBUILD_HOST_CXXFLAGS', [], ('HOST_CXXFLAGS',)),
|
||||
)
|
||||
BaseCompileFlags.__init__(self, context)
|
||||
|
||||
def _optimize_flags(self):
|
||||
optimize_flags = []
|
||||
if self._context.config.substs.get('CROSS_COMPILE'):
|
||||
optimize_flags += self._context.config.substs.get('HOST_OPTIMIZE_FLAGS')
|
||||
elif self._context.config.substs.get('MOZ_OPTIMIZE'):
|
||||
optimize_flags += self._context.config.substs.get('MOZ_OPTIMIZE_FLAGS')
|
||||
return optimize_flags
|
||||
|
||||
|
||||
class CompileFlags(BaseCompileFlags):
|
||||
def __init__(self, context):
|
||||
main_src_dir = mozpath.dirname(context.main_path)
|
||||
self._context = context
|
||||
|
@ -348,18 +392,8 @@ class CompileFlags(ContextDerivedValue, dict):
|
|||
('MOZBUILD_CFLAGS', None, ('CFLAGS',)),
|
||||
('MOZBUILD_CXXFLAGS', None, ('CXXFLAGS',)),
|
||||
)
|
||||
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, v if v is None else TypedList(unicode)(v))
|
||||
for k, v, _ in self.flag_variables))
|
||||
else:
|
||||
dict.__init__(self)
|
||||
BaseCompileFlags.__init__(self, context)
|
||||
|
||||
def _debug_flags(self):
|
||||
if (self._context.config.substs.get('MOZ_DEBUG') or
|
||||
|
@ -1890,6 +1924,11 @@ VARIABLES = {
|
|||
appear in the moz.build file.
|
||||
"""),
|
||||
|
||||
'HOST_COMPILE_FLAGS': (HostCompileFlags, dict,
|
||||
"""Recipe for host compile flags for this context. Not to be manipulated
|
||||
directly.
|
||||
"""),
|
||||
|
||||
'HOST_DEFINES': (InitializedDefines, dict,
|
||||
"""Dictionary of compiler defines to declare for host compilation.
|
||||
See ``DEFINES`` for specifics.
|
||||
|
|
|
@ -131,6 +131,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
self._libs = OrderedDefaultDict(list)
|
||||
self._binaries = OrderedDict()
|
||||
self._compile_dirs = set()
|
||||
self._host_compile_dirs = set()
|
||||
self._compile_flags = dict()
|
||||
self._linkage = []
|
||||
self._static_linking_shared = set()
|
||||
|
@ -774,8 +775,14 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
# Avoid emitting compile flags for directories only containing rust
|
||||
# libraries. Emitted compile flags are only relevant to C/C++ sources
|
||||
# for the time being.
|
||||
if not all(isinstance(l, (RustLibrary, HostRustLibrary))
|
||||
for l in linkables + host_linkables):
|
||||
if not all(isinstance(l, (RustLibrary)) for l in linkables):
|
||||
self._compile_dirs.add(context.objdir)
|
||||
if host_linkables and not all(isinstance(l, HostRustLibrary) for l in host_linkables):
|
||||
self._host_compile_dirs.add(context.objdir)
|
||||
# TODO: objdirs with only host things in them shouldn't need target
|
||||
# flags, but there's at least one Makefile.in (in
|
||||
# build/unix/elfhack) that relies on the value of LDFLAGS being
|
||||
# passed to one-off rules.
|
||||
self._compile_dirs.add(context.objdir)
|
||||
|
||||
sources = defaultdict(list)
|
||||
|
@ -918,6 +925,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
yield obj
|
||||
|
||||
computed_flags = ComputedFlags(context, context['COMPILE_FLAGS'])
|
||||
computed_host_flags = ComputedFlags(context, context['HOST_COMPILE_FLAGS'])
|
||||
|
||||
# Proxy some variables as-is until we have richer classes to represent
|
||||
# them. We should aim to keep this set small because it violates the
|
||||
|
@ -948,8 +956,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
for dll in context['DELAYLOAD_DLLS']])
|
||||
context['OS_LIBS'].append('delayimp')
|
||||
|
||||
for v in ['CMFLAGS', 'CMMFLAGS', 'ASFLAGS', 'LDFLAGS',
|
||||
'HOST_CFLAGS', 'HOST_CXXFLAGS']:
|
||||
for v in ['CMFLAGS', 'CMMFLAGS', 'ASFLAGS', 'LDFLAGS']:
|
||||
if v in context and context[v]:
|
||||
passthru.variables['MOZBUILD_' + v] = context[v]
|
||||
|
||||
|
@ -957,6 +964,10 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
if v in context and context[v]:
|
||||
computed_flags.resolve_flags('MOZBUILD_%s' % v, context[v])
|
||||
|
||||
for v in ['HOST_CXXFLAGS', 'HOST_CFLAGS']:
|
||||
if v in context and context[v]:
|
||||
computed_host_flags.resolve_flags('MOZBUILD_%s' % v, context[v])
|
||||
|
||||
dist_install = context['DIST_INSTALL']
|
||||
if dist_install is True:
|
||||
passthru.variables['DIST_INSTALL'] = True
|
||||
|
@ -975,9 +986,9 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
if (context.config.substs.get('MOZ_DEBUG') and
|
||||
not context.config.substs.get('MOZ_NO_DEBUG_RTL')):
|
||||
rtl_flag += 'd'
|
||||
# Use a list, like MOZBUILD_*FLAGS variables
|
||||
passthru.variables['RTL_FLAGS'] = [rtl_flag]
|
||||
computed_flags.resolve_flags('RTL', [rtl_flag])
|
||||
if not context.config.substs.get('CROSS_COMPILE'):
|
||||
computed_host_flags.resolve_flags('RTL', [rtl_flag])
|
||||
|
||||
generated_files = set()
|
||||
for obj in self._process_generated_files(context):
|
||||
|
@ -991,23 +1002,23 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
generated_files.add(str(sub.relpath))
|
||||
yield sub
|
||||
|
||||
for defines_var, cls in (('DEFINES', Defines),
|
||||
('HOST_DEFINES', HostDefines)):
|
||||
for defines_var, cls, backend_flags in (('DEFINES', Defines, computed_flags),
|
||||
('HOST_DEFINES', HostDefines, computed_host_flags)):
|
||||
defines = context.get(defines_var)
|
||||
if defines:
|
||||
defines_obj = cls(context, defines)
|
||||
yield defines_obj
|
||||
if isinstance(defines_obj, Defines):
|
||||
# DEFINES have consumers outside the compile command line,
|
||||
# HOST_DEFINES do not.
|
||||
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)
|
||||
|
||||
defines_from_obj = list(defines_obj.get_defines())
|
||||
if defines_from_obj:
|
||||
backend_flags.resolve_flags(defines_var, defines_from_obj)
|
||||
|
||||
simple_lists = [
|
||||
('GENERATED_EVENTS_WEBIDL_FILES', GeneratedEventWebIDLFile),
|
||||
|
@ -1178,6 +1189,8 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
|
||||
if context.objdir in self._compile_dirs:
|
||||
self._compile_flags[context.objdir] = computed_flags
|
||||
if context.objdir in self._host_compile_dirs:
|
||||
yield computed_host_flags
|
||||
|
||||
|
||||
def _create_substitution(self, cls, context, path):
|
||||
|
|
|
@ -10,6 +10,4 @@ RCINCLUDE = 'bar.rc'
|
|||
DEFFILE = 'baz.def'
|
||||
|
||||
LDFLAGS += ['-ld flag with spaces', '-x']
|
||||
HOST_CFLAGS += ['-funroll-loops', '-wall']
|
||||
HOST_CXXFLAGS += ['-funroll-loops-harder', '-wall-day-everyday']
|
||||
WIN32_EXE_LDFLAGS += ['-subsystem:console']
|
||||
|
|
|
@ -334,14 +334,6 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
'MOZBUILD_LDFLAGS += -DELAYLOAD:foo.dll',
|
||||
'MOZBUILD_LDFLAGS += -DELAYLOAD:bar.dll',
|
||||
],
|
||||
'MOZBUILD_HOST_CFLAGS': [
|
||||
'MOZBUILD_HOST_CFLAGS += -funroll-loops',
|
||||
'MOZBUILD_HOST_CFLAGS += -wall',
|
||||
],
|
||||
'MOZBUILD_HOST_CXXFLAGS': [
|
||||
'MOZBUILD_HOST_CXXFLAGS += -funroll-loops-harder',
|
||||
'MOZBUILD_HOST_CXXFLAGS += -wall-day-everyday',
|
||||
],
|
||||
'WIN32_EXE_LDFLAGS': [
|
||||
'WIN32_EXE_LDFLAGS += -subsystem:console',
|
||||
],
|
||||
|
@ -692,19 +684,6 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
expected = ['DEFINES += -DFOO \'-DBAZ="ab\'\\\'\'cd"\' -UQUX -DBAR=7 -DVALUE=xyz']
|
||||
self.assertEqual(defines, expected)
|
||||
|
||||
def test_host_defines(self):
|
||||
"""Test that HOST_DEFINES are written to backend.mk correctly."""
|
||||
env = self._consume('host-defines', RecursiveMakeBackend)
|
||||
|
||||
backend_path = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
|
||||
|
||||
var = 'HOST_DEFINES'
|
||||
defines = [val for val in lines if val.startswith(var)]
|
||||
|
||||
expected = ['HOST_DEFINES += -DFOO \'-DBAZ="ab\'\\\'\'cd"\' -UQUX -DBAR=7 -DVALUE=xyz']
|
||||
self.assertEqual(defines, expected)
|
||||
|
||||
def test_local_includes(self):
|
||||
"""Test that LOCAL_INCLUDES are written to backend.mk correctly."""
|
||||
env = self._consume('local_includes', RecursiveMakeBackend)
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
@template
|
||||
def HostLibrary(name):
|
||||
'''Template for libraries.'''
|
||||
HOST_LIBRARY_NAME = name
|
||||
|
||||
HostLibrary('dummy')
|
||||
|
||||
HOST_SOURCES += ['test1.c']
|
||||
|
||||
value = 'xyz'
|
||||
HOST_DEFINES = {
|
||||
'FOO': True,
|
||||
|
@ -12,3 +21,5 @@ HOST_DEFINES.update({
|
|||
'VALUE': value,
|
||||
'QUX': False,
|
||||
})
|
||||
|
||||
HOST_CFLAGS += ['-funroll-loops', '-host-arg']
|
|
@ -12,6 +12,4 @@ RCINCLUDE = 'bar.rc'
|
|||
DEFFILE = 'baz.def'
|
||||
|
||||
LDFLAGS += ['-framework Foo', '-x']
|
||||
HOST_CFLAGS += ['-funroll-loops', '-wall']
|
||||
HOST_CXXFLAGS += ['-funroll-loops-harder', '-wall-day-everyday']
|
||||
WIN32_EXE_LDFLAGS += ['-subsystem:console']
|
||||
|
|
|
@ -190,9 +190,6 @@ class TestEmitterBasic(unittest.TestCase):
|
|||
'DEFFILE': 'baz.def',
|
||||
'MOZBUILD_LDFLAGS': ['-framework Foo', '-x', '-DELAYLOAD:foo.dll',
|
||||
'-DELAYLOAD:bar.dll'],
|
||||
'MOZBUILD_HOST_CFLAGS': ['-funroll-loops', '-wall'],
|
||||
'MOZBUILD_HOST_CXXFLAGS': ['-funroll-loops-harder',
|
||||
'-wall-day-everyday'],
|
||||
'WIN32_EXE_LDFLAGS': ['-subsystem:console'],
|
||||
}
|
||||
|
||||
|
@ -232,6 +229,58 @@ class TestEmitterBasic(unittest.TestCase):
|
|||
self.assertIsInstance(flags, ComputedFlags)
|
||||
self.assertEqual(flags.flags['DEBUG'], [])
|
||||
|
||||
def test_host_compile_flags(self):
|
||||
reader = self.reader('host-compile-flags', extra_substs={
|
||||
'HOST_CXXFLAGS': ['-Wall', '-Werror'],
|
||||
'HOST_CFLAGS': ['-Werror', '-Wall'],
|
||||
})
|
||||
sources, flags, lib, target_flags = self.read_topsrcdir(reader)
|
||||
self.assertIsInstance(flags, ComputedFlags)
|
||||
self.assertEqual(flags.flags['HOST_CXXFLAGS'], reader.config.substs['HOST_CXXFLAGS'])
|
||||
self.assertEqual(flags.flags['HOST_CFLAGS'], reader.config.substs['HOST_CFLAGS'])
|
||||
self.assertEqual(set(flags.flags['HOST_DEFINES']),
|
||||
set(['-DFOO', '-DBAZ="abcd"', '-UQUX', '-DBAR=7', '-DVALUE=xyz']))
|
||||
self.assertEqual(flags.flags['MOZBUILD_HOST_CFLAGS'], ['-funroll-loops', '-host-arg'])
|
||||
self.assertEqual(flags.flags['MOZBUILD_HOST_CXXFLAGS'], [])
|
||||
|
||||
def test_host_no_optimize_flags(self):
|
||||
reader = self.reader('host-compile-flags', extra_substs={
|
||||
'MOZ_OPTIMIZE': '',
|
||||
'MOZ_OPTIMIZE_FLAGS': ['-O2'],
|
||||
})
|
||||
sources, flags, lib, target_flags = self.read_topsrcdir(reader)
|
||||
self.assertIsInstance(flags, ComputedFlags)
|
||||
self.assertEqual(flags.flags['HOST_OPTIMIZE'], [])
|
||||
|
||||
def test_host_optimize_flags(self):
|
||||
reader = self.reader('host-compile-flags', extra_substs={
|
||||
'MOZ_OPTIMIZE': '1',
|
||||
'MOZ_OPTIMIZE_FLAGS': ['-O2'],
|
||||
})
|
||||
sources, flags, lib, target_flags = self.read_topsrcdir(reader)
|
||||
self.assertIsInstance(flags, ComputedFlags)
|
||||
self.assertEqual(flags.flags['HOST_OPTIMIZE'], ['-O2'])
|
||||
|
||||
def test_cross_optimize_flags(self):
|
||||
reader = self.reader('host-compile-flags', extra_substs={
|
||||
'MOZ_OPTIMIZE': '1',
|
||||
'MOZ_OPTIMIZE_FLAGS': ['-O2'],
|
||||
'HOST_OPTIMIZE_FLAGS': ['-O3'],
|
||||
'CROSS_COMPILE': '1',
|
||||
})
|
||||
sources, flags, lib, target_flags = self.read_topsrcdir(reader)
|
||||
self.assertIsInstance(flags, ComputedFlags)
|
||||
self.assertEqual(flags.flags['HOST_OPTIMIZE'], ['-O3'])
|
||||
|
||||
def test_host_rtl_flag(self):
|
||||
reader = self.reader('host-compile-flags', extra_substs={
|
||||
'OS_ARCH': 'WINNT',
|
||||
'MOZ_DEBUG': '1',
|
||||
})
|
||||
sources, flags, lib, target_flags = self.read_topsrcdir(reader)
|
||||
self.assertIsInstance(flags, ComputedFlags)
|
||||
self.assertEqual(flags.flags['RTL'], ['-MDd'])
|
||||
|
||||
def test_compile_flags_validation(self):
|
||||
reader = self.reader('compile-flags-field-validation')
|
||||
|
||||
|
@ -853,25 +902,6 @@ class TestEmitterBasic(unittest.TestCase):
|
|||
|
||||
self.assertEqual(defines, expected)
|
||||
|
||||
def test_host_defines(self):
|
||||
reader = self.reader('host-defines')
|
||||
objs = self.read_topsrcdir(reader)
|
||||
|
||||
defines = {}
|
||||
for o in objs:
|
||||
if isinstance(o, HostDefines):
|
||||
defines = o.defines
|
||||
|
||||
expected = {
|
||||
'BAR': 7,
|
||||
'BAZ': '"abcd"',
|
||||
'FOO': True,
|
||||
'VALUE': 'xyz',
|
||||
'QUX': False,
|
||||
}
|
||||
|
||||
self.assertEqual(defines, expected)
|
||||
|
||||
def test_jar_manifests(self):
|
||||
reader = self.reader('jar-manifests')
|
||||
objs = self.read_topsrcdir(reader)
|
||||
|
@ -1015,11 +1045,15 @@ class TestEmitterBasic(unittest.TestCase):
|
|||
reader = self.reader('host-sources')
|
||||
objs = self.read_topsrcdir(reader)
|
||||
|
||||
# This objdir will generate target flags.
|
||||
flags = objs.pop()
|
||||
self.assertIsInstance(flags, ComputedFlags)
|
||||
# The second to last object is a Linkable
|
||||
linkable = objs.pop()
|
||||
self.assertTrue(linkable.cxx_link)
|
||||
# This objdir will also generate host flags.
|
||||
flags = objs.pop()
|
||||
self.assertIsInstance(flags, ComputedFlags)
|
||||
self.assertEqual(len(objs), 3)
|
||||
for o in objs:
|
||||
self.assertIsInstance(o, HostSources)
|
||||
|
|
Загрузка…
Ссылка в новой задаче