diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2020-02-18 01:12:34 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2020-02-22 06:49:34 +0530 |
commit | cbd143844d54694fda90330e0d49c7ac408c532e (patch) | |
tree | bafb792aef5c886431803bc26091eb7d401d8ddc | |
parent | cace70c64eab4c4f5ba5bca7e76e02cab275b025 (diff) | |
download | meson-cbd143844d54694fda90330e0d49c7ac408c532e.zip meson-cbd143844d54694fda90330e0d49c7ac408c532e.tar.gz meson-cbd143844d54694fda90330e0d49c7ac408c532e.tar.bz2 |
symbolextractor: Add support for clang-cl
Requires the latest LLVm 9.0 release which implements the `-list`
argument to `llvm-lib` and ships with an implementation of `nm` called
`llvm-nm`.
-rw-r--r-- | ci/azure-steps.yml | 4 | ||||
-rw-r--r-- | mesonbuild/scripts/symbolextractor.py | 64 |
2 files changed, 39 insertions, 29 deletions
diff --git a/ci/azure-steps.yml b/ci/azure-steps.yml index 1c861e7..15832bb 100644 --- a/ci/azure-steps.yml +++ b/ci/azure-steps.yml @@ -114,8 +114,8 @@ steps: $env:Path = $origPath # install llvm for clang-cl builds - DownloadFile -Source 'http://releases.llvm.org/7.0.0/LLVM-7.0.0-win64.exe' -Destination LLVM-7.0.0-win64.exe - Start-Process .\LLVM-7.0.0-win64.exe -ArgumentList '/S' -Wait + DownloadFile -Source 'http://releases.llvm.org/9.0.0/LLVM-9.0.0-win64.exe' -Destination LLVM-9.0.0-win64.exe + Start-Process .\LLVM-9.0.0-win64.exe -ArgumentList '/S' -Wait $env:Path = "C:\Program Files\LLVM\bin;$env:Path" $env:CC = "clang-cl" $env:CXX = "clang-cl" diff --git a/mesonbuild/scripts/symbolextractor.py b/mesonbuild/scripts/symbolextractor.py index 2172243..25416c6 100644 --- a/mesonbuild/scripts/symbolextractor.py +++ b/mesonbuild/scripts/symbolextractor.py @@ -140,56 +140,66 @@ def osx_syms(libfilename: str, outfilename: str): write_if_changed('\n'.join(result) + '\n', outfilename) def _get_implib_dllname(impfilename: str) -> T.Tuple[T.List[str], str]: - # First try lib.exe, which is provided by MSVC. - # Do not allow overriding by setting the LIB env var, because that is - # already used for something else: it's the list of library paths MSVC - # will search for import libraries while linking. - output, e1 = call_tool_nowarn(['lib', '-list', impfilename]) - if output: - # The output is a list of DLLs that each symbol exported by the import - # library is available in. We only build import libraries that point to - # a single DLL, so we can pick any of these. Pick the last one for - # simplicity. Also skip the last line, which is empty. - return output.split('\n')[-2:-1], None + all_stderr = '' + # First try lib.exe, which is provided by MSVC. Then llvm-lib.exe, by LLVM + # for clang-cl. + # + # We cannot call get_tool on `lib` because it will look at the `LIB` env + # var which is the list of library paths MSVC will search for import + # libraries while linking. + for lib in (['lib'], get_tool('llvm-lib')): + output, e = call_tool_nowarn(lib + ['-list', impfilename]) + if output: + # The output is a list of DLLs that each symbol exported by the import + # library is available in. We only build import libraries that point to + # a single DLL, so we can pick any of these. Pick the last one for + # simplicity. Also skip the last line, which is empty. + return output.split('\n')[-2:-1], None + all_stderr += e # Next, try dlltool.exe which is provided by MinGW - output, e2 = call_tool_nowarn(get_tool('dlltool') + ['-I', impfilename]) + output, e = call_tool_nowarn(get_tool('dlltool') + ['-I', impfilename]) if output: return [output], None - return ([], (e1 + e2)) + all_stderr += e + return ([], all_stderr) def _get_implib_exports(impfilename: str) -> T.Tuple[T.List[str], str]: + all_stderr = '' # Force dumpbin.exe to use en-US so we can parse its output env = os.environ.copy() env['VSLANG'] = '1033' - output, e1 = call_tool_nowarn(get_tool('dumpbin') + ['-exports', impfilename], env=env) + output, e = call_tool_nowarn(get_tool('dumpbin') + ['-exports', impfilename], env=env) if output: lines = output.split('\n') start = lines.index('File Type: LIBRARY') end = lines.index(' Summary') return lines[start:end], None - # Next, try nm.exe which is provided by MinGW - output, e2 = call_tool_nowarn(get_tool('nm') + ['--extern-only', '--defined-only', - '--format=posix', impfilename]) - if output: - result = [] - for line in output.split('\n'): - if ' T ' not in line or line.startswith('.text'): - continue - result.append(line.split(maxsplit=1)[0]) - return result, None - return ([], (e1 + e2)) + all_stderr += e + # Next, try llvm-nm.exe provided by LLVM, then nm.exe provided by MinGW + for nm in ('llvm-nm', 'nm'): + output, e = call_tool_nowarn(get_tool(nm) + ['--extern-only', '--defined-only', + '--format=posix', impfilename]) + if output: + result = [] + for line in output.split('\n'): + if ' T ' not in line or line.startswith('.text'): + continue + result.append(line.split(maxsplit=1)[0]) + return result, None + all_stderr += e + return ([], all_stderr) def windows_syms(impfilename: str, outfilename: str): # Get the name of the library result, e = _get_implib_dllname(impfilename) if not result: - print_tool_warning('Both lib.exe and dlltool.exe', 'do not work', e) + print_tool_warning('lib, llvm-lib, dlltool', 'do not work or were not found', e) dummy_syms(outfilename) return # Get a list of all symbols exported symbols, e = _get_implib_exports(impfilename) if not symbols: - print_tool_warning('Both dumpbin.exe and nm.exe', 'do not work', e) + print_tool_warning('dumpbin, llvm-nm, nm', 'do not work or were not found', e) dummy_syms(outfilename) return result += symbols |