aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers.py
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.com>2016-04-07 20:19:52 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2016-04-07 20:53:12 +0530
commit1934ddfc5b21d3dd2bb16dfeae67605e11808bdf (patch)
treee08a5854ca1b6fc8e226669f11c8d27e01eb94df /mesonbuild/compilers.py
parent700010e452517d0a0b11e8e460d65b257a449302 (diff)
downloadmeson-1934ddfc5b21d3dd2bb16dfeae67605e11808bdf.zip
meson-1934ddfc5b21d3dd2bb16dfeae67605e11808bdf.tar.gz
meson-1934ddfc5b21d3dd2bb16dfeae67605e11808bdf.tar.bz2
Improve cc.has_function() check to not require any includes and detect stubs
We now use .links() to detect if a C compiler function is available or not, that way the user doesn't need to specify all the possible includes for the check, which simplifies things considerably. Also detect glibc stub functions that will never work and return false for them. Closes #437
Diffstat (limited to 'mesonbuild/compilers.py')
-rw-r--r--mesonbuild/compilers.py46
1 files changed, 36 insertions, 10 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 229d224..0a4473b 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -647,15 +647,41 @@ int main(int argc, char **argv) {
return align
def has_function(self, funcname, prefix, env, extra_args=[]):
- # This fails (returns true) if funcname is a ptr or a variable.
- # The correct check is a lot more difficult.
- # Fix this to do that eventually.
- templ = '''%s
-int main(int argc, char **argv) {
- void *ptr = (void*)(%s);
- return 0;
-};
-'''
+ # Define the symbol to something else in case it is defined by the
+ # includes or defines listed by the user `{0}` or by the compiler.
+ # Then, undef the symbol to get rid of it completely.
+ templ = '''
+ #define {1} meson_disable_define_of_{1}
+ {0}
+ #undef {1}
+ '''
+
+ # Override any GCC internal prototype and declare our own definition for
+ # the symbol. Use char because that's unlikely to be an actual return
+ # value for a function which ensures that we override the definition.
+ templ += '''
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ char {1} ();
+ '''
+
+ # glibc defines functions that are not available on Linux as stubs that
+ # fail with ENOSYS (such as e.g. lchmod). In this case we want to fail
+ # instead of detecting the stub as a valid symbol.
+ templ += '''
+ #if defined __stub_{1} || defined __stub___{1}
+ fail fail fail this function is not going to work
+ #endif
+ '''
+
+ # And finally the actual function call
+ templ += '''
+ int
+ main ()
+ {{
+ return {1} ();
+ }}'''
varname = 'has function ' + funcname
varname = varname.replace(' ', '_')
if self.is_cross:
@@ -664,7 +690,7 @@ int main(int argc, char **argv) {
if isinstance(val, bool):
return val
raise EnvironmentException('Cross variable {0} is not a boolean.'.format(varname))
- return self.compiles(templ % (prefix, funcname), extra_args)
+ return self.links(templ.format(prefix, funcname), extra_args)
def has_member(self, typename, membername, prefix, extra_args=[]):
templ = '''%s