Add 'required' kwarg in header check functions

Closes: #3940
pull/4658/head
Xavier Claessens 6 years ago
parent 4df9006ca4
commit ff2aa5a9ef
  1. 11
      docs/markdown/Reference-manual.md
  2. 34
      mesonbuild/interpreter.py

@ -1760,7 +1760,9 @@ the following methods:
the `prefix` keyword. In order to look for headers in a specific the `prefix` keyword. In order to look for headers in a specific
directory you can use `args : '-I/extra/include/dir`, but this directory you can use `args : '-I/extra/include/dir`, but this
should only be used in exceptional cases for includes that can't be should only be used in exceptional cases for includes that can't be
detected via pkg-config and passed via `dependencies`. detected via pkg-config and passed via `dependencies`. Since *0.50.0* the
`required` keyword argument can be used to abort if the header cannot be
found.
- `has_header` returns true if the specified header *exists*, and is - `has_header` returns true if the specified header *exists*, and is
faster than `check_header()` since it only does a pre-processor check. faster than `check_header()` since it only does a pre-processor check.
@ -1769,13 +1771,16 @@ the following methods:
the `prefix` keyword. In order to look for headers in a specific the `prefix` keyword. In order to look for headers in a specific
directory you can use `args : '-I/extra/include/dir`, but this directory you can use `args : '-I/extra/include/dir`, but this
should only be used in exceptional cases for includes that can't be should only be used in exceptional cases for includes that can't be
detected via pkg-config and passed via `dependencies`. detected via pkg-config and passed via `dependencies`. Since *0.50.0* the
`required` keyword argument can be used to abort if the header cannot be
found.
- `has_header_symbol(headername, symbolname)` allows one to detect - `has_header_symbol(headername, symbolname)` allows one to detect
whether a particular symbol (function, variable, #define, type whether a particular symbol (function, variable, #define, type
definition, etc) is declared in the specified header, you can definition, etc) is declared in the specified header, you can
specify external dependencies to use with `dependencies` keyword specify external dependencies to use with `dependencies` keyword
argument. argument. Since *0.50.0* the `required` keyword argument can be used to abort
if the symbol cannot be found.
- `has_member(typename, membername)` takes two arguments, type name - `has_member(typename, membername)` takes two arguments, type name
and member name and returns true if the type has the specified and member name and returns true if the type has the specified

@ -86,8 +86,8 @@ class FeatureOptionHolder(InterpreterObject, ObjectHolder):
def auto_method(self, args, kwargs): def auto_method(self, args, kwargs):
return self.held_object.is_auto() return self.held_object.is_auto()
def extract_required_kwarg(kwargs, subproject, feature_check=None): def extract_required_kwarg(kwargs, subproject, feature_check=None, default=True):
val = kwargs.get('required', True) val = kwargs.get('required', default)
disabled = False disabled = False
required = False required = False
feature = None feature = None
@ -1344,7 +1344,9 @@ class CompilerHolder(InterpreterObject):
return result return result
@FeatureNew('compiler.check_header', '0.47.0') @FeatureNew('compiler.check_header', '0.47.0')
@FeatureNewKwargs('compiler.check_header', '0.50.0', ['required'])
@permittedKwargs({ @permittedKwargs({
'required',
'prefix', 'prefix',
'no_builtin_args', 'no_builtin_args',
'include_directories', 'include_directories',
@ -1359,19 +1361,27 @@ class CompilerHolder(InterpreterObject):
prefix = kwargs.get('prefix', '') prefix = kwargs.get('prefix', '')
if not isinstance(prefix, str): if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_header must be a string.') raise InterpreterException('Prefix argument of has_header must be a string.')
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject, default=False)
if disabled:
mlog.log('Check usable header', mlog.bold(hname, True), 'skipped: feature', mlog.bold(feature), 'disabled')
return False
extra_args = functools.partial(self.determine_args, kwargs) extra_args = functools.partial(self.determine_args, kwargs)
deps, msg = self.determine_dependencies(kwargs) deps, msg = self.determine_dependencies(kwargs)
haz = self.compiler.check_header(hname, prefix, self.environment, haz = self.compiler.check_header(hname, prefix, self.environment,
extra_args=extra_args, extra_args=extra_args,
dependencies=deps) dependencies=deps)
if haz: if required and not haz:
raise InterpreterException('{} header {!r} not usable'.format(self.compiler.get_display_language(), hname))
elif haz:
h = mlog.green('YES') h = mlog.green('YES')
else: else:
h = mlog.red('NO') h = mlog.red('NO')
mlog.log('Check usable header', mlog.bold(hname, True), msg, h) mlog.log('Check usable header', mlog.bold(hname, True), msg, h)
return haz return haz
@FeatureNewKwargs('compiler.has_header', '0.50.0', ['required'])
@permittedKwargs({ @permittedKwargs({
'required',
'prefix', 'prefix',
'no_builtin_args', 'no_builtin_args',
'include_directories', 'include_directories',
@ -1386,18 +1396,26 @@ class CompilerHolder(InterpreterObject):
prefix = kwargs.get('prefix', '') prefix = kwargs.get('prefix', '')
if not isinstance(prefix, str): if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_header must be a string.') raise InterpreterException('Prefix argument of has_header must be a string.')
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject, default=False)
if disabled:
mlog.log('Has header', mlog.bold(hname, True), 'skipped: feature', mlog.bold(feature), 'disabled')
return False
extra_args = functools.partial(self.determine_args, kwargs) extra_args = functools.partial(self.determine_args, kwargs)
deps, msg = self.determine_dependencies(kwargs) deps, msg = self.determine_dependencies(kwargs)
haz = self.compiler.has_header(hname, prefix, self.environment, haz = self.compiler.has_header(hname, prefix, self.environment,
extra_args=extra_args, dependencies=deps) extra_args=extra_args, dependencies=deps)
if haz: if required and not haz:
raise InterpreterException('{} header {!r} not found'.format(self.compiler.get_display_language(), hname))
elif haz:
h = mlog.green('YES') h = mlog.green('YES')
else: else:
h = mlog.red('NO') h = mlog.red('NO')
mlog.log('Has header', mlog.bold(hname, True), msg, h) mlog.log('Has header', mlog.bold(hname, True), msg, h)
return haz return haz
@FeatureNewKwargs('compiler.has_header_symbol', '0.50.0', ['required'])
@permittedKwargs({ @permittedKwargs({
'required',
'prefix', 'prefix',
'no_builtin_args', 'no_builtin_args',
'include_directories', 'include_directories',
@ -1413,12 +1431,18 @@ class CompilerHolder(InterpreterObject):
prefix = kwargs.get('prefix', '') prefix = kwargs.get('prefix', '')
if not isinstance(prefix, str): if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_header_symbol must be a string.') raise InterpreterException('Prefix argument of has_header_symbol must be a string.')
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject, default=False)
if disabled:
mlog.log('Header <{0}> has symbol'.format(hname), mlog.bold(symbol, True), 'skipped: feature', mlog.bold(feature), 'disabled')
return False
extra_args = functools.partial(self.determine_args, kwargs) extra_args = functools.partial(self.determine_args, kwargs)
deps, msg = self.determine_dependencies(kwargs) deps, msg = self.determine_dependencies(kwargs)
haz = self.compiler.has_header_symbol(hname, symbol, prefix, self.environment, haz = self.compiler.has_header_symbol(hname, symbol, prefix, self.environment,
extra_args=extra_args, extra_args=extra_args,
dependencies=deps) dependencies=deps)
if haz: if required and not haz:
raise InterpreterException('{} symbol {} not found in header {}'.format(self.compiler.get_display_language(), symbol, hname))
elif haz:
h = mlog.green('YES') h = mlog.green('YES')
else: else:
h = mlog.red('NO') h = mlog.red('NO')

Loading…
Cancel
Save