204 lines
5.3 KiB
Python
204 lines
5.3 KiB
Python
from waflib import Logs, Options, Utils
|
|
|
|
|
|
class CompilerTraits(object):
|
|
def get_warnings_flags(self, level):
|
|
"""get_warnings_flags(level) -> list of cflags"""
|
|
raise NotImplementedError
|
|
|
|
def get_optimization_flags(self, level):
|
|
"""get_optimization_flags(level) -> list of cflags"""
|
|
raise NotImplementedError
|
|
|
|
def get_debug_flags(self, level):
|
|
"""get_debug_flags(level) -> (list of cflags, list of cppdefines)"""
|
|
raise NotImplementedError
|
|
|
|
|
|
class GccTraits(CompilerTraits):
|
|
def __init__(self):
|
|
super(GccTraits, self).__init__()
|
|
# cumulative list of warnings per level
|
|
self.warnings_flags = [['-Wall'], ['-Werror'], ['-Wextra']]
|
|
|
|
def get_warnings_flags(self, level):
|
|
warnings = []
|
|
for l in range(level):
|
|
if l < len(self.warnings_flags):
|
|
warnings.extend(self.warnings_flags[l])
|
|
else:
|
|
break
|
|
return warnings
|
|
|
|
def get_optimization_flags(self, level):
|
|
if level == 0:
|
|
return ['-O0']
|
|
elif level == 1:
|
|
return ['-O']
|
|
elif level == 2:
|
|
return ['-O2']
|
|
elif level == 3:
|
|
return ['-O3']
|
|
|
|
def get_debug_flags(self, level):
|
|
if level == 0:
|
|
return (['-g0'], ['NDEBUG'])
|
|
elif level == 1:
|
|
return (['-g'], [])
|
|
elif level >= 2:
|
|
return (['-ggdb', '-g3'], ['_DEBUG'])
|
|
|
|
|
|
class IccTraits(CompilerTraits):
|
|
def __init__(self):
|
|
super(IccTraits, self).__init__()
|
|
# cumulative list of warnings per level
|
|
# icc is _very_ verbose with -Wall, -Werror is barely achievable
|
|
self.warnings_flags = [[], [], ['-Wall']]
|
|
|
|
def get_warnings_flags(self, level):
|
|
warnings = []
|
|
for l in range(level):
|
|
if l < len(self.warnings_flags):
|
|
warnings.extend(self.warnings_flags[l])
|
|
else:
|
|
break
|
|
return warnings
|
|
|
|
def get_optimization_flags(self, level):
|
|
if level == 0:
|
|
return ['-O0']
|
|
elif level == 1:
|
|
return ['-O']
|
|
elif level == 2:
|
|
return ['-O2']
|
|
elif level == 3:
|
|
return ['-O3']
|
|
|
|
def get_debug_flags(self, level):
|
|
if level == 0:
|
|
return (['-g0'], ['NDEBUG'])
|
|
elif level == 1:
|
|
return (['-g'], [])
|
|
elif level >= 2:
|
|
return (['-ggdb', '-g3'], ['_DEBUG'])
|
|
|
|
|
|
|
|
class MsvcTraits(CompilerTraits):
|
|
def __init__(self):
|
|
super(MsvcTraits, self).__init__()
|
|
# cumulative list of warnings per level
|
|
self.warnings_flags = [['/W2'], ['/WX'], ['/Wall']]
|
|
|
|
def get_warnings_flags(self, level):
|
|
warnings = []
|
|
for l in range(level):
|
|
if l < len(self.warnings_flags):
|
|
warnings.extend(self.warnings_flags[l])
|
|
else:
|
|
break
|
|
return warnings
|
|
|
|
def get_optimization_flags(self, level):
|
|
if level == 0:
|
|
return ['/Od']
|
|
elif level == 1:
|
|
return []
|
|
elif level == 2:
|
|
return ['/O2']
|
|
elif level == 3:
|
|
return ['/Ox']
|
|
|
|
def get_debug_flags(self, level):
|
|
if level == 0:
|
|
return ([], ['NDEBUG'])
|
|
elif level == 1:
|
|
return (['/ZI', '/RTC1'], [])
|
|
elif level >= 2:
|
|
return (['/ZI', '/RTC1'], ['_DEBUG'])
|
|
|
|
|
|
|
|
gcc = GccTraits()
|
|
icc = IccTraits()
|
|
msvc = MsvcTraits()
|
|
|
|
# how to map env['COMPILER_CC'] or env['COMPILER_CXX'] into a traits object
|
|
compiler_mapping = {
|
|
'gcc': gcc,
|
|
'g++': gcc,
|
|
'msvc': msvc,
|
|
'icc': icc,
|
|
'icpc': icc,
|
|
'clang': gcc,
|
|
'clang++': gcc,
|
|
}
|
|
|
|
profiles = {
|
|
# profile name: [optimization_level, warnings_level, debug_level]
|
|
'default': [2, 1, 1],
|
|
'debug': [0, 2, 3],
|
|
'release': [3, 1, 0],
|
|
}
|
|
|
|
default_profile = 'default'
|
|
|
|
def options(opt):
|
|
assert default_profile in profiles
|
|
opt.add_option('-d', '--build-profile',
|
|
action='store',
|
|
default=default_profile,
|
|
help=("Specify the build profile. "
|
|
"Build profiles control the default compilation flags"
|
|
" used for C/C++ programs, if CCFLAGS/CXXFLAGS are not"
|
|
" set in the environment. [Allowed Values: %s]"
|
|
% ", ".join([repr(p) for p in list(profiles.keys())])),
|
|
choices=list(profiles.keys()),
|
|
dest='build_profile')
|
|
opt.add_option('--check-profile',
|
|
help=('print out current build profile'),
|
|
default=False, dest='check_profile', action="store_true")
|
|
opt.add_option('--disable-werror',
|
|
help=('disable -Werror flag (warnings treated as errors, e.g., deprecated functions)'),
|
|
default=False, dest='disable_werror', action="store_true")
|
|
def configure(conf):
|
|
cc = conf.env['COMPILER_CC'] or None
|
|
cxx = conf.env['COMPILER_CXX'] or None
|
|
if not (cc or cxx):
|
|
raise Utils.WafError("neither COMPILER_CC nor COMPILER_CXX are defined; "
|
|
"maybe the compiler_cc or compiler_cxx tool has not been configured yet?")
|
|
|
|
try:
|
|
compiler = compiler_mapping[cc]
|
|
except KeyError:
|
|
try:
|
|
compiler = compiler_mapping[cxx]
|
|
except KeyError:
|
|
Logs.warn("No compiler flags support for compiler %r or %r"
|
|
% (cc, cxx))
|
|
return
|
|
|
|
opt_level, warn_level, dbg_level = profiles[Options.options.build_profile]
|
|
|
|
optimizations = compiler.get_optimization_flags(opt_level)
|
|
debug, debug_defs = compiler.get_debug_flags(dbg_level)
|
|
warnings = compiler.get_warnings_flags(warn_level)
|
|
|
|
if Options.options.disable_werror:
|
|
try:
|
|
warnings.remove ('-Werror')
|
|
except ValueError:
|
|
pass
|
|
|
|
if cc and not conf.env['CCFLAGS']:
|
|
conf.env.append_value('CCFLAGS', optimizations)
|
|
conf.env.append_value('CCFLAGS', debug)
|
|
conf.env.append_value('CCFLAGS', warnings)
|
|
conf.env.append_value('CCDEFINES', debug_defs)
|
|
if cxx and not conf.env['CXXFLAGS']:
|
|
conf.env.append_value('CXXFLAGS', optimizations)
|
|
conf.env.append_value('CXXFLAGS', debug)
|
|
conf.env.append_value('CXXFLAGS', warnings)
|
|
conf.env.append_value('CXXDEFINES', debug_defs)
|