From 5bc15b2d9a061b37e55434edec6ae3954e95032b Mon Sep 17 00:00:00 2001 From: Tim Fuller Date: Fri, 12 Jul 2019 18:46:47 -0600 Subject: [PATCH] find_libraries searches lib and lib64 before prefix (#11958) The default library search for a package checks the lib/ and lib64/ directories for libraries before the root prefix, in order to save time when searching for libraries provided by externals (which e.g. may have '/usr/' as their root). This moves that logic into the "find_libraries" utility method so packages implementing their own custom library search logic can benefit from it. This also updates packages which appear to be replicating this logic exactly, replacing it with a single call to "find_libraries". --- lib/spack/llnl/util/filesystem.py | 20 ++++++++++++++++++- lib/spack/spack/spec.py | 18 ++++------------- .../repos/builtin/packages/cuda/package.py | 10 ++-------- .../repos/builtin/packages/hypre/package.py | 11 +++------- .../builtin/packages/sundials/package.py | 13 +++++------- 5 files changed, 33 insertions(+), 39 deletions(-) diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py index f4a1a9360c..ced29ad760 100644 --- a/lib/spack/llnl/util/filesystem.py +++ b/lib/spack/llnl/util/filesystem.py @@ -1389,7 +1389,25 @@ def find_libraries(libraries, root, shared=True, recursive=False): # List of libraries we are searching with suffixes libraries = ['{0}.{1}'.format(lib, suffix) for lib in libraries] - return LibraryList(find(root, libraries, recursive)) + if not recursive: + # If not recursive, look for the libraries directly in root + return LibraryList(find(root, libraries, False)) + + # To speedup the search for external packages configured e.g. in /usr, + # perform first non-recursive search in root/lib then in root/lib64 and + # finally search all of root recursively. The search stops when the first + # match is found. + for subdir in ('lib', 'lib64'): + dirname = join_path(root, subdir) + if not os.path.isdir(dirname): + continue + found_libs = find(dirname, libraries, False) + if found_libs: + break + else: + found_libs = find(root, libraries, True) + + return LibraryList(found_libs) @memoized diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 28b758ed2f..d50c7e7fd7 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -725,28 +725,18 @@ def _libs_default_handler(descriptor, spec, cls): if not name.startswith('lib'): name = 'lib' + name - # To speedup the search for external packages configured e.g. in /usr, - # perform first non-recursive search in prefix.lib then in prefix.lib64 and - # finally search all of prefix recursively. The search stops when the first - # match is found. - prefix = spec.prefix - search_paths = [(prefix.lib, False), (prefix.lib64, False), (prefix, True)] - # If '+shared' search only for shared library; if '~shared' search only for # static library; otherwise, first search for shared and then for static. search_shared = [True] if ('+shared' in spec) else \ ([False] if ('~shared' in spec) else [True, False]) for shared in search_shared: - for path, recursive in search_paths: - libs = find_libraries( - name, root=path, shared=shared, recursive=recursive - ) - if libs: - return libs + libs = find_libraries(name, spec.prefix, shared=shared, recursive=True) + if libs: + return libs msg = 'Unable to recursively locate {0} libraries in {1}' - raise NoLibrariesError(msg.format(spec.name, prefix)) + raise NoLibrariesError(msg.format(spec.name, spec.prefix)) class ForwardQueryToPackage(object): diff --git a/var/spack/repos/builtin/packages/cuda/package.py b/var/spack/repos/builtin/packages/cuda/package.py index 5409a38d52..bb963ec3b2 100644 --- a/var/spack/repos/builtin/packages/cuda/package.py +++ b/var/spack/repos/builtin/packages/cuda/package.py @@ -63,14 +63,8 @@ def install(self, spec, prefix): @property def libs(self): - prefix = self.prefix - search_paths = [(prefix.lib, False), (prefix.lib64, False), - (prefix, True)] - for search_root, recursive in search_paths: - libs = find_libraries( - 'libcuda', root=search_root, shared=True, recursive=recursive) - if libs: - break + libs = find_libraries('libcuda', root=self.prefix, shared=True, + recursive=True) filtered_libs = [] # CUDA 10.0 provides Compatability libraries for running newer versions diff --git a/var/spack/repos/builtin/packages/hypre/package.py b/var/spack/repos/builtin/packages/hypre/package.py index 6459ad339c..89c090e954 100644 --- a/var/spack/repos/builtin/packages/hypre/package.py +++ b/var/spack/repos/builtin/packages/hypre/package.py @@ -150,12 +150,7 @@ def libs(self): """Export the hypre library. Sample usage: spec['hypre'].libs.ld_flags """ - search_paths = [[self.prefix.lib, False], [self.prefix.lib64, False], - [self.prefix, True]] is_shared = '+shared' in self.spec - for path, recursive in search_paths: - libs = find_libraries('libHYPRE', root=path, - shared=is_shared, recursive=recursive) - if libs: - return libs - return None + libs = find_libraries('libHYPRE', root=self.prefix, shared=is_shared, + recursive=True) + return libs or None diff --git a/var/spack/repos/builtin/packages/sundials/package.py b/var/spack/repos/builtin/packages/sundials/package.py index b4882ebbb9..8ccb457644 100644 --- a/var/spack/repos/builtin/packages/sundials/package.py +++ b/var/spack/repos/builtin/packages/sundials/package.py @@ -500,12 +500,9 @@ def libs(self): # Q: should the result be ordered by dependency? else: sun_libs = ['libsundials_' + p for p in query_parameters] - search_paths = [[self.prefix.lib, False], [self.prefix.lib64, False], - [self.prefix, True]] is_shared = '+shared' in self.spec - for path, recursive in search_paths: - libs = find_libraries(sun_libs, root=path, shared=is_shared, - recursive=recursive) - if libs: - return libs - return None # Raise an error + + libs = find_libraries(sun_libs, root=self.prefix, shared=is_shared, + recursive=True) + + return libs or None # Raise an error if no libs are found