diff options
-rw-r--r-- | mesonbuild/scripts/symbolextractor.py | 75 |
1 files changed, 49 insertions, 26 deletions
diff --git a/mesonbuild/scripts/symbolextractor.py b/mesonbuild/scripts/symbolextractor.py index e889f62..dea7284 100644 --- a/mesonbuild/scripts/symbolextractor.py +++ b/mesonbuild/scripts/symbolextractor.py @@ -51,27 +51,47 @@ def write_if_changed(text, outfilename): with open(outfilename, 'w') as f: f.write(text) -def linux_syms(libfilename, outfilename): - evar = 'READELF' - if evar in os.environ: - readelfbin = os.environ[evar].strip() - else: - readelfbin = 'readelf' - evar = 'NM' +def print_tool_warning(tool, msg, stderr=None): + global TOOL_WARNING_FILE + if os.path.exists(TOOL_WARNING_FILE): + return + m = '{!r} {}. {}'.format(tool, msg, RELINKING_WARNING) + if stderr: + m += '\n' + stderr + mlog.warning(m) + # Write it out so we don't warn again + with open(TOOL_WARNING_FILE, 'w'): + pass + +def call_tool(name, args): + evar = name.upper() if evar in os.environ: - nmbin = os.environ[evar].strip() - else: - nmbin = 'nm' - pe, output = Popen_safe([readelfbin, '-d', libfilename])[0:2] - if pe.returncode != 0: - raise RuntimeError('Readelf does not work') + name = os.environ[evar].strip() + # Run it + try: + p, output, e = Popen_safe([name] + args) + except FileNotFoundError: + print_tool_warning(tool, 'not found') + return None + if p.returncode != 0: + print_tool_warning(name, 'does not work', e) + return None + return output + +def linux_syms(libfilename: str, outfilename: str): + # Get the name of the library + output = call_tool(['readelf', '-d', libfilename]) + if not output: + dummy_syms(outfilename) + return result = [x for x in output.split('\n') if 'SONAME' in x] assert(len(result) <= 1) - pnm, output = Popen_safe([nmbin, '--dynamic', '--extern-only', - '--defined-only', '--format=posix', - libfilename])[0:2] - if pnm.returncode != 0: - raise RuntimeError('nm does not work.') + # Get a list of all symbols exported + output = call_tool(['nm', '--dynamic', '--extern-only', '--defined-only', + '--format=posix', libfilename]) + if not output: + dummy_syms(outfilename) + return for line in output.split('\n'): if not line: continue @@ -83,20 +103,23 @@ def linux_syms(libfilename, outfilename): write_if_changed('\n'.join(result) + '\n', outfilename) def osx_syms(libfilename, outfilename): - pe, output = Popen_safe(['otool', '-l', libfilename])[0:2] - if pe.returncode != 0: - raise RuntimeError('Otool does not work.') + # Get the name of the library + output = call_tool(['otool', '-l', libfilename]) + if not output: + dummy_syms(outfilename) + return arr = output.split('\n') for (i, val) in enumerate(arr): if 'LC_ID_DYLIB' in val: match = i break result = [arr[match + 2], arr[match + 5]] # Libreoffice stores all 5 lines but the others seem irrelevant. - pnm, output = Popen_safe(['nm', '--extern-only', - '--defined-only', '--format=posix', - libfilename])[0:2] - if pnm.returncode != 0: - raise RuntimeError('nm does not work.') + # Get a list of all symbols exported + output = call_tool(['nm', '--extern-only', '--defined-only', + '--format=posix', libfilename]) + if not output: + dummy_syms(outfilename) + return result += [' '.join(x.split()[0:2]) for x in output.split('\n')] write_if_changed('\n'.join(result) + '\n', outfilename) |