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.
pull/1511/head
Nirbheek Chauhan 8 years ago
parent d0d7cbd88b
commit de47541e6c
  1. 70
      mesonbuild/compilers.py
  2. 15
      mesonbuild/interpreter.py
  3. 19
      test cases/common/140 get define/meson.build

@ -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…
Cancel
Save