diff options
-rw-r--r-- | bin/symbols-check.py | 44 | ||||
-rw-r--r-- | meson.build | 12 |
2 files changed, 50 insertions, 6 deletions
diff --git a/bin/symbols-check.py b/bin/symbols-check.py index 47305919634..0d56a19561e 100644 --- a/bin/symbols-check.py +++ b/bin/symbols-check.py @@ -19,9 +19,10 @@ PLATFORM_SYMBOLS = [ ] -def get_symbols(nm, lib): +def get_symbols_nm(nm, lib): ''' List all the (non platform-specific) symbols exported by the library + using `nm` ''' symbols = [] platform_name = platform.system() @@ -39,7 +40,35 @@ def get_symbols(nm, lib): assert symbol_name[0] == '_' symbol_name = symbol_name[1:] symbols.append(symbol_name) + return symbols + +def get_symbols_dumpbin(dumpbin, lib): + ''' + List all the (non platform-specific) symbols exported by the library + using `dumpbin` + ''' + symbols = [] + output = subprocess.check_output([dumpbin, '/exports', lib], + stderr=open(os.devnull, 'w')).decode("ascii") + for line in output.splitlines(): + fields = line.split() + # The lines with the symbols are made of at least 4 columns; see details below + if len(fields) < 4: + continue + try: + # Making sure the first 3 columns are a dec counter, a hex counter + # and a hex address + _ = int(fields[0], 10) + _ = int(fields[1], 16) + _ = int(fields[2], 16) + except ValueError: + continue + symbol_name = fields[3] + # De-mangle symbols + if symbol_name[0] == '_': + symbol_name = symbol_name[1:].split('@')[0] + symbols.append(symbol_name) return symbols @@ -55,12 +84,21 @@ def main(): help='path to library') parser.add_argument('--nm', action='store', - required=True, + help='path to binary (or name in $PATH)') + parser.add_argument('--dumpbin', + action='store', help='path to binary (or name in $PATH)') args = parser.parse_args() try: - lib_symbols = get_symbols(args.nm, args.lib) + if platform.system() == 'Windows': + if not args.dumpbin: + parser.error('--dumpbin is mandatory') + lib_symbols = get_symbols_dumpbin(args.dumpbin, args.lib) + else: + if not args.nm: + parser.error('--nm is mandatory') + lib_symbols = get_symbols_nm(args.nm, args.lib) except: # We can't run this test, but we haven't technically failed it either # Return the GNU "skip" error code diff --git a/meson.build b/meson.build index 020f725116f..796b628e5eb 100644 --- a/meson.build +++ b/meson.build @@ -1680,9 +1680,15 @@ endif pkg = import('pkgconfig') -prog_nm = find_program('nm', required : false) -with_symbols_check = prog_nm.found() and with_tests -symbols_check_args = ['--nm', prog_nm.path()] +if host_machine.system() == 'windows' + prog_dumpbin = find_program('dumpbin', required : false) + with_symbols_check = prog_dumpbin.found() and with_tests + symbols_check_args = ['--dumpbin', prog_dumpbin.path()] +else + prog_nm = find_program('nm', required : false) + with_symbols_check = prog_nm.found() and with_tests + symbols_check_args = ['--nm', prog_nm.path()] +endif # This quirk needs to be applied to sources with functions defined in assembly # as GCC LTO drops them. See: https://bugs.freedesktop.org/show_bug.cgi?id=109391 |