diff options
Diffstat (limited to 'third_party/waf/wafadmin/Tools/config_c.py')
-rw-r--r-- | third_party/waf/wafadmin/Tools/config_c.py | 754 |
1 files changed, 0 insertions, 754 deletions
diff --git a/third_party/waf/wafadmin/Tools/config_c.py b/third_party/waf/wafadmin/Tools/config_c.py deleted file mode 100644 index cdf3b3ebb68..00000000000 --- a/third_party/waf/wafadmin/Tools/config_c.py +++ /dev/null @@ -1,754 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2008 (ita) - -""" -c/c++ configuration routines -""" - -import os, imp, sys, shlex, shutil -from Utils import md5 -import Build, Utils, Configure, Task, Options, Logs, TaskGen -from Constants import * -from Configure import conf, conftest - -cfg_ver = { - 'atleast-version': '>=', - 'exact-version': '==', - 'max-version': '<=', -} - -SNIP1 = ''' - int main() { - void *p; - p=(void*)(%s); - return 0; -} -''' - -SNIP2 = ''' -int main() { - if ((%(type_name)s *) 0) return 0; - if (sizeof (%(type_name)s)) return 0; -} -''' - -SNIP3 = ''' -int main() { - return 0; -} -''' - -def parse_flags(line, uselib, env): - """pkg-config still has bugs on some platforms, and there are many -config programs, parsing flags is necessary :-/""" - - lst = shlex.split(line) - while lst: - x = lst.pop(0) - st = x[:2] - ot = x[2:] - app = env.append_value - if st == '-I' or st == '/I': - if not ot: ot = lst.pop(0) - app('CPPPATH_' + uselib, ot) - elif st == '-D': - if not ot: ot = lst.pop(0) - app('CXXDEFINES_' + uselib, ot) - app('CCDEFINES_' + uselib, ot) - elif st == '-l': - if not ot: ot = lst.pop(0) - app('LIB_' + uselib, ot) - elif st == '-L': - if not ot: ot = lst.pop(0) - app('LIBPATH_' + uselib, ot) - elif x == '-pthread' or x.startswith('+'): - app('CCFLAGS_' + uselib, x) - app('CXXFLAGS_' + uselib, x) - app('LINKFLAGS_' + uselib, x) - elif x == '-framework': - app('FRAMEWORK_' + uselib, lst.pop(0)) - elif x.startswith('-F'): - app('FRAMEWORKPATH_' + uselib, x[2:]) - elif x.startswith('-std'): - app('CCFLAGS_' + uselib, x) - app('CXXFLAGS_' + uselib, x) - app('LINKFLAGS_' + uselib, x) - # - # NOTE on special treatment of -Wl,-R and -Wl,-rpath: - # - # It is important to not put a library provided RPATH - # into the LINKFLAGS but in the RPATH instead, since - # the provided LINKFLAGS get prepended to our own internal - # RPATH later, and hence can potentially lead to linking - # in too old versions of our internal libs. - # - elif x == '-Wl,-rpath' or x == '-Wl,-R': - app('RPATH_' + uselib, lst.pop(0).lstrip('-Wl,')) - elif x.startswith('-Wl,-R,'): - app('RPATH_' + uselib, x[7:]) - elif x.startswith('-Wl,-R'): - app('RPATH_' + uselib, x[6:]) - elif x.startswith('-Wl,-rpath,'): - app('RPATH_' + uselib, x[11:]) - elif x.startswith('-Wl'): - app('LINKFLAGS_' + uselib, x) - elif x.startswith('-m') or x.startswith('-f'): - app('CCFLAGS_' + uselib, x) - app('CXXFLAGS_' + uselib, x) - -@conf -def ret_msg(self, f, kw): - """execute a function, when provided""" - if isinstance(f, str): - return f - return f(kw) - -@conf -def validate_cfg(self, kw): - if not 'path' in kw: - if not self.env.PKGCONFIG: - 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: - kw['msg'] = 'Checking for pkg-config version >= %s' % kw['atleast_pkgconfig_version'] - return - - # pkg-config --modversion - if 'modversion' in kw: - return - - if 'variables' in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for %s variables' % kw['package'] - return - - # checking for the version of a module, for the moment, one thing at a time - for x in cfg_ver.keys(): - y = x.replace('-', '_') - if y in kw: - if not 'package' in kw: - raise ValueError('%s requires a package' % x) - - if not 'msg' in kw: - kw['msg'] = 'Checking for %s %s %s' % (kw['package'], cfg_ver[x], kw[y]) - return - - if not 'msg' in kw: - kw['msg'] = 'Checking for %s' % (kw['package'] or kw['path']) - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - if not 'errmsg' in kw: - kw['errmsg'] = 'not found' - -@conf -def cmd_and_log(self, cmd, kw): - Logs.debug('runner: %s\n' % cmd) - if self.log: - self.log.write('%s\n' % cmd) - - try: - p = Utils.pproc.Popen(cmd, stdout=Utils.pproc.PIPE, stderr=Utils.pproc.PIPE, shell=True) - (out, err) = p.communicate() - except OSError, e: - self.log.write('error %r' % e) - self.fatal(str(e)) - - # placeholder, don't touch - out = str(out) - err = str(err) - - if self.log: - self.log.write(out) - self.log.write(err) - - if p.returncode: - if not kw.get('errmsg', ''): - if kw.get('mandatory', False): - kw['errmsg'] = out.strip() - else: - kw['errmsg'] = 'no' - self.fatal('fail') - return out - -@conf -def exec_cfg(self, kw): - - # pkg-config version - if 'atleast_pkgconfig_version' in kw: - cmd = '%s --atleast-pkgconfig-version=%s' % (kw['path'], kw['atleast_pkgconfig_version']) - self.cmd_and_log(cmd, kw) - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - return - - # checking for the version of a module - for x in cfg_ver: - y = x.replace('-', '_') - if y in kw: - self.cmd_and_log('%s --%s=%s %s' % (kw['path'], x, kw[y], kw['package']), kw) - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0) - break - - # retrieving the version of a module - if 'modversion' in kw: - version = self.cmd_and_log('%s --modversion %s' % (kw['path'], kw['modversion']), kw).strip() - self.define('%s_VERSION' % Utils.quote_define_name(kw.get('uselib_store', kw['modversion'])), version) - return version - - # retrieving variables of a module - if 'variables' in kw: - env = kw.get('env', self.env) - uselib = kw.get('uselib_store', kw['package'].upper()) - vars = Utils.to_list(kw['variables']) - for v in vars: - val = self.cmd_and_log('%s --variable=%s %s' % (kw['path'], v, kw['package']), kw).strip() - var = '%s_%s' % (uselib, v) - env[var] = val - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - return - - lst = [kw['path']] - - - defi = kw.get('define_variable', None) - if not defi: - defi = self.env.PKG_CONFIG_DEFINES or {} - for key, val in defi.iteritems(): - lst.append('--define-variable=%s=%s' % (key, val)) - - lst.append(kw.get('args', '')) - lst.append(kw['package']) - - # so we assume the command-line will output flags to be parsed afterwards - cmd = ' '.join(lst) - ret = self.cmd_and_log(cmd, kw) - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - - self.define(self.have_define(kw.get('uselib_store', kw['package'])), 1, 0) - parse_flags(ret, kw.get('uselib_store', kw['package'].upper()), kw.get('env', self.env)) - return ret - -@conf -def check_cfg(self, *k, **kw): - """ - for pkg-config mostly, but also all the -config tools - conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', package='', uselib_store='OPEN_MPI') - conf.check_cfg(package='dbus-1', variables='system_bus_default_address session_bus_services_dir') - """ - - self.validate_cfg(kw) - if 'msg' in kw: - self.check_message_1(kw['msg']) - ret = None - try: - ret = self.exec_cfg(kw) - except Configure.ConfigurationError, e: - if 'errmsg' in kw: - self.check_message_2(kw['errmsg'], 'YELLOW') - if 'mandatory' in kw and kw['mandatory']: - if Logs.verbose > 1: - raise - else: - self.fatal('the configuration failed (see %r)' % self.log.name) - else: - kw['success'] = ret - if 'okmsg' in kw: - self.check_message_2(self.ret_msg(kw['okmsg'], kw)) - - return ret - -# the idea is the following: now that we are certain -# that all the code here is only for c or c++, it is -# easy to put all the logic in one function -# -# this should prevent code duplication (ita) - -# env: an optional environment (modified -> provide a copy) -# compiler: cc or cxx - it tries to guess what is best -# type: cprogram, cshlib, cstaticlib -# code: a c code to execute -# uselib_store: where to add the variables -# uselib: parameters to use for building -# define: define to set, like FOO in #define FOO, if not set, add /* #undef FOO */ -# execute: True or False - will return the result of the execution - -@conf -def validate_c(self, kw): - """validate the parameters for the test method""" - - if not 'env' in kw: - kw['env'] = self.env.copy() - - env = kw['env'] - if not 'compiler' in kw: - kw['compiler'] = 'cc' - if env['CXX_NAME'] and Task.TaskBase.classes.get('cxx', None): - kw['compiler'] = 'cxx' - if not self.env['CXX']: - self.fatal('a c++ compiler is required') - else: - if not self.env['CC']: - self.fatal('a c compiler is required') - - if not 'type' in kw: - kw['type'] = 'cprogram' - - assert not(kw['type'] != 'cprogram' and kw.get('execute', 0)), 'can only execute programs' - - - #if kw['type'] != 'program' and kw.get('execute', 0): - # raise ValueError, 'can only execute programs' - - def to_header(dct): - if 'header_name' in dct: - dct = Utils.to_list(dct['header_name']) - return ''.join(['#include <%s>\n' % x for x in dct]) - return '' - - # set the file name - if not 'compile_mode' in kw: - kw['compile_mode'] = (kw['compiler'] == 'cxx') and 'cxx' or 'cc' - - if not 'compile_filename' in kw: - kw['compile_filename'] = 'test.c' + ((kw['compile_mode'] == 'cxx') and 'pp' or '') - - #OSX - if 'framework_name' in kw: - try: TaskGen.task_gen.create_task_macapp - except AttributeError: self.fatal('frameworks require the osx tool') - - 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'] = [] - fwk = '%s/%s.h' % (fwkname, fwkname) - if kw.get('remove_dot_h', None): - fwk = fwk[:-2] - kw['header_name'] = Utils.to_list(kw['header_name']) + [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) + SNIP1 % 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 'msg' in kw: - kw['msg'] = 'Checking for type %s' % tu - if not 'header_name' in kw: - kw['header_name'] = 'stdint.h' - kw['code'] = to_header(kw) + SNIP2 % {'type_name' : 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: - kw['msg'] = 'Checking for header %s' % kw['header_name'] - - l = Utils.to_list(kw['header_name']) - assert len(l)>0, 'list of headers in header_name is empty' - - kw['code'] = to_header(kw) + SNIP3 - - if not 'uselib_store' in kw: - kw['uselib_store'] = l[0].upper() - - if not 'define_name' in kw: - kw['define_name'] = self.have_define(l[0]) - - if 'lib' in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for library %s' % kw['lib'] - if not 'uselib_store' in kw: - kw['uselib_store'] = kw['lib'].upper() - - if 'staticlib' in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for static library %s' % kw['staticlib'] - if not 'uselib_store' in kw: - kw['uselib_store'] = kw['staticlib'].upper() - - if 'fragment' in kw: - # an additional code fragment may be provided to replace the predefined code - # in custom headers - kw['code'] = kw['fragment'] - if not 'msg' in kw: - kw['msg'] = 'Checking for custom code' - if not 'errmsg' in kw: - kw['errmsg'] = 'no' - - for (flagsname,flagstype) in [('cxxflags','compiler'), ('cflags','compiler'), ('linkflags','linker')]: - if flagsname in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for %s flags %s' % (flagstype, kw[flagsname]) - if not 'errmsg' in kw: - kw['errmsg'] = 'no' - - if not 'execute' in kw: - kw['execute'] = False - - if not 'errmsg' in kw: - kw['errmsg'] = 'not found' - - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - - if not 'code' in kw: - kw['code'] = SNIP3 - - if not kw.get('success'): kw['success'] = None - - assert 'msg' in kw, 'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c' - -@conf -def post_check(self, *k, **kw): - "set the variables after a test was run successfully" - - is_success = False - if kw['execute']: - if kw['success'] is not None: - is_success = True - else: - is_success = (kw['success'] == 0) - - if 'define_name' in kw: - if 'header_name' in kw or 'function_name' in kw or 'type_name' in kw or 'fragment' in kw: - if kw['execute']: - key = kw['success'] - if isinstance(key, str): - if key: - self.define(kw['define_name'], key, quote=kw.get('quote', 1)) - else: - self.define_cond(kw['define_name'], True) - else: - self.define_cond(kw['define_name'], False) - else: - self.define_cond(kw['define_name'], is_success) - - if is_success and 'uselib_store' in kw: - import cc, cxx - for k in set(cc.g_cc_flag_vars).union(cxx.g_cxx_flag_vars): - lk = k.lower() - # inconsistency: includes -> CPPPATH - if k == 'CPPPATH': lk = 'includes' - if k == 'CXXDEFINES': lk = 'defines' - if k == 'CCDEFINES': lk = 'defines' - if lk in kw: - val = kw[lk] - # remove trailing slash - if isinstance(val, str): - val = val.rstrip(os.path.sep) - self.env.append_unique(k + '_' + kw['uselib_store'], val) - -@conf -def check(self, *k, **kw): - # so this will be the generic function - # it will be safer to use check_cxx or check_cc - self.validate_c(kw) - self.check_message_1(kw['msg']) - ret = None - try: - ret = self.run_c_code(*k, **kw) - except Configure.ConfigurationError, e: - self.check_message_2(kw['errmsg'], 'YELLOW') - if 'mandatory' in kw and kw['mandatory']: - if Logs.verbose > 1: - raise - else: - self.fatal('the configuration failed (see %r)' % self.log.name) - else: - kw['success'] = ret - self.check_message_2(self.ret_msg(kw['okmsg'], kw)) - - self.post_check(*k, **kw) - if not kw.get('execute', False): - return ret == 0 - return ret - -@conf -def run_c_code(self, *k, **kw): - test_f_name = kw['compile_filename'] - - k = 0 - while k < 10000: - # make certain to use a fresh folder - necessary for win32 - dir = os.path.join(self.blddir, '.conf_check_%d' % k) - - # if the folder already exists, remove it - try: - shutil.rmtree(dir) - except OSError: - pass - - try: - os.stat(dir) - except OSError: - break - - k += 1 - - try: - os.makedirs(dir) - except: - self.fatal('cannot create a configuration test folder %r' % dir) - - try: - os.stat(dir) - except: - self.fatal('cannot use the configuration test folder %r' % dir) - - bdir = os.path.join(dir, 'testbuild') - - if not os.path.exists(bdir): - os.makedirs(bdir) - - env = kw['env'] - - dest = open(os.path.join(dir, test_f_name), 'w') - dest.write(kw['code']) - dest.close() - - back = os.path.abspath('.') - - bld = Build.BuildContext() - bld.log = self.log - bld.all_envs.update(self.all_envs) - bld.all_envs['default'] = env - bld.lst_variants = bld.all_envs.keys() - bld.load_dirs(dir, bdir) - - os.chdir(dir) - - bld.rescan(bld.srcnode) - - if not 'features' in kw: - # conf.check(features='cc cprogram pyext', ...) - kw['features'] = [kw['compile_mode'], kw['type']] # "cprogram cc" - - o = bld(features=kw['features'], source=test_f_name, target='testprog') - - for k, v in kw.iteritems(): - setattr(o, k, v) - - self.log.write("==>\n%s\n<==\n" % kw['code']) - - # compile the program - try: - bld.compile() - except Utils.WafError: - ret = Utils.ex_stack() - else: - ret = 0 - - # chdir before returning - os.chdir(back) - - if ret: - self.log.write('command returned %r' % ret) - self.fatal(str(ret)) - - # if we need to run the program, try to get its result - # keep the name of the program to execute - if kw['execute']: - lastprog = o.link_task.outputs[0].abspath(env) - - args = Utils.to_list(kw.get('exec_args', [])) - proc = Utils.pproc.Popen([lastprog] + args, stdout=Utils.pproc.PIPE, stderr=Utils.pproc.PIPE) - (out, err) = proc.communicate() - w = self.log.write - w(str(out)) - w('\n') - w(str(err)) - w('\n') - w('returncode %r' % proc.returncode) - w('\n') - if proc.returncode: - self.fatal(Utils.ex_stack()) - ret = out - - return ret - -@conf -def check_cxx(self, *k, **kw): - kw['compiler'] = 'cxx' - return self.check(*k, **kw) - -@conf -def check_cc(self, *k, **kw): - kw['compiler'] = 'cc' - return self.check(*k, **kw) - -@conf -def define(self, define, value, quote=1): - """store a single define and its state into an internal list for later - writing to a config header file. Value can only be - a string or int; other types not supported. String - values will appear properly quoted in the generated - header file.""" - assert define and isinstance(define, str) - - # ordered_dict is for writing the configuration header in order - tbl = self.env[DEFINES] or Utils.ordered_dict() - - # the user forgot to tell if the value is quoted or not - if isinstance(value, str): - if quote: - tbl[define] = '"%s"' % repr('"'+value)[2:-1].replace('"', '\\"') - else: - tbl[define] = value - elif isinstance(value, int): - tbl[define] = value - else: - raise TypeError('define %r -> %r must be a string or an int' % (define, value)) - - # add later to make reconfiguring faster - self.env[DEFINES] = tbl - self.env[define] = value # <- not certain this is necessary - -@conf -def undefine(self, define): - """store a single define and its state into an internal list - for later writing to a config header file""" - assert define and isinstance(define, str) - - tbl = self.env[DEFINES] or Utils.ordered_dict() - - value = UNDEFINED - tbl[define] = value - - # add later to make reconfiguring faster - self.env[DEFINES] = tbl - self.env[define] = value - -@conf -def define_cond(self, name, value): - """Conditionally define a name. - Formally equivalent to: if value: define(name, 1) else: undefine(name)""" - if value: - self.define(name, 1) - else: - self.undefine(name) - -@conf -def is_defined(self, key): - defines = self.env[DEFINES] - if not defines: - return False - try: - value = defines[key] - except KeyError: - return False - else: - return value != UNDEFINED - -@conf -def get_define(self, define): - "get the value of a previously stored define" - try: return self.env[DEFINES][define] - except KeyError: return None - -@conf -def have_define(self, name): - "prefix the define with 'HAVE_' and make sure it has valid characters." - return self.__dict__.get('HAVE_PAT', 'HAVE_%s') % Utils.quote_define_name(name) - -@conf -def write_config_header(self, configfile='', env='', guard='', top=False): - "save the defines into a file" - if not configfile: configfile = WAF_CONFIG_H - waf_guard = guard or '_%s_WAF' % Utils.quote_define_name(configfile) - - # configfile -> absolute path - # there is a good reason to concatenate first and to split afterwards - if not env: env = self.env - if top: - diff = '' - else: - diff = Utils.diff_path(self.srcdir, self.curdir) - full = os.sep.join([self.blddir, env.variant(), diff, configfile]) - full = os.path.normpath(full) - (dir, base) = os.path.split(full) - - try: os.makedirs(dir) - except: pass - - dest = open(full, 'w') - dest.write('/* Configuration header created by Waf - do not edit */\n') - dest.write('#ifndef %s\n#define %s\n\n' % (waf_guard, waf_guard)) - - dest.write(self.get_config_header()) - - # config files are not removed on "waf clean" - env.append_unique(CFG_FILES, os.path.join(diff, configfile)) - - dest.write('\n#endif /* %s */\n' % waf_guard) - dest.close() - -@conf -def get_config_header(self): - """Fill-in the contents of the config header. Override when you need to write your own config header.""" - config_header = [] - - tbl = self.env[DEFINES] or Utils.ordered_dict() - for key in tbl.allkeys: - value = tbl[key] - if value is None: - config_header.append('#define %s' % key) - elif value is UNDEFINED: - config_header.append('/* #undef %s */' % key) - else: - config_header.append('#define %s %s' % (key, value)) - return "\n".join(config_header) - -@conftest -def find_cpp(conf): - v = conf.env - cpp = [] - if v['CPP']: cpp = v['CPP'] - elif 'CPP' in conf.environ: cpp = conf.environ['CPP'] - if not cpp: cpp = conf.find_program('cpp', var='CPP') - #if not cpp: cpp = v['CC'] - #if not cpp: cpp = v['CXX'] - v['CPP'] = cpp - -@conftest -def cc_add_flags(conf): - conf.add_os_flags('CFLAGS', 'CCFLAGS') - conf.add_os_flags('CPPFLAGS') - -@conftest -def cxx_add_flags(conf): - conf.add_os_flags('CXXFLAGS') - conf.add_os_flags('CPPFLAGS') - -@conftest -def link_add_flags(conf): - conf.add_os_flags('LINKFLAGS') - conf.add_os_flags('LDFLAGS', 'LINKFLAGS') - -@conftest -def cc_load_tools(conf): - conf.check_tool('cc') - -@conftest -def cxx_load_tools(conf): - conf.check_tool('cxx') |