diff options
Diffstat (limited to 'third_party/waf/waflib/Tools/c_config.py')
-rw-r--r-- | third_party/waf/waflib/Tools/c_config.py | 218 |
1 files changed, 74 insertions, 144 deletions
diff --git a/third_party/waf/waflib/Tools/c_config.py b/third_party/waf/waflib/Tools/c_config.py index b6156004895..db8197db14b 100644 --- a/third_party/waf/waflib/Tools/c_config.py +++ b/third_party/waf/waflib/Tools/c_config.py @@ -4,7 +4,7 @@ #!/usr/bin/env python # encoding: utf-8 -# Thomas Nagy, 2005-2016 (ita) +# Thomas Nagy, 2005-2018 (ita) """ C/C++/D configuration helpers @@ -23,32 +23,6 @@ WAF_CONFIG_H = 'config.h' DEFKEYS = 'define_key' INCKEYS = 'include_key' -cfg_ver = { - 'atleast-version': '>=', - 'exact-version': '==', - 'max-version': '<=', -} - -SNIP_FUNCTION = ''' -int main(int argc, char **argv) { - void (*p)(); - (void)argc; (void)argv; - p=(void(*)())(%s); - return !p; -} -''' -"""Code template for checking for functions""" - -SNIP_TYPE = ''' -int main(int argc, char **argv) { - (void)argc; (void)argv; - if ((%(type_name)s *) 0) return 0; - if (sizeof (%(type_name)s)) return 0; - return 1; -} -''' -"""Code template for checking for types""" - SNIP_EMPTY_PROGRAM = ''' int main(int argc, char **argv) { (void)argc; (void)argv; @@ -56,15 +30,6 @@ int main(int argc, char **argv) { } ''' -SNIP_FIELD = ''' -int main(int argc, char **argv) { - char *off; - (void)argc; (void)argv; - off = (char*) &((%(type_name)s*)0)->%(field_name)s; - return (size_t) off < sizeof(%(type_name)s); -} -''' - MACRO_TO_DESTOS = { '__linux__' : 'linux', '__GNU__' : 'gnu', # hurd @@ -205,7 +170,8 @@ def parse_flags(self, line, uselib_store, env=None, force_static=False, posix=No static = False elif x.startswith('-Wl') or x in ('-rdynamic', '-pie'): app('LINKFLAGS', x) - elif x.startswith(('-m', '-f', '-dynamic', '-O')): + elif x.startswith(('-m', '-f', '-dynamic', '-O', '-g')): + # Adding the -W option breaks python builds on Openindiana app('CFLAGS', x) app('CXXFLAGS', x) elif x.startswith('-bundle'): @@ -243,55 +209,42 @@ def validate_cfg(self, kw): self.find_program('pkg-config', var='PKGCONFIG') kw['path'] = self.env.PKGCONFIG - # pkg-config version - if 'atleast_pkgconfig_version' in kw: - if not 'msg' in kw: + # verify that exactly one action is requested + s = ('atleast_pkgconfig_version' in kw) + ('modversion' in kw) + ('package' in kw) + if s != 1: + raise ValueError('exactly one of atleast_pkgconfig_version, modversion and package must be set') + if not 'msg' in kw: + if 'atleast_pkgconfig_version' in kw: kw['msg'] = 'Checking for pkg-config version >= %r' % kw['atleast_pkgconfig_version'] - return + elif 'modversion' in kw: + kw['msg'] = 'Checking for %r version' % kw['modversion'] + else: + kw['msg'] = 'Checking for %r' %(kw['package']) - if not 'okmsg' in kw: + # let the modversion check set the okmsg to the detected version + if not 'okmsg' in kw and not 'modversion' in kw: kw['okmsg'] = 'yes' if not 'errmsg' in kw: kw['errmsg'] = 'not found' - if 'modversion' in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for %r version' % kw['modversion'] + # pkg-config version + if 'atleast_pkgconfig_version' in kw: + pass + elif 'modversion' in kw: if not 'uselib_store' in kw: kw['uselib_store'] = kw['modversion'] if not 'define_name' in kw: kw['define_name'] = '%s_VERSION' % Utils.quote_define_name(kw['uselib_store']) - return - - if not 'package' in kw: - raise ValueError('a package name is required') - - if not 'uselib_store' in kw: - kw['uselib_store'] = kw['package'].upper() - - if not 'define_name' in kw: - kw['define_name'] = self.have_define(kw['uselib_store']) - - if not 'msg' in kw: - kw['msg'] = 'Checking for %r' % (kw['package'] or kw['path']) - - for x in cfg_ver: - # Gotcha: only one predicate is allowed at a time - # TODO remove in waf 2.0 - y = x.replace('-', '_') - if y in kw: - package = kw['package'] - if Logs.verbose: - Logs.warn('Passing %r to conf.check_cfg() is obsolete, pass parameters directly, eg:', y) - Logs.warn(" conf.check_cfg(package='%s', args=['--libs', '--cflags', '%s >= 1.6'])", package, package) - if not 'msg' in kw: - kw['msg'] = 'Checking for %r %s %s' % (package, cfg_ver[x], kw[y]) - break + else: + if not 'uselib_store' in kw: + kw['uselib_store'] = Utils.to_list(kw['package'])[0].upper() + if not 'define_name' in kw: + kw['define_name'] = self.have_define(kw['uselib_store']) @conf def exec_cfg(self, kw): """ - Executes ``pkg-config`` or other ``-config`` applications to colect configuration flags: + Executes ``pkg-config`` or other ``-config`` applications to collect configuration flags: * if atleast_pkgconfig_version is given, check that pkg-config has the version n and return * if modversion is given, then return the module version @@ -335,23 +288,13 @@ def exec_cfg(self, kw): if 'atleast_pkgconfig_version' in kw: cmd = path + ['--atleast-pkgconfig-version=%s' % kw['atleast_pkgconfig_version']] self.cmd_and_log(cmd, env=env) - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' return - for x in cfg_ver: - # TODO remove in waf 2.0 - y = x.replace('-', '_') - if y in kw: - self.cmd_and_log(path + ['--%s=%s' % (x, kw[y]), kw['package']], env=env) - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - define_it() - break - # single version for a module if 'modversion' in kw: version = self.cmd_and_log(path + ['--modversion', kw['modversion']], env=env).strip() + if not 'okmsg' in kw: + kw['okmsg'] = version self.define(kw['define_name'], version) return version @@ -381,14 +324,10 @@ def exec_cfg(self, kw): val = self.cmd_and_log(lst + ['--variable=' + v], env=env).strip() var = '%s_%s' % (kw['uselib_store'], v) v_env[var] = val - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' return # so we assume the command-line will output flags to be parsed afterwards ret = self.cmd_and_log(lst, env=env) - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' define_it() self.parse_flags(ret, kw['uselib_store'], kw.get('env', self.env), force_static=static, posix=kw.get('posix')) @@ -405,8 +344,6 @@ def check_cfg(self, *k, **kw): def configure(conf): conf.load('compiler_c') conf.check_cfg(package='glib-2.0', args='--libs --cflags') - conf.check_cfg(package='glib-2.0', uselib_store='GLIB', atleast_version='2.10.0', - args='--cflags --libs') conf.check_cfg(package='pango') conf.check_cfg(package='pango', uselib_store='MYPANGO', args=['--cflags', '--libs']) conf.check_cfg(package='pango', @@ -419,11 +356,6 @@ def check_cfg(self, *k, **kw): conf.check_cfg(package='gtk+-2.0', variables=['includedir', 'prefix'], uselib_store='FOO') print(conf.env.FOO_includedir) """ - if k: - lst = k[0].split() - kw['package'] = lst[0] - kw['args'] = ' '.join(lst[1:]) - self.validate_cfg(kw) if 'msg' in kw: self.start_msg(kw['msg'], **kw) @@ -490,6 +422,9 @@ def validate_c(self, kw): :param auto_add_header_name: if header_name was set, add the headers in env.INCKEYS so the next tests will include these headers :type auto_add_header_name: bool """ + for x in ('type_name', 'field_name', 'function_name'): + if x in kw: + Logs.warn('Invalid argument %r in test' % x) if not 'build_fun' in kw: kw['build_fun'] = build_fun @@ -510,7 +445,7 @@ def validate_c(self, kw): if not 'compile_mode' in kw: kw['compile_mode'] = 'c' - if 'cxx' in Utils.to_list(kw.get('features',[])) or kw.get('compiler', '') == 'cxx': + if 'cxx' in Utils.to_list(kw.get('features', [])) or kw.get('compiler') == 'cxx': kw['compile_mode'] = 'cxx' if not 'type' in kw: @@ -533,50 +468,19 @@ def validate_c(self, kw): return ''.join(['#include <%s>\n' % x for x in dct]) return '' - #OSX if 'framework_name' in kw: + # OSX, not sure this is used anywhere fwkname = kw['framework_name'] if not 'uselib_store' in kw: kw['uselib_store'] = fwkname.upper() - if not kw.get('no_header', False): - if not 'header_name' in kw: - kw['header_name'] = [] + if not kw.get('no_header'): fwk = '%s/%s.h' % (fwkname, fwkname) if kw.get('remove_dot_h'): fwk = fwk[:-2] - kw['header_name'] = Utils.to_list(kw['header_name']) + [fwk] - + val = kw.get('header_name', []) + kw['header_name'] = Utils.to_list(val) + [fwk] kw['msg'] = 'Checking for framework %s' % fwkname kw['framework'] = fwkname - #kw['frameworkpath'] = set it yourself - - if 'function_name' in kw: - fu = kw['function_name'] - if not 'msg' in kw: - kw['msg'] = 'Checking for function %s' % fu - kw['code'] = to_header(kw) + SNIP_FUNCTION % fu - if not 'uselib_store' in kw: - kw['uselib_store'] = fu.upper() - if not 'define_name' in kw: - kw['define_name'] = self.have_define(fu) - - elif 'type_name' in kw: - tu = kw['type_name'] - if not 'header_name' in kw: - kw['header_name'] = 'stdint.h' - if 'field_name' in kw: - field = kw['field_name'] - kw['code'] = to_header(kw) + SNIP_FIELD % {'type_name' : tu, 'field_name' : field} - if not 'msg' in kw: - kw['msg'] = 'Checking for field %s in %s' % (field, tu) - if not 'define_name' in kw: - kw['define_name'] = self.have_define((tu + '_' + field).upper()) - else: - kw['code'] = to_header(kw) + SNIP_TYPE % {'type_name' : tu} - if not 'msg' in kw: - kw['msg'] = 'Checking for type %s' % tu - if not 'define_name' in kw: - kw['define_name'] = self.have_define(tu.upper()) elif 'header_name' in kw: if not 'msg' in kw: @@ -639,11 +543,12 @@ def validate_c(self, kw): kw['code'] = '\n'.join(['#include <%s>' % x for x in self.env[INCKEYS]]) + '\n' + kw['code'] # in case defines lead to very long command-lines - if kw.get('merge_config_header', False) or env.merge_config_header: + if kw.get('merge_config_header') or env.merge_config_header: kw['code'] = '%s\n\n%s' % (self.get_config_header(), kw['code']) env.DEFINES = [] # modify the copy - if not kw.get('success'): kw['success'] = None + if not kw.get('success'): + kw['success'] = None if 'define_name' in kw: self.undefine(kw['define_name']) @@ -659,7 +564,7 @@ def post_check(self, *k, **kw): is_success = 0 if kw['execute']: if kw['success'] is not None: - if kw.get('define_ret', False): + if kw.get('define_ret'): is_success = kw['success'] else: is_success = (kw['success'] == 0) @@ -667,7 +572,6 @@ def post_check(self, *k, **kw): is_success = (kw['success'] == 0) if kw.get('define_name'): - # TODO this is still way too complicated comment = kw.get('comment', '') define_name = kw['define_name'] if kw['execute'] and kw.get('define_ret') and isinstance(is_success, str): @@ -698,7 +602,7 @@ def post_check(self, *k, **kw): self.env[define_name] = int(is_success) if 'header_name' in kw: - if kw.get('auto_add_header_name', False): + if kw.get('auto_add_header_name'): self.env.append_value(INCKEYS, Utils.to_list(kw['header_name'])) if is_success and 'uselib_store' in kw: @@ -986,7 +890,8 @@ def write_config_header(self, configfile='', guard='', top=False, defines=True, :type define_prefix: string :param define_prefix: prefix all the defines in the file with a particular prefix """ - if not configfile: configfile = WAF_CONFIG_H + if not configfile: + configfile = WAF_CONFIG_H waf_guard = guard or 'W_%s_WAF' % Utils.quote_define_name(configfile) node = top and self.bldnode or self.path.get_bld() @@ -1110,8 +1015,8 @@ def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): cmd = cc + ['-dM', '-E', '-'] env = conf.env.env or None try: - out, err = conf.cmd_and_log(cmd, output=0, input='\n', env=env) - except Exception: + out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), env=env) + except Errors.WafError: conf.fatal('Could not determine the compiler version %r' % cmd) if gcc: @@ -1159,6 +1064,8 @@ def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): conf.env.DEST_BINFMT = 'elf' elif isD('__WINNT__') or isD('__CYGWIN__') or isD('_WIN32'): conf.env.DEST_BINFMT = 'pe' + if not conf.env.IMPLIBDIR: + conf.env.IMPLIBDIR = conf.env.LIBDIR # for .lib or .dll.a files conf.env.LIBDIR = conf.env.BINDIR elif isD('__APPLE__'): conf.env.DEST_BINFMT = 'mac-o' @@ -1218,7 +1125,7 @@ def get_suncc_version(conf, cc): cmd = cc + ['-V'] try: out, err = conf.cmd_and_log(cmd, output=0) - except Errors.WafError ,e: + except Errors.WafError as e: # Older versions of the compiler exit with non-zero status when reporting their version if not (hasattr(e, 'returncode') and hasattr(e, 'stdout') and hasattr(e, 'stderr')): conf.fatal('Could not find suncc %r' % cmd) @@ -1252,14 +1159,14 @@ def add_as_needed(self): # ============ parallel configuration -class cfgtask(Task.TaskBase): +class cfgtask(Task.Task): """ A task that executes build configuration tests (calls conf.check) Make sure to use locks if concurrent access to the same conf.env data is necessary. """ def __init__(self, *k, **kw): - Task.TaskBase.__init__(self, *k, **kw) + Task.Task.__init__(self, *k, **kw) self.run_after = set() def display(self): @@ -1274,6 +1181,9 @@ class cfgtask(Task.TaskBase): def uid(self): return Utils.SIG_NIL + def signature(self): + return Utils.SIG_NIL + def run(self): conf = self.conf bld = Build.BuildContext(top_dir=conf.srcnode.abspath(), out_dir=conf.bldnode.abspath()) @@ -1301,7 +1211,7 @@ class cfgtask(Task.TaskBase): return 1 def process(self): - Task.TaskBase.process(self) + Task.Task.process(self) if 'msg' in self.args: with self.generator.bld.multicheck_lock: self.conf.start_msg(self.args['msg']) @@ -1357,11 +1267,12 @@ def multicheck(self, *k, **kw): bld = par() bld.keep = kw.get('run_all_tests', True) + bld.imp_sigs = {} tasks = [] id_to_task = {} for dct in k: - x = Task.classes['cfgtask'](bld=bld) + x = Task.classes['cfgtask'](bld=bld, env=None) tasks.append(x) x.args = dct x.bld = bld @@ -1424,3 +1335,22 @@ def multicheck(self, *k, **kw): if x.hasrun != Task.SUCCESS: if x.args.get('mandatory', True): self.fatal(kw.get('fatalmsg') or 'One of the tests has failed, read config.log for more information') + +@conf +def check_gcc_o_space(self, mode='c'): + if int(self.env.CC_VERSION[0]) > 4: + # this is for old compilers + return + self.env.stash() + if mode == 'c': + self.env.CCLNK_TGT_F = ['-o', ''] + elif mode == 'cxx': + self.env.CXXLNK_TGT_F = ['-o', ''] + features = '%s %sshlib' % (mode, mode) + try: + self.check(msg='Checking if the -o link must be split from arguments', fragment=SNIP_EMPTY_PROGRAM, features=features) + except self.errors.ConfigurationError: + self.env.revert() + else: + self.env.commit() + |