aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorMarvin Scholz <epirat07@gmail.com>2023-09-06 03:12:55 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2023-09-07 00:45:38 +0300
commit3fc16f05b513f26aa5da614673116074f5d60396 (patch)
tree4227d8e3c741ecefb8fc8849cd25e1399f004741 /mesonbuild
parent346a9157436fb88fbf38e2d1284fa7373c14d4a1 (diff)
downloadmeson-3fc16f05b513f26aa5da614673116074f5d60396.zip
meson-3fc16f05b513f26aa5da614673116074f5d60396.tar.gz
meson-3fc16f05b513f26aa5da614673116074f5d60396.tar.bz2
Add compiler.has_define
Adds a new method to the compiler object, has_define. This makes it possible to check if a preprocessor macro/define is set or not. This is especially helpful if the define in question is empty, for example: #define MESON_EMPTY_DEFINE This would yield the same results as a missing define with the existing get_define method, as it would return an empty string for both cases. Therefore this additional method is needed.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/compilers/mixins/clike.py27
-rw-r--r--mesonbuild/interpreter/compiler.py22
2 files changed, 40 insertions, 9 deletions
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index 4999d60..f37bcf4 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -672,13 +672,15 @@ class CLikeCompiler(Compiler):
extra_args: T.Union[T.List[str], T.Callable[[CompileCheckMode], T.List[str]]],
dependencies: T.Optional[T.List['Dependency']],
disable_cache: bool = False) -> T.Tuple[str, bool]:
- delim = '"MESON_GET_DEFINE_DELIMITER"'
+ delim_start = '"MESON_GET_DEFINE_DELIMITER_START"\n'
+ delim_end = '\n"MESON_GET_DEFINE_DELIMITER_END"'
+ sentinel_undef = '"MESON_GET_DEFINE_UNDEFINED_SENTINEL"'
code = f'''
{prefix}
#ifndef {dname}
- # define {dname}
+ # define {dname} {sentinel_undef}
#endif
- {delim}\n{dname}'''
+ {delim_start}{dname}{delim_end}'''
args = self.build_wrapper_args(env, extra_args, dependencies,
mode=CompileCheckMode.PREPROCESS).to_native()
func = functools.partial(self.cached_compile, code, env.coredata, extra_args=args, mode=CompileCheckMode.PREPROCESS)
@@ -688,10 +690,21 @@ class CLikeCompiler(Compiler):
cached = p.cached
if p.returncode != 0:
raise mesonlib.EnvironmentException(f'Could not get define {dname!r}')
- # Get the preprocessed value after the delimiter,
- # minus the extra newline at the end and
- # merge string literals.
- return self._concatenate_string_literals(p.stdout.split(delim + '\n')[-1][:-1]).strip(), cached
+
+ # Get the preprocessed value between the delimiters
+ star_idx = p.stdout.find(delim_start)
+ end_idx = p.stdout.rfind(delim_end)
+ if (star_idx == -1) or (end_idx == -1) or (star_idx == end_idx):
+ raise AssertionError('BUG: Delimiters not found in preprocessor output!')
+ define_value = p.stdout[star_idx + len(delim_start):end_idx]
+
+ if define_value == sentinel_undef:
+ define_value = None
+ else:
+ # Merge string literals
+ define_value = self._concatenate_string_literals(define_value).strip()
+
+ return define_value, cached
def get_return_value(self, fname: str, rtype: str, prefix: str,
env: 'Environment', extra_args: T.Optional[T.List[str]],
diff --git a/mesonbuild/interpreter/compiler.py b/mesonbuild/interpreter/compiler.py
index b85aa37..b6a1a85 100644
--- a/mesonbuild/interpreter/compiler.py
+++ b/mesonbuild/interpreter/compiler.py
@@ -189,6 +189,7 @@ class CompilerHolder(ObjectHolder['Compiler']):
'compute_int': self.compute_int_method,
'sizeof': self.sizeof_method,
'get_define': self.get_define_method,
+ 'has_define': self.has_define_method,
'check_header': self.check_header_method,
'has_header': self.has_header_method,
'has_header_symbol': self.has_header_symbol_method,
@@ -475,8 +476,25 @@ class CompilerHolder(ObjectHolder['Compiler']):
extra_args=extra_args,
dependencies=deps)
cached_msg = mlog.blue('(cached)') if cached else ''
- mlog.log('Fetching value of define', mlog.bold(element, True), msg, value, cached_msg)
- return value
+ value_msg = '(undefined)' if value is None else value
+ mlog.log('Fetching value of define', mlog.bold(element, True), msg, value_msg, cached_msg)
+ return value if value is not None else ''
+
+ @FeatureNew('compiler.has_define', '1.3.0')
+ @typed_pos_args('compiler.has_define', str)
+ @typed_kwargs('compiler.has_define', *_COMMON_KWS)
+ def has_define_method(self, args: T.Tuple[str], kwargs: 'CommonKW') -> bool:
+ define_name = args[0]
+ extra_args = functools.partial(self._determine_args, kwargs)
+ deps, msg = self._determine_dependencies(kwargs['dependencies'], endl=None)
+ value, cached = self.compiler.get_define(define_name, kwargs['prefix'], self.environment,
+ extra_args=extra_args,
+ dependencies=deps)
+ cached_msg = mlog.blue('(cached)') if cached else ''
+ h = mlog.green('YES') if value is not None else mlog.red('NO')
+ mlog.log('Checking if define', mlog.bold(define_name, True), msg, 'exists:', h, cached_msg)
+
+ return value is not None
@typed_pos_args('compiler.compiles', (str, mesonlib.File))
@typed_kwargs('compiler.compiles', *_COMPILES_KWS)