diff options
author | Tim-Philipp Müller <tim@centricular.com> | 2016-04-07 20:19:52 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2016-04-07 20:53:12 +0530 |
commit | 1934ddfc5b21d3dd2bb16dfeae67605e11808bdf (patch) | |
tree | e08a5854ca1b6fc8e226669f11c8d27e01eb94df /mesonbuild/compilers.py | |
parent | 700010e452517d0a0b11e8e460d65b257a449302 (diff) | |
download | meson-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.py | 46 |
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 |