aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Scholz <epirat07@gmail.com>2022-02-11 03:48:11 +0100
committerMarvin Scholz <epirat07@gmail.com>2022-03-31 10:55:55 +0200
commitf02ffc007c103189a3f80204676268f9a4429daa (patch)
treedae5a6f2ec9771c672d39f890761e6ad07adff24
parent2cdddbab56ffdbca6accfc626521968fbe2c917e (diff)
downloadmeson-f02ffc007c103189a3f80204676268f9a4429daa.zip
meson-f02ffc007c103189a3f80204676268f9a4429daa.tar.gz
meson-f02ffc007c103189a3f80204676268f9a4429daa.tar.bz2
clike: add more reliable ways to check underscore prefix
Fix #5482
-rw-r--r--mesonbuild/compilers/mixins/clike.py79
1 files changed, 73 insertions, 6 deletions
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index 269ce5c..7044b4e 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -900,9 +900,10 @@ class CLikeCompiler(Compiler):
return self.compiles(t, env, extra_args=extra_args,
dependencies=dependencies)
- def symbols_have_underscore_prefix(self, env: 'Environment') -> bool:
+ def _symbols_have_underscore_prefix_searchbin(self, env: 'Environment') -> bool:
'''
- Check if the compiler prefixes an underscore to global C symbols
+ Check if symbols have underscore prefix by compiling a small test binary
+ and then searching the binary for the string,
'''
symbol_name = b'meson_uscore_prefix'
code = '''#ifdef __cplusplus
@@ -914,7 +915,7 @@ class CLikeCompiler(Compiler):
#endif
'''
args = self.get_compiler_check_args(CompileCheckMode.COMPILE)
- n = 'symbols_have_underscore_prefix'
+ n = '_symbols_have_underscore_prefix_searchbin'
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:
raise RuntimeError(f'BUG: Unable to compile {n!r} check: {p.stdout}')
@@ -925,13 +926,79 @@ class CLikeCompiler(Compiler):
# Check if the underscore form of the symbol is somewhere
# in the output file.
if b'_' + symbol_name in line:
- mlog.debug("Symbols have underscore prefix: YES")
+ mlog.debug("Underscore prefix check found prefixed function in binary")
return True
# Else, check if the non-underscored form is present
elif symbol_name in line:
- mlog.debug("Symbols have underscore prefix: NO")
+ mlog.debug("Underscore prefix check found non-prefixed function in binary")
return False
- raise RuntimeError(f'BUG: {n!r} check failed unexpectedly')
+ raise RuntimeError(f'BUG: {n!r} check did not find symbol string in binary')
+
+ def _symbols_have_underscore_prefix_define(self, env: 'Environment') -> T.Optional[bool]:
+ '''
+ Check if symbols have underscore prefix by querying the
+ __USER_LABEL_PREFIX__ define that most compilers provide
+ for this. Return if functions have underscore prefix or None
+ if it was not possible to determine, like when the compiler
+ does not set the define or the define has an unexpected value.
+ '''
+ delim = '"MESON_HAVE_UNDERSCORE_DELIMITER" '
+ code = f'''
+ #ifndef __USER_LABEL_PREFIX__
+ #define MESON_UNDERSCORE_PREFIX unsupported
+ #else
+ #define MESON_UNDERSCORE_PREFIX __USER_LABEL_PREFIX__
+ #endif
+ {delim}MESON_UNDERSCORE_PREFIX
+ '''
+ with self._build_wrapper(code, env, mode='preprocess', want_output=False, temp_dir=env.scratch_dir) as p:
+ if p.returncode != 0:
+ raise RuntimeError(f'BUG: Unable to preprocess _symbols_have_underscore_prefix_define check: {p.stdout}')
+ symbol_prefix = p.stdout.partition(delim)[-1].rstrip()
+
+ mlog.debug(f'Queried compiler for function prefix: __USER_LABEL_PREFIX__ is "{symbol_prefix!s}"')
+ if symbol_prefix == '_':
+ return True
+ elif symbol_prefix == '':
+ return False
+ else:
+ return None
+
+ def _symbols_have_underscore_prefix_list(self, env: 'Environment') -> T.Optional[bool]:
+ '''
+ Check if symbols have underscore prefix by consulting a hardcoded
+ list of cases where we know the results.
+ Return if functions have underscore prefix or None if unknown.
+ '''
+ m = env.machines[self.for_machine]
+ # Darwin always uses the underscore prefix, not matter what
+ if m.is_darwin():
+ return True
+ # Windows uses the underscore prefix on x86 (32bit) only
+ if m.is_windows() or m.is_cygwin():
+ return m.cpu_family == 'x86'
+ return None
+
+
+ def symbols_have_underscore_prefix(self, env: 'Environment') -> bool:
+ '''
+ Check if the compiler prefixes an underscore to global C symbols
+ '''
+ # First, try to query the compiler directly
+ result = self._symbols_have_underscore_prefix_define(env)
+ if result is not None:
+ return result
+
+ # Else, try to consult a hardcoded list of cases we know
+ # absolutely have an underscore prefix
+ result = self._symbols_have_underscore_prefix_list(env)
+ if result is not None:
+ return result
+
+ # As a last resort, try search in a compiled binary, which is the
+ # most unreliable way of checking this, see #5482
+ return self._symbols_have_underscore_prefix_searchbin(env)
+
def _get_patterns(self, env: 'Environment', prefixes: T.List[str], suffixes: T.List[str], shared: bool = False) -> T.List[str]:
patterns = [] # type: T.List[str]