diff --git a/demos/c++/wscript b/demos/c++/wscript index ca9d9822..5115c000 100644 --- a/demos/c++/wscript +++ b/demos/c++/wscript @@ -16,6 +16,7 @@ def options(opt): def configure(conf): conf.load('compiler_cxx') conf.check(header_name='stdio.h', features='cxx cxxprogram', mandatory=False) + conf.check_cxx_func('memcpy') def build(bld): bld.shlib(source='a.cpp', target='mylib', vnum='9.8.7') diff --git a/demos/c/wscript b/demos/c/wscript index c02184b0..d0fa6fdf 100644 --- a/demos/c/wscript +++ b/demos/c/wscript @@ -41,6 +41,7 @@ def configure(conf): conf.check(lib='m', cflags='-Wall', defines=['var=foo', 'x=y'], uselib_store='M', mandatory=False) conf.check_large_file(mandatory=False) conf.check_inline() + conf.check_c_func('memcpy') endianness = conf.check_endianness() conf.define_cond("BIG_ENDIAN", endianness == "big") diff --git a/docs/sphinx/confmap.rst b/docs/sphinx/confmap.rst index 5832d1a8..b34d2c98 100644 --- a/docs/sphinx/confmap.rst +++ b/docs/sphinx/confmap.rst @@ -33,6 +33,10 @@ Configuration methods * check_ +.. _check_c_func: tools/c_config.html#waflib.Tools.c_config.check_c_func + +* check_c_func_ + .. _check_cc: tools/c_config.html#waflib.Tools.c_config.check_cc * check_cc_ @@ -45,6 +49,10 @@ Configuration methods * check_cxx_ +.. _check_cxx_func: tools/c_config.html#waflib.Tools.c_config.check_cxx_func + +* check_cxx_func_ + .. _check_dlibrary: tools/d_config.html#waflib.Tools.d_config.check_dlibrary * check_dlibrary_ diff --git a/waflib/Tools/c_config.py b/waflib/Tools/c_config.py index 80580cc9..de78cc60 100644 --- a/waflib/Tools/c_config.py +++ b/waflib/Tools/c_config.py @@ -26,6 +26,32 @@ int main(int argc, char **argv) { } ''' +CHECK_FUNC_FRAGMENT = ''' +#define func innocuous_func + +#ifdef __STDC__ +#include +#else +#include +#endif + +#undef func + +#ifdef __cplusplus +extern "C" +#endif +char func(); + +#if defined __stub_func || defined __stub___func +#error "stub only" +#endif + +int main(int argc, char **argv) { + (void)argc; (void)argv; + return func(); +} +''' + MACRO_TO_DESTOS = { '__linux__' : 'linux', '__GNU__' : 'gnu', # hurd @@ -709,6 +735,56 @@ def check_cc(self, *k, **kw): kw['compiler'] = 'c' return self.check(*k, **kw) +def check_func(function_name, **kw): + kw['define_name'] = 'HAVE_' + function_name.upper() + kw['fragment'] = CHECK_FUNC_FRAGMENT.replace('func', function_name) + kw['msg'] = 'Checking for ' + function_name + return kw; + +@conf +def check_cxx_func(self, function_name, *k, **kw): + """ + Checks whether the library function specified by ``function_name`` + exists. This check is similar to the Autoconf AC_CHECK_FUNCS() macro. + Compiles and links a test program referencing the ``function_name`` + symbol via a function call using the C++ compiler. Defines + ``HAVE_FUNCTION_NAME`` to 1 in the configuration header if the check + was successful, otherwise it is not defined. The check may also + succeed in case the referenced symbol is actually not a function. There + is no need to specify header files to include. This function sets the + ``compiler``, ``define_name``, ``features``, ``fragment``, and ``msg`` + parameters and then calls :py:func:`waflib.Tools.c_config.check` to + carry out the check. + + :param function_name: the name of the function to check + :type function_name: string + """ + kw = check_func(function_name, **kw) + kw['features'] = 'cxx cxxprogram' + return self.check_cxx(*k, **kw) + +@conf +def check_c_func(self, function_name, *k, **kw): + """ + Checks whether the library function specified by ``function_name`` + exists. This check is similar to the Autoconf AC_CHECK_FUNCS() macro. + Compiles and links a test program referencing the ``function_name`` + symbol via a function call using the C compiler. Defines + ``HAVE_FUNCTION_NAME`` to 1 in the configuration header if the check + was successful, otherwise it is not defined. The check may also + succeed in case the referenced symbol is actually not a function. There + is no need to specify header files to include. This function sets the + ``compiler``, ``define_name``, ``features``, ``fragment``, and ``msg`` + parameters and then calls :py:func:`waflib.Tools.c_config.check` to + carry out the check. + + :param function_name: the name of the function to check + :type function_name: string + """ + kw = check_func(function_name, **kw) + kw['features'] = 'c cprogram' + return self.check_cc(*k, **kw) + @conf def set_define_comment(self, key, comment): """