Repository: spack/spack

Issue:
Windows rpath support (#31930) breaks "find_libraries"
### Steps to reproduce the issue

```
spack install dyninst
```


### Error message

```
==> dyninst: Executing phase: 'cmake'
==> Error: NoLibrariesError: Unable to recursively locate libiberty libraries in /scratch/krentel/libiberty/install/linux-rhel8-x86_64/gcc-8.5.0/libiberty-2.37-d42oua4hpsotsfjijg6zhvlvswpowekx

/scratch/krentel/libiberty/spack-repo/var/spack/repos/builtin/packages/dyninst/package.py:118, in cmake_args:
        115            "-DElfUtils_ROOT_DIR=%s" % spec["elf"].prefix,
        116            "-DLibIberty_ROOT_DIR=%s" % spec["libiberty"].prefix,
        117            "-DTBB_ROOT_DIR=%s" % spec["tbb"].prefix,
  >>    118            self.define("LibIberty_LIBRARIES", spec["libiberty"].libs),
        119        ]
        120
```


### Information on your system

* **Spack:** 0.19.0.dev0 (53a7b49619671a318274cdec43952a1d59f77ff0)
* **Python:** 3.6.8
* **Platform:** linux-rhel8-zen2
* **Concretizer:** clingo


### Additional information

Something in this commit breaks the build for dyninst.

```
commit 53a7b49619671a318274cdec43952a1d59f77ff0 (HEAD)
Author: John W. Parent <45471568+johnwparent@users.noreply.github.com>
Date:   Tue Sep 13 13:28:29 2022 -0400

    Windows rpath support (#31930)
```

Dyninst uses the following line to find the libiberty.a library:

```
self.define("LibIberty_LIBRARIES", spec["libiberty"].libs),
```

Dyninst needs `LibIberty_LIBRARIES` to be set to the path to `libiberty.a`.
This used to work, but after the above commit, the build for dyninst
fails as:

```
==> dyninst: Executing phase: 'cmake'
==> Error: NoLibrariesError: Unable to recursively locate libiberty libraries in /scratch/krentel/libiberty/install/linux-rhel8-x86_64/gcc-8.5.0/libiberty-2.37-d42oua4hpsotsfjijg6zhvlvswpowekx

/scratch/krentel/libiberty/spack-repo/var/spack/repos/builtin/packages/dyninst/package.py:118, in cmake_args:
        115            "-DElfUtils_ROOT_DIR=%s" % spec["elf"].prefix,
        116            "-DLibIberty_ROOT_DIR=%s" % spec["libiberty"].prefix,
        117            "-DTBB_ROOT_DIR=%s" % spec["tbb"].prefix,
  >>    118            self.define("LibIberty_LIBRARIES", spec["libiberty"].libs),
        119        ]
        120
```

The build for dyninst fails, but I think the real problem is in core
in the default searching for libraries.  Or, maybe there's a disagreement
whether the library search should return the library or the directory
containing the library.  I'm not sure (but it used to work).

@johnwparent @hainest 


### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have run `spack maintainers <name-of-the-package>` and **@mentioned** any maintainers
- [X] I have uploaded the build log and environment files
- [X] I have searched the issues of this repo and believe this is not a duplicate


Discussion:
The error is https://github.com/spack/spack/pull/31930/files#r971114971 I'll try to submit a fix asap.

Resolving patch:
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -2055,22 +2055,22 @@ def find_libraries(libraries, root, shared=True, recursive=False):
         raise TypeError(message)
 
     if is_windows:
-        static = "lib"
-        shared = "dll"
+        static_ext = "lib"
+        shared_ext = "dll"
     else:
         # Used on both Linux and macOS
-        static = "a"
-        shared = "so"
+        static_ext = "a"
+        shared_ext = "so"
 
     # Construct the right suffix for the library
     if shared:
         # Used on both Linux and macOS
-        suffixes = [shared]
+        suffixes = [shared_ext]
         if sys.platform == "darwin":
             # Only used on macOS
             suffixes.append("dylib")
     else:
-        suffixes = [static]
+        suffixes = [static_ext]
 
     # List of libraries we are searching with suffixes
     libraries = ["{0}.{1}".format(lib, suffix) for lib in libraries for suffix in suffixes]


Test patch:
diff --git a/lib/spack/spack/test/llnl/util/file_list.py b/lib/spack/spack/test/llnl/util/file_list.py
--- a/lib/spack/spack/test/llnl/util/file_list.py
+++ b/lib/spack/spack/test/llnl/util/file_list.py
@@ -72,7 +72,7 @@ def header_list():
 plat_shared_ext = "dll" if is_windows else "so"
 
 
-plat_apple_shared_ext = "dll" if is_windows else "dylib"
+plat_apple_shared_ext = "dylib"
 
 
 class TestLibraryList(object):
@@ -86,7 +86,7 @@ def test_joined_and_str(self, library_list):
         expected = " ".join(
             [
                 "/dir1/liblapack.%s" % plat_static_ext,
-                "/dir2/libpython3.6.%s" % plat_apple_shared_ext,
+                "/dir2/libpython3.6.%s" % (plat_apple_shared_ext if not is_windows else "dll"),
                 "/dir1/libblas.%s" % plat_static_ext,
                 "/dir3/libz.%s" % plat_shared_ext,
                 "libmpi.%s.20.10.1" % plat_shared_ext,
@@ -101,7 +101,7 @@ def test_joined_and_str(self, library_list):
         expected = ";".join(
             [
                 "/dir1/liblapack.%s" % plat_static_ext,
-                "/dir2/libpython3.6.%s" % plat_apple_shared_ext,
+                "/dir2/libpython3.6.%s" % (plat_apple_shared_ext if not is_windows else "dll"),
                 "/dir1/libblas.%s" % plat_static_ext,
                 "/dir3/libz.%s" % plat_shared_ext,
                 "libmpi.%s.20.10.1" % plat_shared_ext,
@@ -254,6 +254,29 @@ def test_add(self, header_list):
 search_dir = os.path.join(spack.paths.test_path, "data", "directory_search")
 
 
+@pytest.mark.parametrize(
+    "lib_list,kwargs",
+    [
+        (["liba"], {"shared": True, "recursive": True}),
+        (["liba"], {"shared": False, "recursive": True}),
+        (["libc", "liba"], {"shared": True, "recursive": True}),
+        (["liba", "libc"], {"shared": False, "recursive": True}),
+        (["libc", "libb", "liba"], {"shared": True, "recursive": True}),
+        (["liba", "libb", "libc"], {"shared": False, "recursive": True}),
+    ],
+)
+def test_library_type_search(lib_list, kwargs):
+    results = find_libraries(lib_list, search_dir, **kwargs)
+    assert len(results) != 0
+    for result in results:
+        lib_type_ext = plat_shared_ext
+        if not kwargs["shared"]:
+            lib_type_ext = plat_static_ext
+        assert result.endswith(lib_type_ext) or (
+            kwargs["shared"] and result.endswith(plat_apple_shared_ext)
+        )
+
+
 @pytest.mark.parametrize(
     "search_fn,search_list,root,kwargs",
     [