From 2eb8db1dd2e8da010974a48c024538930a48ea94 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Sat, 9 Sep 2017 15:22:56 -0500 Subject: Fix name detection in HeaderList and LibraryList (#5118) * Fix name detection in HeaderList and LibraryList * Add support for CUDA header files --- lib/spack/llnl/util/filesystem.py | 60 ++++++++++++++++++++++++++++++--------- lib/spack/spack/test/file_list.py | 42 ++++++++++++++------------- 2 files changed, 68 insertions(+), 34 deletions(-) (limited to 'lib') diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py index 554ae25230..4f018536e6 100644 --- a/lib/spack/llnl/util/filesystem.py +++ b/lib/spack/llnl/util/filesystem.py @@ -647,19 +647,6 @@ class FileList(collections.Sequence): """ return list(dedupe(os.path.basename(x) for x in self.files)) - @property - def names(self): - """Stable de-duplication of file names in the list without extensions - - >>> h = HeaderList(['/dir1/a.h', '/dir2/b.h', '/dir3/a.h']) - >>> h.names - ['a', 'b'] - - Returns: - list of strings: A list of files without extensions - """ - return list(dedupe(x.split('.')[0] for x in self.basenames)) - def __getitem__(self, item): cls = type(self) if isinstance(item, numbers.Integral): @@ -709,6 +696,34 @@ class HeaderList(FileList): """ return self.files + @property + def names(self): + """Stable de-duplication of header names in the list without extensions + + >>> h = HeaderList(['/dir1/a.h', '/dir2/b.h', '/dir3/a.h']) + >>> h.names + ['a', 'b'] + + Returns: + list of strings: A list of files without extensions + """ + names = [] + + for x in self.basenames: + name = x + + # Valid extensions include: ['.cuh', '.hpp', '.hh', '.h'] + for ext in ['.cuh', '.hpp', '.hh', '.h']: + i = name.rfind(ext) + if i != -1: + names.append(name[:i]) + break + else: + # No valid extension, should we still include it? + names.append(name) + + return list(dedupe(names)) + @property def include_flags(self): """Include flags @@ -833,7 +848,24 @@ class LibraryList(FileList): Returns: list of strings: A list of library names """ - return list(dedupe(x.split('.')[0][3:] for x in self.basenames)) + names = [] + + for x in self.basenames: + name = x + if x.startswith('lib'): + name = x[3:] + + # Valid extensions include: ['.dylib', '.so', '.a'] + for ext in ['.dylib', '.so', '.a']: + i = name.rfind(ext) + if i != -1: + names.append(name[:i]) + break + else: + # No valid extension, should we still include it? + names.append(name) + + return list(dedupe(names)) @property def search_flags(self): diff --git a/lib/spack/spack/test/file_list.py b/lib/spack/spack/test/file_list.py index 66f71b4190..4b71881313 100644 --- a/lib/spack/spack/test/file_list.py +++ b/lib/spack/spack/test/file_list.py @@ -36,12 +36,13 @@ from llnl.util.filesystem import find_libraries, find_headers @pytest.fixture() def library_list(): """Returns an instance of LibraryList.""" + # Test all valid extensions: ['.a', '.dylib', '.so'] l = [ '/dir1/liblapack.a', - '/dir2/libfoo.dylib', + '/dir2/libpython3.6.dylib', # name may contain periods '/dir1/libblas.a', - '/dir3/libbar.so', - 'libbaz.so' + '/dir3/libz.so', + 'libmpi.so.20.10.1', # shared object libraries may be versioned ] return LibraryList(l) @@ -50,12 +51,13 @@ def library_list(): @pytest.fixture() def header_list(): """Returns an instance of header list""" + # Test all valid extensions: ['.h', '.hpp', '.hh', '.cuh'] h = [ '/dir1/Python.h', - '/dir2/datetime.h', - '/dir1/pyconfig.h', - '/dir3/core.h', - 'pymem.h' + '/dir2/date.time.h', + '/dir1/pyconfig.hpp', + '/dir3/core.hh', + 'pymem.cuh', ] h = HeaderList(h) h.add_macro('-DBOOST_LIB_NAME=boost_regex') @@ -72,14 +74,14 @@ class TestLibraryList(object): def test_joined_and_str(self, library_list): s1 = library_list.joined() - expected = '/dir1/liblapack.a /dir2/libfoo.dylib /dir1/libblas.a /dir3/libbar.so libbaz.so' # noqa: E501 + expected = '/dir1/liblapack.a /dir2/libpython3.6.dylib /dir1/libblas.a /dir3/libz.so libmpi.so.20.10.1' # noqa: E501 assert s1 == expected s2 = str(library_list) assert s1 == s2 s3 = library_list.joined(';') - expected = '/dir1/liblapack.a;/dir2/libfoo.dylib;/dir1/libblas.a;/dir3/libbar.so;libbaz.so' # noqa: E501 + expected = '/dir1/liblapack.a;/dir2/libpython3.6.dylib;/dir1/libblas.a;/dir3/libz.so;libmpi.so.20.10.1' # noqa: E501 assert s3 == expected def test_flags(self, library_list): @@ -93,12 +95,12 @@ class TestLibraryList(object): link_flags = library_list.link_flags assert '-llapack' in link_flags - assert '-lfoo' in link_flags + assert '-lpython3.6' in link_flags assert '-lblas' in link_flags - assert '-lbar' in link_flags - assert '-lbaz' in link_flags + assert '-lz' in link_flags + assert '-lmpi' in link_flags assert isinstance(link_flags, str) - assert link_flags == '-llapack -lfoo -lblas -lbar -lbaz' + assert link_flags == '-llapack -lpython3.6 -lblas -lz -lmpi' ld_flags = library_list.ld_flags assert isinstance(ld_flags, str) @@ -106,7 +108,7 @@ class TestLibraryList(object): def test_paths_manipulation(self, library_list): names = library_list.names - assert names == ['lapack', 'foo', 'blas', 'bar', 'baz'] + assert names == ['lapack', 'python3.6', 'blas', 'z', 'mpi'] directories = library_list.directories assert directories == ['/dir1', '/dir2', '/dir3'] @@ -123,7 +125,7 @@ class TestLibraryList(object): def test_add(self, library_list): pylist = [ '/dir1/liblapack.a', # removed from the final list - '/dir2/libbaz.so', + '/dir2/libmpi.so', '/dir4/libnew.a' ] another = LibraryList(pylist) @@ -146,14 +148,14 @@ class TestHeaderList(object): def test_joined_and_str(self, header_list): s1 = header_list.joined() - expected = '/dir1/Python.h /dir2/datetime.h /dir1/pyconfig.h /dir3/core.h pymem.h' # noqa: E501 + expected = '/dir1/Python.h /dir2/date.time.h /dir1/pyconfig.hpp /dir3/core.hh pymem.cuh' # noqa: E501 assert s1 == expected s2 = str(header_list) assert s1 == s2 s3 = header_list.joined(';') - expected = '/dir1/Python.h;/dir2/datetime.h;/dir1/pyconfig.h;/dir3/core.h;pymem.h' # noqa: E501 + expected = '/dir1/Python.h;/dir2/date.time.h;/dir1/pyconfig.hpp;/dir3/core.hh;pymem.cuh' # noqa: E501 assert s3 == expected def test_flags(self, header_list): @@ -176,7 +178,7 @@ class TestHeaderList(object): def test_paths_manipulation(self, header_list): names = header_list.names - assert names == ['Python', 'datetime', 'pyconfig', 'core', 'pymem'] + assert names == ['Python', 'date.time', 'pyconfig', 'core', 'pymem'] directories = header_list.directories assert directories == ['/dir1', '/dir2', '/dir3'] @@ -193,8 +195,8 @@ class TestHeaderList(object): def test_add(self, header_list): pylist = [ '/dir1/Python.h', # removed from the final list - '/dir2/pyconfig.h', - '/dir4/datetime.h' + '/dir2/pyconfig.hpp', + '/dir4/date.time.h' ] another = HeaderList(pylist) h = header_list + another -- cgit v1.2.3-60-g2f50