diff options
author | David Cournapeau <cournape@gmail.com> | 2011-04-06 08:52:44 +0900 |
---|---|---|
committer | David Cournapeau <cournape@gmail.com> | 2011-08-29 00:32:26 +0200 |
commit | 26403b686f5f2cec29f8179f9af771c1cbe2198e (patch) | |
tree | 4172d134a86d4d17b0546b12647cc36051f3ec02 /numpy/build_utils | |
parent | c334fbbf35e4eb4eb1dfc0c08412e9a0d6e5a873 (diff) | |
download | numpy-26403b686f5f2cec29f8179f9af771c1cbe2198e.tar.gz |
BUG: build waf build utils in separate module to avoid 'spurious' imports.
Diffstat (limited to 'numpy/build_utils')
-rw-r--r-- | numpy/build_utils/__init__.py | 467 | ||||
-rw-r--r-- | numpy/build_utils/waf.py | 467 |
2 files changed, 467 insertions, 467 deletions
diff --git a/numpy/build_utils/__init__.py b/numpy/build_utils/__init__.py index c66be467d..e69de29bb 100644 --- a/numpy/build_utils/__init__.py +++ b/numpy/build_utils/__init__.py @@ -1,467 +0,0 @@ -import os -import re - -import waflib.Configure -import waflib.Tools.c_config -from waflib import Logs, Utils - -DEFKEYS = waflib.Tools.c_config.DEFKEYS -DEFINE_COMMENTS = "define_commentz" - -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 '' - -# Make the given string safe to be used as a CPP macro -def sanitize_string(s): - key_up = s.upper() - return re.sub('[^A-Z0-9_]', '_', key_up) - -def validate_arguments(self, kw): - if not 'env' in kw: - kw['env'] = self.env.derive() - if not "compile_mode" in kw: - kw["compile_mode"] = "c" - if not 'compile_filename' in kw: - kw['compile_filename'] = 'test.c' + \ - ((kw['compile_mode'] == 'cxx') and 'pp' or '') - if not 'features' in kw: - kw['features'] = [kw['compile_mode']] - if not 'execute' in kw: - kw['execute'] = False - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - if not 'errmsg' in kw: - kw['errmsg'] = 'no !' - -def try_compile(self, kw): - self.start_msg(kw["msg"]) - ret = None - try: - ret = self.run_c_code(**kw) - except self.errors.ConfigurationError as e: - self.end_msg(kw['errmsg'], 'YELLOW') - if Logs.verbose > 1: - raise - else: - self.fatal('The configuration failed') - else: - kw['success'] = ret - self.end_msg(self.ret_msg(kw['okmsg'], kw)) - -@waflib.Configure.conf -def check_header(self, header_name, **kw): - code = """ -%s - -int main() -{ -} -""" % to_header({"header_name": header_name}) - - kw["code"] = code - kw["define_comment"] = "/* Define to 1 if you have the `%s' header. */" % header_name - kw["define_name"] = "HAVE_%s" % sanitize_string(header_name) - if not "features" in kw: - kw["features"] = ["c"] - kw["msg"] = "Checking for header %r" % header_name - - validate_arguments(self, kw) - try_compile(self, kw) - ret = kw["success"] - if ret == 0: - kw["define_value"] = 1 - else: - kw["define_value"] = 0 - - self.post_check(**kw) - if not kw.get('execute', False): - return ret == 0 - return ret - -@waflib.Configure.conf -def check_declaration(self, symbol, **kw): - code = r""" -int main() -{ -#ifndef %s - (void) %s; -#endif - ; - return 0; -} -""" % (symbol, symbol) - - kw["code"] = to_header(kw) + code - kw["msg"] = "Checking for macro %r" % symbol - kw["errmsg"] = "not found" - kw["okmsg"] = "yes" - - validate_arguments(self, kw) - try_compile(self, kw) - ret = kw["success"] - - kw["define_name"] = "HAVE_DECL_%s" % sanitize_string(symbol) - kw["define_comment"] = "/* Set to 1 if %s is defined. */" % symbol - self.post_check(**kw) - if not kw.get('execute', False): - return ret == 0 - return ret - -@waflib.Configure.conf -def check_type(self, type_name, **kw): - code = r""" -int main() { - if ((%(type_name)s *) 0) - return 0; - if (sizeof (%(type_name)s)) - return 0; -} -""" % {"type_name": type_name} - - kw["code"] = to_header(kw) + code - kw["msg"] = "Checking for type %r" % type_name - kw["errmsg"] = "not found" - kw["okmsg"] = "yes" - - validate_arguments(self, kw) - try_compile(self, kw) - ret = kw["success"] - if ret == 0: - kw["define_value"] = 1 - else: - kw["define_value"] = 0 - - kw["define_name"] = "HAVE_%s" % sanitize_string(type_name) - kw["define_comment"] = "/* Set to 1 if %s is defined. */" % type_name - self.post_check(**kw) - if not kw.get('execute', False): - return ret == 0 - return ret - -def do_binary_search(conf, type_name, kw): - code = """\ -typedef %(type)s waf_check_sizeof_type; -int main () -{ - static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) >= 0)]; - test_array [0] = 0 - - ; - return 0; -} -""" % {"type": type_name} - kw["code"] = to_header(kw) + code - - try: - conf.run_c_code(**kw) - except conf.errors.ConfigurationError, e: - conf.end_msg("failed !") - if waflib.Logs.verbose > 1: - raise - else: - conf.fatal("The configuration failed !") - - body = r""" -typedef %(type)s waf_check_sizeof_type; -int main () -{ - static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) <= %(size)s)]; - test_array [0] = 0 - - ; - return 0; -} -""" - # The principle is simple: we first find low and high bounds - # of size for the type, where low/high are looked up on a log - # scale. Then, we do a binary search to find the exact size - # between low and high - low = 0 - mid = 0 - while True: - try: - kw["code"] = to_header(kw) + body % {"type": type_name, "size": mid} - validate_arguments(conf, kw) - conf.run_c_code(**kw) - break - except conf.errors.ConfigurationError: - #log.info("failure to test for bound %d" % mid) - low = mid + 1 - mid = 2 * mid + 1 - - high = mid - ret = None - # Binary search: - while low != high: - mid = (high - low) / 2 + low - try: - kw["code"] = to_header(kw) + body % {"type": type_name, "size": mid} - validate_arguments(conf, kw) - ret = conf.run_c_code(**kw) - high = mid - except conf.errors.ConfigurationError: - low = mid + 1 - - return low - -@waflib.Configure.conf -def check_type_size(conf, type_name, expected_sizes=None, **kw): - kw["define_name"] = "SIZEOF_%s" % sanitize_string(type_name) - kw["define_comment"] = "/* The size of `%s', as computed by sizeof. */" % type_name - kw["msg"] = "Checking sizeof(%s)" % type_name - - validate_arguments(conf, kw) - conf.start_msg(kw["msg"]) - - if expected_sizes is not None: - try: - val = int(expected_sizes) - except TypeError: - values = expected_sizes - else: - values = [val] - - size = None - for value in values: - code = """\ - typedef %(type)s waf_check_sizeof_type; - int main () - { - static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) == %(size)d)]; - test_array [0] = 0 - - ; - return 0; - } - """ % {"type": type_name, "size": value} - kw["code"] = to_header(kw) + code - try: - conf.run_c_code(**kw) - size = value - break - except conf.errors.ConfigurationError: - pass - if size is None: - size = do_binary_search(conf, type_name, kw) - else: - size = do_binary_search(conf, type_name, kw) - - kw["define_value"] = size - kw["success"] = 0 - conf.end_msg(size) - conf.post_check(**kw) - return size - -@waflib.Configure.conf -def check_functions_at_once(self, funcs, **kw): - header = [] - header = ['#ifdef __cplusplus'] - header.append('extern "C" {') - header.append('#endif') - for f in funcs: - header.append("\tchar %s();" % f) - # Handle MSVC intrinsics: force MS compiler to make a function - # call. Useful to test for some functions when built with - # optimization on, to avoid build error because the intrinsic - # and our 'fake' test declaration do not match. - header.append("#ifdef _MSC_VER") - header.append("#pragma function(%s)" % f) - header.append("#endif") - header.append('#ifdef __cplusplus') - header.append('};') - header.append('#endif') - funcs_decl = "\n".join(header) - - tmp = [] - for f in funcs: - tmp.append("\t%s();" % f) - tmp = "\n".join(tmp) - - code = r""" -%(include)s -%(funcs_decl)s - -int main (void) -{ - %(tmp)s - return 0; -} -""" % {"tmp": tmp, "include": to_header(kw), "funcs_decl": funcs_decl} - kw["code"] = code - if not "features" in kw: - kw["features"] = ["c", "cprogram"] - - msg = ", ".join(funcs) - if len(msg) > 30: - _funcs = list(funcs) - msg = [] - while len(", ".join(msg)) < 30 and _funcs: - msg.append(_funcs.pop(0)) - msg = ", ".join(msg) + ",..." - if "lib" in kw: - kw["msg"] = "Checking for functions %s in library %r" % (msg, kw["lib"]) - else: - kw["msg"] = "Checking for functions %s" % msg - - validate_arguments(self, kw) - try_compile(self, kw) - ret = kw["success"] - - # We set the config.h define here because we need to define several of them - # in one shot - if ret == 0: - for f in funcs: - self.define_with_comment("HAVE_%s" % sanitize_string(f), 1, - "/* Define to 1 if you have the `%s' function */" % f) - - self.post_check(**kw) - if not kw.get('execute', False): - return ret == 0 - return ret - -@waflib.Configure.conf -def check_inline(conf, **kw): - validate_arguments(conf, kw) - - code = """ -#ifndef __cplusplus -static %(inline)s int static_func (void) -{ - return 0; -} -%(inline)s int nostatic_func (void) -{ - return 0; -} -#endif""" - - conf.start_msg("Checking for inline support") - inline = None - for k in ['inline', '__inline__', '__inline']: - try: - kw["code"] = code % {"inline": k} - ret = conf.run_c_code(**kw) - inline = k - break - except conf.errors.ConfigurationError: - pass - - if inline is None: - conf.end_msg("failed", 'YELLOW') - if Logs.verbose > 1: - raise - else: - conf.fatal('The configuration failed') - else: - kw['success'] = ret - conf.end_msg(inline) - return inline - -@waflib.Configure.conf -def post_check(self, *k, **kw): - "set the variables after a test was run successfully" - - is_success = 0 - if kw['execute']: - if kw['success'] is not None: - is_success = kw['success'] - else: - is_success = (kw['success'] == 0) - - def define_or_stuff(): - nm = kw['define_name'] - cmt = kw.get('define_comment', None) - value = kw.get("define_value", is_success) - if kw['execute'] and kw.get('define_ret', None) and isinstance(is_success, str): - self.define_with_comment(kw['define_name'], value, cmt, quote=kw.get('quote', 1)) - else: - self.define_cond(kw['define_name'], value, cmt) - - if 'define_name' in kw: - define_or_stuff() - - if is_success and 'uselib_store' in kw: - from waflib.Tools import ccroot - - # TODO see get_uselib_vars from ccroot.py - _vars = set([]) - for x in kw['features']: - if x in ccroot.USELIB_VARS: - _vars |= ccroot.USELIB_VARS[x] - - for k in _vars: - lk = k.lower() - if k == 'INCLUDES': lk = 'includes' - if k == 'DEFKEYS': 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) - return is_success - -@waflib.Configure.conf -def define_with_comment(conf, define, value, comment=None, quote=True): - if comment is None: - return conf.define(define, value, quote) - - assert define and isinstance(define, str) - - comment_tbl = conf.env[DEFINE_COMMENTS] or {} - comment_tbl[define] = comment - conf.env[DEFINE_COMMENTS] = comment_tbl - - return conf.define(define, value, quote) - -@waflib.Configure.conf -def get_comment(self, key): - assert key and isinstance(key, str) - - if key in self.env[DEFINE_COMMENTS]: - return self.env[DEFINE_COMMENTS][key] - return None - -@waflib.Configure.conf -def define_cond(self, name, value, comment): - """Conditionally define a name. - Formally equivalent to: if value: define(name, 1) else: undefine(name)""" - if value: - self.define_with_comment(name, value, comment) - else: - self.undefine(name) - -@waflib.Configure.conf -def get_config_header(self, defines=True, headers=False): - """ - Create the contents of a ``config.h`` file from the defines and includes - set in conf.env.define_key / conf.env.include_key. No include guards are added. - - :param defines: write the defines values - :type defines: bool - :param headers: write the headers - :type headers: bool - :return: the contents of a ``config.h`` file - :rtype: string - """ - tpl = self.env["CONFIG_HEADER_TEMPLATE"] or "%(content)s" - - lst = [] - if headers: - for x in self.env[INCKEYS]: - lst.append('#include <%s>' % x) - - if defines: - for x in self.env[DEFKEYS]: - if self.is_defined(x): - val = self.get_define(x) - cmt = self.get_comment(x) - if cmt is not None: - lst.append(cmt) - lst.append('#define %s %s\n' % (x, val)) - else: - lst.append('/* #undef %s */\n' % x) - return tpl % {"content": "\n".join(lst)} diff --git a/numpy/build_utils/waf.py b/numpy/build_utils/waf.py new file mode 100644 index 000000000..c66be467d --- /dev/null +++ b/numpy/build_utils/waf.py @@ -0,0 +1,467 @@ +import os +import re + +import waflib.Configure +import waflib.Tools.c_config +from waflib import Logs, Utils + +DEFKEYS = waflib.Tools.c_config.DEFKEYS +DEFINE_COMMENTS = "define_commentz" + +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 '' + +# Make the given string safe to be used as a CPP macro +def sanitize_string(s): + key_up = s.upper() + return re.sub('[^A-Z0-9_]', '_', key_up) + +def validate_arguments(self, kw): + if not 'env' in kw: + kw['env'] = self.env.derive() + if not "compile_mode" in kw: + kw["compile_mode"] = "c" + if not 'compile_filename' in kw: + kw['compile_filename'] = 'test.c' + \ + ((kw['compile_mode'] == 'cxx') and 'pp' or '') + if not 'features' in kw: + kw['features'] = [kw['compile_mode']] + if not 'execute' in kw: + kw['execute'] = False + if not 'okmsg' in kw: + kw['okmsg'] = 'yes' + if not 'errmsg' in kw: + kw['errmsg'] = 'no !' + +def try_compile(self, kw): + self.start_msg(kw["msg"]) + ret = None + try: + ret = self.run_c_code(**kw) + except self.errors.ConfigurationError as e: + self.end_msg(kw['errmsg'], 'YELLOW') + if Logs.verbose > 1: + raise + else: + self.fatal('The configuration failed') + else: + kw['success'] = ret + self.end_msg(self.ret_msg(kw['okmsg'], kw)) + +@waflib.Configure.conf +def check_header(self, header_name, **kw): + code = """ +%s + +int main() +{ +} +""" % to_header({"header_name": header_name}) + + kw["code"] = code + kw["define_comment"] = "/* Define to 1 if you have the `%s' header. */" % header_name + kw["define_name"] = "HAVE_%s" % sanitize_string(header_name) + if not "features" in kw: + kw["features"] = ["c"] + kw["msg"] = "Checking for header %r" % header_name + + validate_arguments(self, kw) + try_compile(self, kw) + ret = kw["success"] + if ret == 0: + kw["define_value"] = 1 + else: + kw["define_value"] = 0 + + self.post_check(**kw) + if not kw.get('execute', False): + return ret == 0 + return ret + +@waflib.Configure.conf +def check_declaration(self, symbol, **kw): + code = r""" +int main() +{ +#ifndef %s + (void) %s; +#endif + ; + return 0; +} +""" % (symbol, symbol) + + kw["code"] = to_header(kw) + code + kw["msg"] = "Checking for macro %r" % symbol + kw["errmsg"] = "not found" + kw["okmsg"] = "yes" + + validate_arguments(self, kw) + try_compile(self, kw) + ret = kw["success"] + + kw["define_name"] = "HAVE_DECL_%s" % sanitize_string(symbol) + kw["define_comment"] = "/* Set to 1 if %s is defined. */" % symbol + self.post_check(**kw) + if not kw.get('execute', False): + return ret == 0 + return ret + +@waflib.Configure.conf +def check_type(self, type_name, **kw): + code = r""" +int main() { + if ((%(type_name)s *) 0) + return 0; + if (sizeof (%(type_name)s)) + return 0; +} +""" % {"type_name": type_name} + + kw["code"] = to_header(kw) + code + kw["msg"] = "Checking for type %r" % type_name + kw["errmsg"] = "not found" + kw["okmsg"] = "yes" + + validate_arguments(self, kw) + try_compile(self, kw) + ret = kw["success"] + if ret == 0: + kw["define_value"] = 1 + else: + kw["define_value"] = 0 + + kw["define_name"] = "HAVE_%s" % sanitize_string(type_name) + kw["define_comment"] = "/* Set to 1 if %s is defined. */" % type_name + self.post_check(**kw) + if not kw.get('execute', False): + return ret == 0 + return ret + +def do_binary_search(conf, type_name, kw): + code = """\ +typedef %(type)s waf_check_sizeof_type; +int main () +{ + static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) >= 0)]; + test_array [0] = 0 + + ; + return 0; +} +""" % {"type": type_name} + kw["code"] = to_header(kw) + code + + try: + conf.run_c_code(**kw) + except conf.errors.ConfigurationError, e: + conf.end_msg("failed !") + if waflib.Logs.verbose > 1: + raise + else: + conf.fatal("The configuration failed !") + + body = r""" +typedef %(type)s waf_check_sizeof_type; +int main () +{ + static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) <= %(size)s)]; + test_array [0] = 0 + + ; + return 0; +} +""" + # The principle is simple: we first find low and high bounds + # of size for the type, where low/high are looked up on a log + # scale. Then, we do a binary search to find the exact size + # between low and high + low = 0 + mid = 0 + while True: + try: + kw["code"] = to_header(kw) + body % {"type": type_name, "size": mid} + validate_arguments(conf, kw) + conf.run_c_code(**kw) + break + except conf.errors.ConfigurationError: + #log.info("failure to test for bound %d" % mid) + low = mid + 1 + mid = 2 * mid + 1 + + high = mid + ret = None + # Binary search: + while low != high: + mid = (high - low) / 2 + low + try: + kw["code"] = to_header(kw) + body % {"type": type_name, "size": mid} + validate_arguments(conf, kw) + ret = conf.run_c_code(**kw) + high = mid + except conf.errors.ConfigurationError: + low = mid + 1 + + return low + +@waflib.Configure.conf +def check_type_size(conf, type_name, expected_sizes=None, **kw): + kw["define_name"] = "SIZEOF_%s" % sanitize_string(type_name) + kw["define_comment"] = "/* The size of `%s', as computed by sizeof. */" % type_name + kw["msg"] = "Checking sizeof(%s)" % type_name + + validate_arguments(conf, kw) + conf.start_msg(kw["msg"]) + + if expected_sizes is not None: + try: + val = int(expected_sizes) + except TypeError: + values = expected_sizes + else: + values = [val] + + size = None + for value in values: + code = """\ + typedef %(type)s waf_check_sizeof_type; + int main () + { + static int test_array [1 - 2 * !(((long) (sizeof (waf_check_sizeof_type))) == %(size)d)]; + test_array [0] = 0 + + ; + return 0; + } + """ % {"type": type_name, "size": value} + kw["code"] = to_header(kw) + code + try: + conf.run_c_code(**kw) + size = value + break + except conf.errors.ConfigurationError: + pass + if size is None: + size = do_binary_search(conf, type_name, kw) + else: + size = do_binary_search(conf, type_name, kw) + + kw["define_value"] = size + kw["success"] = 0 + conf.end_msg(size) + conf.post_check(**kw) + return size + +@waflib.Configure.conf +def check_functions_at_once(self, funcs, **kw): + header = [] + header = ['#ifdef __cplusplus'] + header.append('extern "C" {') + header.append('#endif') + for f in funcs: + header.append("\tchar %s();" % f) + # Handle MSVC intrinsics: force MS compiler to make a function + # call. Useful to test for some functions when built with + # optimization on, to avoid build error because the intrinsic + # and our 'fake' test declaration do not match. + header.append("#ifdef _MSC_VER") + header.append("#pragma function(%s)" % f) + header.append("#endif") + header.append('#ifdef __cplusplus') + header.append('};') + header.append('#endif') + funcs_decl = "\n".join(header) + + tmp = [] + for f in funcs: + tmp.append("\t%s();" % f) + tmp = "\n".join(tmp) + + code = r""" +%(include)s +%(funcs_decl)s + +int main (void) +{ + %(tmp)s + return 0; +} +""" % {"tmp": tmp, "include": to_header(kw), "funcs_decl": funcs_decl} + kw["code"] = code + if not "features" in kw: + kw["features"] = ["c", "cprogram"] + + msg = ", ".join(funcs) + if len(msg) > 30: + _funcs = list(funcs) + msg = [] + while len(", ".join(msg)) < 30 and _funcs: + msg.append(_funcs.pop(0)) + msg = ", ".join(msg) + ",..." + if "lib" in kw: + kw["msg"] = "Checking for functions %s in library %r" % (msg, kw["lib"]) + else: + kw["msg"] = "Checking for functions %s" % msg + + validate_arguments(self, kw) + try_compile(self, kw) + ret = kw["success"] + + # We set the config.h define here because we need to define several of them + # in one shot + if ret == 0: + for f in funcs: + self.define_with_comment("HAVE_%s" % sanitize_string(f), 1, + "/* Define to 1 if you have the `%s' function */" % f) + + self.post_check(**kw) + if not kw.get('execute', False): + return ret == 0 + return ret + +@waflib.Configure.conf +def check_inline(conf, **kw): + validate_arguments(conf, kw) + + code = """ +#ifndef __cplusplus +static %(inline)s int static_func (void) +{ + return 0; +} +%(inline)s int nostatic_func (void) +{ + return 0; +} +#endif""" + + conf.start_msg("Checking for inline support") + inline = None + for k in ['inline', '__inline__', '__inline']: + try: + kw["code"] = code % {"inline": k} + ret = conf.run_c_code(**kw) + inline = k + break + except conf.errors.ConfigurationError: + pass + + if inline is None: + conf.end_msg("failed", 'YELLOW') + if Logs.verbose > 1: + raise + else: + conf.fatal('The configuration failed') + else: + kw['success'] = ret + conf.end_msg(inline) + return inline + +@waflib.Configure.conf +def post_check(self, *k, **kw): + "set the variables after a test was run successfully" + + is_success = 0 + if kw['execute']: + if kw['success'] is not None: + is_success = kw['success'] + else: + is_success = (kw['success'] == 0) + + def define_or_stuff(): + nm = kw['define_name'] + cmt = kw.get('define_comment', None) + value = kw.get("define_value", is_success) + if kw['execute'] and kw.get('define_ret', None) and isinstance(is_success, str): + self.define_with_comment(kw['define_name'], value, cmt, quote=kw.get('quote', 1)) + else: + self.define_cond(kw['define_name'], value, cmt) + + if 'define_name' in kw: + define_or_stuff() + + if is_success and 'uselib_store' in kw: + from waflib.Tools import ccroot + + # TODO see get_uselib_vars from ccroot.py + _vars = set([]) + for x in kw['features']: + if x in ccroot.USELIB_VARS: + _vars |= ccroot.USELIB_VARS[x] + + for k in _vars: + lk = k.lower() + if k == 'INCLUDES': lk = 'includes' + if k == 'DEFKEYS': 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) + return is_success + +@waflib.Configure.conf +def define_with_comment(conf, define, value, comment=None, quote=True): + if comment is None: + return conf.define(define, value, quote) + + assert define and isinstance(define, str) + + comment_tbl = conf.env[DEFINE_COMMENTS] or {} + comment_tbl[define] = comment + conf.env[DEFINE_COMMENTS] = comment_tbl + + return conf.define(define, value, quote) + +@waflib.Configure.conf +def get_comment(self, key): + assert key and isinstance(key, str) + + if key in self.env[DEFINE_COMMENTS]: + return self.env[DEFINE_COMMENTS][key] + return None + +@waflib.Configure.conf +def define_cond(self, name, value, comment): + """Conditionally define a name. + Formally equivalent to: if value: define(name, 1) else: undefine(name)""" + if value: + self.define_with_comment(name, value, comment) + else: + self.undefine(name) + +@waflib.Configure.conf +def get_config_header(self, defines=True, headers=False): + """ + Create the contents of a ``config.h`` file from the defines and includes + set in conf.env.define_key / conf.env.include_key. No include guards are added. + + :param defines: write the defines values + :type defines: bool + :param headers: write the headers + :type headers: bool + :return: the contents of a ``config.h`` file + :rtype: string + """ + tpl = self.env["CONFIG_HEADER_TEMPLATE"] or "%(content)s" + + lst = [] + if headers: + for x in self.env[INCKEYS]: + lst.append('#include <%s>' % x) + + if defines: + for x in self.env[DEFKEYS]: + if self.is_defined(x): + val = self.get_define(x) + cmt = self.get_comment(x) + if cmt is not None: + lst.append(cmt) + lst.append('#define %s %s\n' % (x, val)) + else: + lst.append('/* #undef %s */\n' % x) + return tpl % {"content": "\n".join(lst)} |