|
|
@ -260,6 +260,9 @@ class Compiler(): |
|
|
|
def has_header(self, *args, **kwargs): |
|
|
|
def has_header(self, *args, **kwargs): |
|
|
|
raise EnvironmentException('Language %s does not support header checks.' % self.language) |
|
|
|
raise EnvironmentException('Language %s does not support header checks.' % self.language) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def has_header_symbol(self, *args, **kwargs): |
|
|
|
|
|
|
|
raise EnvironmentException('Language %s does not support header symbol checks.' % self.language) |
|
|
|
|
|
|
|
|
|
|
|
def compiles(self, *args, **kwargs): |
|
|
|
def compiles(self, *args, **kwargs): |
|
|
|
raise EnvironmentException('Language %s does not support compile checks.' % self.language) |
|
|
|
raise EnvironmentException('Language %s does not support compile checks.' % self.language) |
|
|
|
|
|
|
|
|
|
|
@ -349,6 +352,9 @@ class CCompiler(Compiler): |
|
|
|
def get_compile_only_args(self): |
|
|
|
def get_compile_only_args(self): |
|
|
|
return ['-c'] |
|
|
|
return ['-c'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_no_optimization_args(self): |
|
|
|
|
|
|
|
return ['-O0'] |
|
|
|
|
|
|
|
|
|
|
|
def get_output_args(self, target): |
|
|
|
def get_output_args(self, target): |
|
|
|
return ['-o', target] |
|
|
|
return ['-o', target] |
|
|
|
|
|
|
|
|
|
|
@ -462,6 +468,14 @@ int someSymbolHereJustForFun; |
|
|
|
''' |
|
|
|
''' |
|
|
|
return self.compiles(templ % hname, extra_args) |
|
|
|
return self.compiles(templ % hname, extra_args) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def has_header_symbol(self, hname, symbol, prefix, extra_args=[]): |
|
|
|
|
|
|
|
templ = '''{2} |
|
|
|
|
|
|
|
#include <{0}> |
|
|
|
|
|
|
|
int main () {{ {1}; }}''' |
|
|
|
|
|
|
|
# Pass -O0 to ensure that the symbol isn't optimized away |
|
|
|
|
|
|
|
extra_args += self.get_no_optimization_args() |
|
|
|
|
|
|
|
return self.compiles(templ.format(hname, symbol, prefix), extra_args) |
|
|
|
|
|
|
|
|
|
|
|
def compile(self, code, srcname, extra_args=[]): |
|
|
|
def compile(self, code, srcname, extra_args=[]): |
|
|
|
commands = self.get_exelist() |
|
|
|
commands = self.get_exelist() |
|
|
|
commands.append(srcname) |
|
|
|
commands.append(srcname) |
|
|
@ -639,15 +653,41 @@ int main(int argc, char **argv) { |
|
|
|
return align |
|
|
|
return align |
|
|
|
|
|
|
|
|
|
|
|
def has_function(self, funcname, prefix, env, extra_args=[]): |
|
|
|
def has_function(self, funcname, prefix, env, extra_args=[]): |
|
|
|
# This fails (returns true) if funcname is a ptr or a variable. |
|
|
|
# Define the symbol to something else in case it is defined by the |
|
|
|
# The correct check is a lot more difficult. |
|
|
|
# includes or defines listed by the user `{0}` or by the compiler. |
|
|
|
# Fix this to do that eventually. |
|
|
|
# Then, undef the symbol to get rid of it completely. |
|
|
|
templ = '''%s |
|
|
|
templ = ''' |
|
|
|
int main(int argc, char **argv) { |
|
|
|
#define {1} meson_disable_define_of_{1} |
|
|
|
void *ptr = (void*)(%s); |
|
|
|
{0} |
|
|
|
return 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 = 'has function ' + funcname |
|
|
|
varname = varname.replace(' ', '_') |
|
|
|
varname = varname.replace(' ', '_') |
|
|
|
if self.is_cross: |
|
|
|
if self.is_cross: |
|
|
@ -656,7 +696,15 @@ int main(int argc, char **argv) { |
|
|
|
if isinstance(val, bool): |
|
|
|
if isinstance(val, bool): |
|
|
|
return val |
|
|
|
return val |
|
|
|
raise EnvironmentException('Cross variable {0} is not a boolean.'.format(varname)) |
|
|
|
raise EnvironmentException('Cross variable {0} is not a boolean.'.format(varname)) |
|
|
|
return self.compiles(templ % (prefix, funcname), extra_args) |
|
|
|
if self.links(templ.format(prefix, funcname), extra_args): |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
# Some functions like alloca() are defined as compiler built-ins which |
|
|
|
|
|
|
|
# are inlined by the compiler, so test for that instead. Built-ins are |
|
|
|
|
|
|
|
# special functions that ignore all includes and defines, so we just |
|
|
|
|
|
|
|
# directly try to link via main(). |
|
|
|
|
|
|
|
# Add -O0 to ensure that the symbol isn't optimized away by the compiler |
|
|
|
|
|
|
|
extra_args += self.get_no_optimization_args() |
|
|
|
|
|
|
|
return self.links('int main() {{ {0}; }}'.format('__builtin_' + funcname), extra_args) |
|
|
|
|
|
|
|
|
|
|
|
def has_member(self, typename, membername, prefix, extra_args=[]): |
|
|
|
def has_member(self, typename, membername, prefix, extra_args=[]): |
|
|
|
templ = '''%s |
|
|
|
templ = '''%s |
|
|
@ -1257,6 +1305,9 @@ class VisualStudioCCompiler(CCompiler): |
|
|
|
def get_compile_only_args(self): |
|
|
|
def get_compile_only_args(self): |
|
|
|
return ['/c'] |
|
|
|
return ['/c'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_no_optimization_args(self): |
|
|
|
|
|
|
|
return ['/Od'] |
|
|
|
|
|
|
|
|
|
|
|
def get_output_args(self, target): |
|
|
|
def get_output_args(self, target): |
|
|
|
if target.endswith('.exe'): |
|
|
|
if target.endswith('.exe'): |
|
|
|
return ['/Fe' + target] |
|
|
|
return ['/Fe' + target] |
|
|
|