• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""Verifies that a list of libraries is installed on the system.
16
17Takes a list of arguments with every two subsequent arguments being a logical
18tuple of (path, check_soname). The path to the library and either True or False
19to indicate whether to check the soname field on the shared library.
20
21Example Usage:
22./check_cuda_libs.py /path/to/lib1.so True /path/to/lib2.so False
23"""
24import os
25import os.path
26import platform
27import subprocess
28import sys
29
30# pylint: disable=g-import-not-at-top,g-importing-member
31try:
32  from shutil import which
33except ImportError:
34  from distutils.spawn import find_executable as which
35# pylint: enable=g-import-not-at-top,g-importing-member
36
37
38class ConfigError(Exception):
39  pass
40
41
42def _is_windows():
43  return platform.system() == "Windows"
44
45
46def check_cuda_lib(path, check_soname=True):
47  """Tests if a library exists on disk and whether its soname matches the filename.
48
49  Args:
50    path: the path to the library.
51    check_soname: whether to check the soname as well.
52
53  Raises:
54    ConfigError: If the library does not exist or if its soname does not match
55    the filename.
56  """
57  if not os.path.isfile(path):
58    raise ConfigError("No library found under: " + path)
59  objdump = which("objdump")
60  if check_soname and objdump is not None and not _is_windows():
61    # Decode is necessary as in py3 the return type changed from str to bytes
62    output = subprocess.check_output([objdump, "-p", path]).decode("utf-8")
63    output = [line for line in output.splitlines() if "SONAME" in line]
64    sonames = [line.strip().split(" ")[-1] for line in output]
65    if not any(soname == os.path.basename(path) for soname in sonames):
66      raise ConfigError("None of the libraries match their SONAME: " + path)
67
68
69def main():
70  try:
71    args = [argv for argv in sys.argv[1:]]
72    if len(args) % 2 == 1:
73      raise ConfigError("Expected even number of arguments")
74    checked_paths = []
75    for i in range(0, len(args), 2):
76      path = args[i]
77      check_cuda_lib(path, check_soname=args[i + 1] == "True")
78      checked_paths.append(path)
79    # pylint: disable=superfluous-parens
80    print(os.linesep.join(checked_paths))
81    # pylint: enable=superfluous-parens
82  except ConfigError as e:
83    sys.stderr.write(str(e))
84    sys.exit(1)
85
86
87if __name__ == "__main__":
88  main()
89