New compiler function: cc.get_define()
Runs the pre-processor and fetches the value of the define. Can find any arbitrary value and returns it as a string.
This commit is contained in:
parent
d0d7cbd88b
commit
de47541e6c
|
@ -906,8 +906,6 @@ class CCompiler(Compiler):
|
|||
return self.sanity_check_impl(work_dir, environment, 'sanitycheckc.c', code)
|
||||
|
||||
def has_header(self, hname, prefix, env, extra_args=None, dependencies=None):
|
||||
if extra_args is None:
|
||||
extra_args = []
|
||||
fargs = {'prefix': prefix, 'header': hname}
|
||||
code = '''{prefix}
|
||||
#ifdef __has_include
|
||||
|
@ -921,8 +919,6 @@ class CCompiler(Compiler):
|
|||
dependencies, 'preprocess')
|
||||
|
||||
def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
|
||||
if extra_args is None:
|
||||
extra_args = []
|
||||
fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol}
|
||||
t = '''{prefix}
|
||||
#include <{header}>
|
||||
|
@ -934,7 +930,7 @@ class CCompiler(Compiler):
|
|||
}}'''
|
||||
return self.compiles(t.format(**fargs), env, extra_args, dependencies)
|
||||
|
||||
def compiles(self, code, env, extra_args=None, dependencies=None, mode='compile'):
|
||||
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
|
||||
if extra_args is None:
|
||||
extra_args = []
|
||||
elif isinstance(extra_args, str):
|
||||
|
@ -943,49 +939,41 @@ class CCompiler(Compiler):
|
|||
dependencies = []
|
||||
elif not isinstance(dependencies, list):
|
||||
dependencies = [dependencies]
|
||||
# Add compile flags needed by dependencies
|
||||
# Collect compiler arguments
|
||||
args = CompilerArgs(self)
|
||||
for d in dependencies:
|
||||
# Add compile flags needed by dependencies
|
||||
args += d.get_compile_args()
|
||||
if mode == 'link':
|
||||
# Add link flags needed to find dependencies
|
||||
args += d.get_link_args()
|
||||
# Select a CRT if needed since we're linking
|
||||
if mode == 'link':
|
||||
args += self.get_linker_debug_crt_args()
|
||||
# Read c_args/cpp_args/etc from the cross-info file (if needed)
|
||||
args += self.get_cross_extra_flags(env, compile=True, link=False)
|
||||
args += self.get_cross_extra_flags(env, compile=(mode != 'preprocess'),
|
||||
link=(mode == 'link'))
|
||||
# Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS from the env
|
||||
# We assume that the user has ensured these are compiler-specific
|
||||
args += env.coredata.external_args[self.language]
|
||||
# Add LDFLAGS from the env. We assume that the user has ensured these
|
||||
# are compiler-specific
|
||||
if mode == 'link':
|
||||
args += env.coredata.external_link_args[self.language]
|
||||
args += self.get_compiler_check_args()
|
||||
# extra_args must override all other arguments, so we add them last
|
||||
args += extra_args
|
||||
return args
|
||||
|
||||
def compiles(self, code, env, extra_args=None, dependencies=None, mode='compile'):
|
||||
args = self._get_compiler_check_args(env, extra_args, dependencies, mode)
|
||||
# We only want to compile; not link
|
||||
with self.compile(code, args.to_native(), mode) as p:
|
||||
return p.returncode == 0
|
||||
|
||||
def _links_wrapper(self, code, env, extra_args, dependencies):
|
||||
"Shares common code between self.links and self.run"
|
||||
if extra_args is None:
|
||||
extra_args = []
|
||||
elif isinstance(extra_args, str):
|
||||
extra_args = [extra_args]
|
||||
if dependencies is None:
|
||||
dependencies = []
|
||||
elif not isinstance(dependencies, list):
|
||||
dependencies = [dependencies]
|
||||
# Add compile and link flags needed by dependencies
|
||||
args = CompilerArgs(self)
|
||||
for d in dependencies:
|
||||
args += d.get_compile_args()
|
||||
args += d.get_link_args()
|
||||
# Select a CRT if needed since we're linking
|
||||
args += self.get_linker_debug_crt_args()
|
||||
# Read c_args/c_link_args/cpp_args/cpp_link_args/etc from the
|
||||
# cross-info file (if needed)
|
||||
args += self.get_cross_extra_flags(env, compile=True, link=True)
|
||||
# Add LDFLAGS from the env. We assume that the user has ensured these
|
||||
# are compiler-specific
|
||||
args += env.coredata.external_link_args[self.language]
|
||||
# Add compiler check args such that they override
|
||||
args += self.get_compiler_check_args()
|
||||
# extra_args must override all other arguments, so we add them last
|
||||
args += extra_args
|
||||
args = self._get_compiler_check_args(env, extra_args, dependencies, mode='link')
|
||||
return self.compile(code, args.to_native())
|
||||
|
||||
def links(self, code, env, extra_args=None, dependencies=None):
|
||||
|
@ -1141,6 +1129,24 @@ class CCompiler(Compiler):
|
|||
raise EnvironmentException('Could not determine alignment of %s. Sorry. You might want to file a bug.' % typename)
|
||||
return align
|
||||
|
||||
def get_define(self, dname, prefix, env, extra_args, dependencies):
|
||||
delim = '"MESON_GET_DEFINE_DELIMITER"'
|
||||
fargs = {'prefix': prefix, 'define': dname, 'delim': delim}
|
||||
code = '''
|
||||
#ifndef {define}
|
||||
# define {define}
|
||||
#endif
|
||||
{prefix}
|
||||
{delim}\n{define}'''
|
||||
args = self._get_compiler_check_args(env, extra_args, dependencies,
|
||||
mode='preprocess').to_native()
|
||||
with self.compile(code.format(**fargs), args, 'preprocess') as p:
|
||||
if p.returncode != 0:
|
||||
raise EnvironmentException('Could not get define {!r}'.format(dname))
|
||||
# Get the preprocessed value after the delimiter,
|
||||
# minus the extra newline at the end
|
||||
return p.stdo.split(delim + '\n')[-1][:-1]
|
||||
|
||||
@staticmethod
|
||||
def _no_prototype_templ():
|
||||
"""
|
||||
|
|
|
@ -634,6 +634,7 @@ class CompilerHolder(InterpreterObject):
|
|||
'get_id': self.get_id_method,
|
||||
'compute_int': self.compute_int_method,
|
||||
'sizeof': self.sizeof_method,
|
||||
'get_define': self.get_define_method,
|
||||
'has_header': self.has_header_method,
|
||||
'has_header_symbol': self.has_header_symbol_method,
|
||||
'run': self.run_method,
|
||||
|
@ -865,6 +866,20 @@ class CompilerHolder(InterpreterObject):
|
|||
mlog.log('Checking for size of "%s": %d' % (element, esize))
|
||||
return esize
|
||||
|
||||
def get_define_method(self, args, kwargs):
|
||||
if len(args) != 1:
|
||||
raise InterpreterException('get_define() takes exactly one argument.')
|
||||
check_stringlist(args)
|
||||
element = args[0]
|
||||
prefix = kwargs.get('prefix', '')
|
||||
if not isinstance(prefix, str):
|
||||
raise InterpreterException('Prefix argument of get_define() must be a string.')
|
||||
extra_args = self.determine_args(kwargs)
|
||||
deps = self.determine_dependencies(kwargs)
|
||||
value = self.compiler.get_define(element, prefix, self.environment, extra_args, deps)
|
||||
mlog.log('Checking for value of define "%s": %s' % (element, value))
|
||||
return value
|
||||
|
||||
def compiles_method(self, args, kwargs):
|
||||
if len(args) != 1:
|
||||
raise InterpreterException('compiles method takes exactly one argument.')
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
project('get define', 'c', 'cpp')
|
||||
|
||||
host_system = host_machine.system()
|
||||
|
||||
foreach lang : ['c', 'cpp']
|
||||
cc = meson.get_compiler(lang)
|
||||
if host_system == 'linux'
|
||||
d = cc.get_define('__linux__')
|
||||
assert(d == '1', '__linux__ value is @0@ instead of 1'.format(d))
|
||||
elif host_system == 'darwin'
|
||||
d = cc.get_define('__APPLE__')
|
||||
assert(d == '1', '__APPLE__ value is @0@ instead of 1'.format(d))
|
||||
elif host_system == 'windows'
|
||||
d = cc.get_define('_WIN32')
|
||||
assert(d == '1', '_WIN32 value is @0@ instead of 1'.format(d))
|
||||
else
|
||||
error('Please report a bug and help us improve support for this platform')
|
||||
endif
|
||||
endforeach
|
Loading…
Reference in New Issue