|
|
|
@ -348,35 +348,32 @@ class CLikeCompiler(Compiler): |
|
|
|
|
def check_header(self, hname: str, prefix: str, env: 'Environment', *, |
|
|
|
|
extra_args: T.Optional[T.List[str]] = None, |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: |
|
|
|
|
fargs = {'prefix': prefix, 'header': hname} |
|
|
|
|
code = '''{prefix} |
|
|
|
|
#include <{header}>''' |
|
|
|
|
return self.compiles(code.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
code = f'''{prefix} |
|
|
|
|
#include <{hname}>''' |
|
|
|
|
return self.compiles(code, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
|
|
|
|
|
def has_header(self, hname: str, prefix: str, env: 'Environment', *, |
|
|
|
|
extra_args: T.Optional[T.List[str]] = None, |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']] = None, |
|
|
|
|
disable_cache: bool = False) -> T.Tuple[bool, bool]: |
|
|
|
|
fargs = {'prefix': prefix, 'header': hname} |
|
|
|
|
code = '''{prefix} |
|
|
|
|
code = f'''{prefix} |
|
|
|
|
#ifdef __has_include |
|
|
|
|
#if !__has_include("{header}") |
|
|
|
|
#error "Header '{header}' could not be found" |
|
|
|
|
#if !__has_include("{hname}") |
|
|
|
|
#error "Header '{hname}' could not be found" |
|
|
|
|
#endif |
|
|
|
|
#else |
|
|
|
|
#include <{header}> |
|
|
|
|
#include <{hname}> |
|
|
|
|
#endif''' |
|
|
|
|
return self.compiles(code.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
return self.compiles(code, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies, mode='preprocess', disable_cache=disable_cache) |
|
|
|
|
|
|
|
|
|
def has_header_symbol(self, hname: str, symbol: str, prefix: str, |
|
|
|
|
env: 'Environment', *, |
|
|
|
|
extra_args: T.Optional[T.List[str]] = None, |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: |
|
|
|
|
fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol} |
|
|
|
|
t = '''{prefix} |
|
|
|
|
#include <{header}> |
|
|
|
|
t = f'''{prefix} |
|
|
|
|
#include <{hname}> |
|
|
|
|
int main(void) {{ |
|
|
|
|
/* If it's not defined as a macro, try to use as a symbol */ |
|
|
|
|
#ifndef {symbol} |
|
|
|
@ -384,7 +381,7 @@ class CLikeCompiler(Compiler): |
|
|
|
|
#endif |
|
|
|
|
return 0; |
|
|
|
|
}}''' |
|
|
|
|
return self.compiles(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
return self.compiles(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
|
|
|
|
|
def _get_basic_compiler_args(self, env: 'Environment', mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]: |
|
|
|
@ -499,11 +496,10 @@ class CLikeCompiler(Compiler): |
|
|
|
|
def _compile_int(self, expression: str, prefix: str, env: 'Environment', |
|
|
|
|
extra_args: T.Optional[T.List[str]], |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']]) -> bool: |
|
|
|
|
fargs = {'prefix': prefix, 'expression': expression} |
|
|
|
|
t = '''#include <stdio.h> |
|
|
|
|
t = f'''#include <stdio.h> |
|
|
|
|
{prefix} |
|
|
|
|
int main(void) {{ static int a[1-2*!({expression})]; a[0]=0; return 0; }}''' |
|
|
|
|
return self.compiles(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
return self.compiles(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies)[0] |
|
|
|
|
|
|
|
|
|
def cross_compute_int(self, expression: str, low: T.Optional[int], high: T.Optional[int], |
|
|
|
@ -565,14 +561,13 @@ class CLikeCompiler(Compiler): |
|
|
|
|
extra_args = [] |
|
|
|
|
if self.is_cross: |
|
|
|
|
return self.cross_compute_int(expression, low, high, guess, prefix, env, extra_args, dependencies) |
|
|
|
|
fargs = {'prefix': prefix, 'expression': expression} |
|
|
|
|
t = '''#include<stdio.h> |
|
|
|
|
t = f'''#include<stdio.h> |
|
|
|
|
{prefix} |
|
|
|
|
int main(void) {{ |
|
|
|
|
printf("%ld\\n", (long)({expression})); |
|
|
|
|
return 0; |
|
|
|
|
}};''' |
|
|
|
|
res = self.run(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
res = self.run(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
if not res.compiled: |
|
|
|
|
return -1 |
|
|
|
@ -585,14 +580,13 @@ class CLikeCompiler(Compiler): |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']] = None) -> int: |
|
|
|
|
if extra_args is None: |
|
|
|
|
extra_args = [] |
|
|
|
|
fargs = {'prefix': prefix, 'type': typename} |
|
|
|
|
t = '''#include <stdio.h> |
|
|
|
|
t = f'''#include <stdio.h> |
|
|
|
|
{prefix} |
|
|
|
|
int main(void) {{ |
|
|
|
|
{type} something; |
|
|
|
|
{typename} something; |
|
|
|
|
return 0; |
|
|
|
|
}}''' |
|
|
|
|
if not self.compiles(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
if not self.compiles(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies)[0]: |
|
|
|
|
return -1 |
|
|
|
|
return self.cross_compute_int('sizeof(%s)' % typename, None, None, None, prefix, env, extra_args, dependencies) |
|
|
|
@ -602,17 +596,16 @@ class CLikeCompiler(Compiler): |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']] = None) -> int: |
|
|
|
|
if extra_args is None: |
|
|
|
|
extra_args = [] |
|
|
|
|
fargs = {'prefix': prefix, 'type': typename} |
|
|
|
|
if self.is_cross: |
|
|
|
|
return self.cross_sizeof(typename, prefix, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
t = '''#include<stdio.h> |
|
|
|
|
t = f'''#include<stdio.h> |
|
|
|
|
{prefix} |
|
|
|
|
int main(void) {{ |
|
|
|
|
printf("%ld\\n", (long)(sizeof({type}))); |
|
|
|
|
printf("%ld\\n", (long)(sizeof({typename}))); |
|
|
|
|
return 0; |
|
|
|
|
}};''' |
|
|
|
|
res = self.run(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
res = self.run(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
if not res.compiled: |
|
|
|
|
return -1 |
|
|
|
@ -625,23 +618,22 @@ class CLikeCompiler(Compiler): |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']] = None) -> int: |
|
|
|
|
if extra_args is None: |
|
|
|
|
extra_args = [] |
|
|
|
|
fargs = {'prefix': prefix, 'type': typename} |
|
|
|
|
t = '''#include <stdio.h> |
|
|
|
|
t = f'''#include <stdio.h> |
|
|
|
|
{prefix} |
|
|
|
|
int main(void) {{ |
|
|
|
|
{type} something; |
|
|
|
|
{typename} something; |
|
|
|
|
return 0; |
|
|
|
|
}}''' |
|
|
|
|
if not self.compiles(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
if not self.compiles(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies)[0]: |
|
|
|
|
return -1 |
|
|
|
|
t = '''#include <stddef.h> |
|
|
|
|
t = f'''#include <stddef.h> |
|
|
|
|
{prefix} |
|
|
|
|
struct tmp {{ |
|
|
|
|
char c; |
|
|
|
|
{type} target; |
|
|
|
|
{typename} target; |
|
|
|
|
}};''' |
|
|
|
|
return self.cross_compute_int('offsetof(struct tmp, target)', None, None, None, t.format(**fargs), env, extra_args, dependencies) |
|
|
|
|
return self.cross_compute_int('offsetof(struct tmp, target)', None, None, None, t, env, extra_args, dependencies) |
|
|
|
|
|
|
|
|
|
def alignment(self, typename: str, prefix: str, env: 'Environment', *, |
|
|
|
|
extra_args: T.Optional[T.List[str]] = None, |
|
|
|
@ -651,19 +643,18 @@ class CLikeCompiler(Compiler): |
|
|
|
|
if self.is_cross: |
|
|
|
|
return self.cross_alignment(typename, prefix, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
fargs = {'prefix': prefix, 'type': typename} |
|
|
|
|
t = '''#include <stdio.h> |
|
|
|
|
t = f'''#include <stdio.h> |
|
|
|
|
#include <stddef.h> |
|
|
|
|
{prefix} |
|
|
|
|
struct tmp {{ |
|
|
|
|
char c; |
|
|
|
|
{type} target; |
|
|
|
|
{typename} target; |
|
|
|
|
}}; |
|
|
|
|
int main(void) {{ |
|
|
|
|
printf("%d", (int)offsetof(struct tmp, target)); |
|
|
|
|
return 0; |
|
|
|
|
}}''' |
|
|
|
|
res = self.run(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
res = self.run(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
if not res.compiled: |
|
|
|
|
raise mesonlib.EnvironmentException('Could not compile alignment test.') |
|
|
|
@ -679,18 +670,17 @@ class CLikeCompiler(Compiler): |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']], |
|
|
|
|
disable_cache: bool = False) -> T.Tuple[str, bool]: |
|
|
|
|
delim = '"MESON_GET_DEFINE_DELIMITER"' |
|
|
|
|
fargs = {'prefix': prefix, 'define': dname, 'delim': delim} |
|
|
|
|
code = ''' |
|
|
|
|
code = f''' |
|
|
|
|
{prefix} |
|
|
|
|
#ifndef {define} |
|
|
|
|
# define {define} |
|
|
|
|
#ifndef {dname} |
|
|
|
|
# define {dname} |
|
|
|
|
#endif |
|
|
|
|
{delim}\n{define}''' |
|
|
|
|
{delim}\n{dname}''' |
|
|
|
|
args = self.build_wrapper_args(env, extra_args, dependencies, |
|
|
|
|
mode=CompileCheckMode.PREPROCESS).to_native() |
|
|
|
|
func = functools.partial(self.cached_compile, code.format(**fargs), env.coredata, extra_args=args, mode='preprocess') |
|
|
|
|
func = functools.partial(self.cached_compile, code, env.coredata, extra_args=args, mode='preprocess') |
|
|
|
|
if disable_cache: |
|
|
|
|
func = functools.partial(self.compile, code.format(**fargs), extra_args=args, mode='preprocess', temp_dir=env.scratch_dir) |
|
|
|
|
func = functools.partial(self.compile, code, extra_args=args, mode='preprocess', temp_dir=env.scratch_dir) |
|
|
|
|
with func() as p: |
|
|
|
|
cached = p.cached |
|
|
|
|
if p.returncode != 0: |
|
|
|
@ -713,25 +703,24 @@ class CLikeCompiler(Compiler): |
|
|
|
|
cast = '(long long int)' |
|
|
|
|
else: |
|
|
|
|
raise AssertionError(f'BUG: Unknown return type {rtype!r}') |
|
|
|
|
fargs = {'prefix': prefix, 'f': fname, 'cast': cast, 'fmt': fmt} |
|
|
|
|
code = '''{prefix} |
|
|
|
|
code = f'''{prefix} |
|
|
|
|
#include <stdio.h> |
|
|
|
|
int main(void) {{ |
|
|
|
|
printf ("{fmt}", {cast} {f}()); |
|
|
|
|
printf ("{fmt}", {cast} {fname}()); |
|
|
|
|
return 0; |
|
|
|
|
}}'''.format(**fargs) |
|
|
|
|
}}''' |
|
|
|
|
res = self.run(code, env, extra_args=extra_args, dependencies=dependencies) |
|
|
|
|
if not res.compiled: |
|
|
|
|
m = 'Could not get return value of {}()' |
|
|
|
|
raise mesonlib.EnvironmentException(m.format(fname)) |
|
|
|
|
m = f'Could not get return value of {fname}()' |
|
|
|
|
raise mesonlib.EnvironmentException(m) |
|
|
|
|
if rtype == 'string': |
|
|
|
|
return res.stdout |
|
|
|
|
elif rtype == 'int': |
|
|
|
|
try: |
|
|
|
|
return int(res.stdout.strip()) |
|
|
|
|
except ValueError: |
|
|
|
|
m = 'Return value of {}() is not an int' |
|
|
|
|
raise mesonlib.EnvironmentException(m.format(fname)) |
|
|
|
|
m = f'Return value of {fname}() is not an int' |
|
|
|
|
raise mesonlib.EnvironmentException(m) |
|
|
|
|
assert False, 'Unreachable' |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
@ -896,28 +885,25 @@ class CLikeCompiler(Compiler): |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: |
|
|
|
|
if extra_args is None: |
|
|
|
|
extra_args = [] |
|
|
|
|
fargs = {'prefix': prefix, 'type': typename, 'name': 'foo'} |
|
|
|
|
# Create code that accesses all members |
|
|
|
|
members = '' |
|
|
|
|
for member in membernames: |
|
|
|
|
members += '{}.{};\n'.format(fargs['name'], member) |
|
|
|
|
fargs['members'] = members |
|
|
|
|
t = '''{prefix} |
|
|
|
|
members += f'foo.{member};\n' |
|
|
|
|
t = f'''{prefix} |
|
|
|
|
void bar(void) {{ |
|
|
|
|
{type} {name}; |
|
|
|
|
{typename} foo; |
|
|
|
|
{members} |
|
|
|
|
}};''' |
|
|
|
|
return self.compiles(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
return self.compiles(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
|
|
|
|
|
def has_type(self, typename: str, prefix: str, env: 'Environment', extra_args: T.List[str], |
|
|
|
|
dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: |
|
|
|
|
fargs = {'prefix': prefix, 'type': typename} |
|
|
|
|
t = '''{prefix} |
|
|
|
|
t = f'''{prefix} |
|
|
|
|
void bar(void) {{ |
|
|
|
|
sizeof({type}); |
|
|
|
|
sizeof({typename}); |
|
|
|
|
}};''' |
|
|
|
|
return self.compiles(t.format(**fargs), env, extra_args=extra_args, |
|
|
|
|
return self.compiles(t, env, extra_args=extra_args, |
|
|
|
|
dependencies=dependencies) |
|
|
|
|
|
|
|
|
|
def symbols_have_underscore_prefix(self, env: 'Environment') -> bool: |
|
|
|
@ -937,11 +923,11 @@ class CLikeCompiler(Compiler): |
|
|
|
|
n = 'symbols_have_underscore_prefix' |
|
|
|
|
with self._build_wrapper(code, env, extra_args=args, mode='compile', want_output=True, temp_dir=env.scratch_dir) as p: |
|
|
|
|
if p.returncode != 0: |
|
|
|
|
m = 'BUG: Unable to compile {!r} check: {}' |
|
|
|
|
raise RuntimeError(m.format(n, p.stdout)) |
|
|
|
|
m = f'BUG: Unable to compile {n!r} check: {p.stdout}' |
|
|
|
|
raise RuntimeError(m) |
|
|
|
|
if not os.path.isfile(p.output_name): |
|
|
|
|
m = 'BUG: Can\'t find compiled test code for {!r} check' |
|
|
|
|
raise RuntimeError(m.format(n)) |
|
|
|
|
m = f'BUG: Can\'t find compiled test code for {n!r} check' |
|
|
|
|
raise RuntimeError(m) |
|
|
|
|
with open(p.output_name, 'rb') as o: |
|
|
|
|
for line in o: |
|
|
|
|
# Check if the underscore form of the symbol is somewhere |
|
|
|
@ -1065,8 +1051,7 @@ class CLikeCompiler(Compiler): |
|
|
|
|
if archs and env.machines.host.cpu_family in archs: |
|
|
|
|
return p |
|
|
|
|
else: |
|
|
|
|
mlog.debug('Rejected {}, supports {} but need {}' |
|
|
|
|
.format(p, archs, env.machines.host.cpu_family)) |
|
|
|
|
mlog.debug(f'Rejected {p}, supports {archs} but need {env.machines.host.cpu_family}') |
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
@functools.lru_cache() |
|
|
|
@ -1236,14 +1221,13 @@ class CLikeCompiler(Compiler): |
|
|
|
|
if arg.startswith('-Wno-'): |
|
|
|
|
new_args.append('-W' + arg[5:]) |
|
|
|
|
if arg.startswith('-Wl,'): |
|
|
|
|
mlog.warning('{} looks like a linker argument, ' |
|
|
|
|
mlog.warning(f'{arg} looks like a linker argument, ' |
|
|
|
|
'but has_argument and other similar methods only ' |
|
|
|
|
'support checking compiler arguments. Using them ' |
|
|
|
|
'to check linker arguments are never supported, ' |
|
|
|
|
'and results are likely to be wrong regardless of ' |
|
|
|
|
'the compiler you are using. has_link_argument or ' |
|
|
|
|
'other similar method can be used instead.' |
|
|
|
|
.format(arg)) |
|
|
|
|
'other similar method can be used instead.') |
|
|
|
|
new_args.append(arg) |
|
|
|
|
return self.has_arguments(new_args, env, code, mode='compile') |
|
|
|
|
|
|
|
|
|