Skip to content

Commit

Permalink
find_libraries searches lib and lib64 before prefix (spack#11958)
Browse files Browse the repository at this point in the history
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".
  • Loading branch information
tjfulle authored and scheibelp committed Jul 13, 2019
1 parent f1ce1dd commit 5bc15b2
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 39 deletions.
20 changes: 19 additions & 1 deletion lib/spack/llnl/util/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 4 additions & 14 deletions lib/spack/spack/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
10 changes: 2 additions & 8 deletions var/spack/repos/builtin/packages/cuda/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 3 additions & 8 deletions var/spack/repos/builtin/packages/hypre/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
13 changes: 5 additions & 8 deletions var/spack/repos/builtin/packages/sundials/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 5bc15b2

Please sign in to comment.