We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Cannot use Spack-built gcc
I built gcc with Spack, then added it manually to Spack's compiler list:

```
$ cat ~/.spack/compilers.yaml
compilers:
- compiler:
    modules: []
    operating_system: elcapitan
    paths:
      cc: /usr/bin/clang
      cxx: /usr/bin/clang++
      f77: null
      fc: null
    spec: clang@8.0.0-apple
- compiler:
    modules: []
    operating_system: elcapitan
    paths:
      cc: /usr/bin/gcc
      cxx: /usr/bin/g++
      f77: null
      fc: null
    spec: gcc@4.2.1
- compiler:
    modules: []
    operating_system: elcapitan
    paths:
      cc: /Users/eschnett/src/spack/opt/spack/darwin-elcapitan-x86_64/clang-8.0.0-apple/gcc-6.2.0-oqafsa4af6qaah553lcrsqlh2dczk2ic/bin/gcc
      cxx: /Users/eschnett/src/spack/opt/spack/darwin-elcapitan-x86_64/clang-8.0.0-apple/gcc-6.2.0-oqafsa4af6qaah553lcrsqlh2dczk2ic/bin/g++
      f77: /Users/eschnett/src/spack/opt/spack/darwin-elcapitan-x86_64/clang-8.0.0-apple/gcc-6.2.0-oqafsa4af6qaah553lcrsqlh2dczk2ic/bin/gfortran
      fc: /Users/eschnett/src/spack/opt/spack/darwin-elcapitan-x86_64/clang-8.0.0-apple/gcc-6.2.0-oqafsa4af6qaah553lcrsqlh2dczk2ic/bin/gfortran
    spec: gcc@6.2.0-spack
```

This used to work fine, but doesn't any more: When I try to use this compiler, Spack produces an error:

```
$ spack spec cactusext +funhpc +julia +simulationio %gcc@6.2.0-spack
Input spec
------------------------------
  cactusext%gcc@6.2.0-spack+funhpc+julia+simulationio

Normalized
------------------------------
  cactusext%gcc@6.2.0-spack+funhpc+julia+simulationio
      ^boost+mpi
          ^openmpi%gcc@6.1.0-spack
              ^hwloc%gcc@6.1.0-spack
                  ^libpciaccess
                      ^libtool
                          ^m4
      ^fftw%gcc@6.1.0-spack+mpi+openmp
      ^funhpc%gcc@6.1.0-spack
          ^cereal
              ^cmake@2.8:
          ^curl
              ^openssl%gcc@6.1.0-spack
                  ^zlib%gcc@6.1.0-spack
          ^jemalloc%clang@7.3.0-apple
          ^openmpi%gcc@6.1.0-spack
          ^qthreads
      ^git%clang@7.3.0-apple
          ^autoconf
          ^expat
          ^gettext
          ^libiconv
          ^pcre
          ^perl
      ^gsl%gcc@6.1.0-spack
      ^hdf5@1.10.0-patch1%gcc@6.1.0-spack+mpi
      ^hdf5-blosc%gcc@6.1.0-spack
          ^c-blosc
              ^snappy
      ^julia@master%gcc@6.1.0-spack+hdf5+mpi
          ^python@2.7.12%clang@7.3.0-apple
              ^bzip2
              ^ncurses
              ^readline
              ^sqlite
      ^lmod%gcc@6.1.0-spack
          ^lua@5.2:%gcc@6.1.0-spack
          ^lua-luafilesystem
          ^lua-luaposix
          ^tcl
      ^openblas%gcc@6.1.0-spack
      ^papi%gcc@6.1.0-spack
      ^petsc%gcc@6.1.0-spack+boost+hdf5+mpi~mumps
          ^openblas%gcc@6.1.0-spack
      ^simulationio%gcc@6.1.0-spack
          ^swig

Concretized
------------------------------
Traceback (most recent call last):
  File "/Users/eschnett/src/spack/bin/spack", line 192, in <module>
    main()
  File "/Users/eschnett/src/spack/bin/spack", line 169, in main
    return_val = command(parser, args)
  File "/Users/eschnett/src/spack/lib/spack/spack/cmd/spec.py", line 57, in spec
    spec.concretize()
  File "/Users/eschnett/src/spack/lib/spack/spack/spec.py", line 1256, in concretize
    self._expand_virtual_packages(),
  File "/Users/eschnett/src/spack/lib/spack/spack/spec.py", line 1173, in _expand_virtual_packages
    spec)
  File "/Users/eschnett/src/spack/lib/spack/spack/concretize.py", line 127, in choose_virtual_or_external
    strict = [spack.abi.compatible(c, abi_exemplar) for c in candidates]
  File "/Users/eschnett/src/spack/lib/spack/spack/abi.py", line 126, in compatible
    self.compiler_compatible(parent, child, loose=loosematch)
  File "/Users/eschnett/src/spack/lib/spack/spack/abi.py", line 115, in compiler_compatible
    self._gcc_compiler_compare(pversion, cversion)):
  File "/Users/eschnett/src/spack/lib/spack/llnl/util/lang.py", line 187, in __call__
    self.cache[args] = self.func(*args)
  File "/Users/eschnett/src/spack/lib/spack/spack/abi.py", line 79, in _gcc_compiler_compare
    plib = self._gcc_get_libstdcxx_version(pversion)
  File "/Users/eschnett/src/spack/lib/spack/llnl/util/lang.py", line 187, in __call__
    self.cache[args] = self.func(*args)
  File "/Users/eschnett/src/spack/lib/spack/spack/abi.py", line 70, in _gcc_get_libstdcxx_version
    libpath = os.readlink(output.strip())
OSError: [Errno 2] No such file or directory: 'libstdc++.so'
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/spack/spack/abi.py`
Content:
```
1 ##############################################################################
2 # Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
3 # Produced at the Lawrence Livermore National Laboratory.
4 #
5 # This file is part of Spack.
6 # Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
7 # LLNL-CODE-647188
8 #
9 # For details, see https://github.com/llnl/spack
10 # Please also see the LICENSE file for our notice and the LGPL.
11 #
12 # This program is free software; you can redistribute it and/or modify
13 # it under the terms of the GNU Lesser General Public License (as
14 # published by the Free Software Foundation) version 2.1, February 1999.
15 #
16 # This program is distributed in the hope that it will be useful, but
17 # WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
19 # conditions of the GNU Lesser General Public License for more details.
20 #
21 # You should have received a copy of the GNU Lesser General Public
22 # License along with this program; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 ##############################################################################
25 
26 import os
27 import spack
28 import spack.spec
29 from spack.spec import CompilerSpec
30 from spack.util.executable import Executable, ProcessError
31 from llnl.util.lang import memoized
32 
33 
34 class ABI(object):
35     """This class provides methods to test ABI compatibility between specs.
36        The current implementation is rather rough and could be improved."""
37 
38     def architecture_compatible(self, parent, child):
39         """Return true if parent and child have ABI compatible targets."""
40         return not parent.architecture or not child.architecture or \
41             parent.architecture == child.architecture
42 
43     @memoized
44     def _gcc_get_libstdcxx_version(self, version):
45         """Returns gcc ABI compatibility info by getting the library version of
46            a compiler's libstdc++.so or libgcc_s.so"""
47         spec = CompilerSpec("gcc", version)
48         compilers = spack.compilers.compilers_for_spec(spec)
49         if not compilers:
50             return None
51         compiler = compilers[0]
52         rungcc = None
53         libname = None
54         output = None
55         if compiler.cxx:
56             rungcc = Executable(compiler.cxx)
57             libname = "libstdc++.so"
58         elif compiler.cc:
59             rungcc = Executable(compiler.cc)
60             libname = "libgcc_s.so"
61         else:
62             return None
63         try:
64             output = rungcc("--print-file-name=%s" % libname,
65                             return_output=True)
66         except ProcessError:
67             return None
68         if not output:
69             return None
70         libpath = os.readlink(output.strip())
71         if not libpath:
72             return None
73         return os.path.basename(libpath)
74 
75     @memoized
76     def _gcc_compiler_compare(self, pversion, cversion):
77         """Returns true iff the gcc version pversion and cversion
78           are ABI compatible."""
79         plib = self._gcc_get_libstdcxx_version(pversion)
80         clib = self._gcc_get_libstdcxx_version(cversion)
81         if not plib or not clib:
82             return False
83         return plib == clib
84 
85     def _intel_compiler_compare(self, pversion, cversion):
86         """Returns true iff the intel version pversion and cversion
87            are ABI compatible"""
88 
89         # Test major and minor versions.  Ignore build version.
90         if (len(pversion.version) < 2 or len(cversion.version) < 2):
91             return False
92         return pversion.version[:2] == cversion.version[:2]
93 
94     def compiler_compatible(self, parent, child, **kwargs):
95         """Return true if compilers for parent and child are ABI compatible."""
96         if not parent.compiler or not child.compiler:
97             return True
98 
99         if parent.compiler.name != child.compiler.name:
100             # Different compiler families are assumed ABI incompatible
101             return False
102 
103         if kwargs.get('loose', False):
104             return True
105 
106         # TODO: Can we move the specialized ABI matching stuff
107         # TODO: into compiler classes?
108         for pversion in parent.compiler.versions:
109             for cversion in child.compiler.versions:
110                 # For a few compilers use specialized comparisons.
111                 # Otherwise match on version match.
112                 if pversion.satisfies(cversion):
113                     return True
114                 elif (parent.compiler.name == "gcc" and
115                       self._gcc_compiler_compare(pversion, cversion)):
116                     return True
117                 elif (parent.compiler.name == "intel" and
118                       self._intel_compiler_compare(pversion, cversion)):
119                     return True
120         return False
121 
122     def compatible(self, parent, child, **kwargs):
123         """Returns true iff a parent and child spec are ABI compatible"""
124         loosematch = kwargs.get('loose', False)
125         return self.architecture_compatible(parent, child) and \
126             self.compiler_compatible(parent, child, loose=loosematch)
127
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lib/spack/spack/abi.py b/lib/spack/spack/abi.py
--- a/lib/spack/spack/abi.py
+++ b/lib/spack/spack/abi.py
@@ -54,10 +54,10 @@
         output = None
         if compiler.cxx:
             rungcc = Executable(compiler.cxx)
-            libname = "libstdc++.so"
+            libname = "libstdc++." + dso_suffix
         elif compiler.cc:
             rungcc = Executable(compiler.cc)
-            libname = "libgcc_s.so"
+            libname = "libgcc_s." + dso_suffix
         else:
             return None
         try:

{"golden_diff": "diff --git a/lib/spack/spack/abi.py b/lib/spack/spack/abi.py\n--- a/lib/spack/spack/abi.py\n+++ b/lib/spack/spack/abi.py\n@@ -54,10 +54,10 @@\n         output = None\n         if compiler.cxx:\n             rungcc = Executable(compiler.cxx)\n-            libname = \"libstdc++.so\"\n+            libname = \"libstdc++.\" + dso_suffix\n         elif compiler.cc:\n             rungcc = Executable(compiler.cc)\n-            libname = \"libgcc_s.so\"\n+            libname = \"libgcc_s.\" + dso_suffix\n         else:\n             return None\n         try:\n", "issue": "Cannot use Spack-built gcc\nI built gcc with Spack, then added it manually to Spack's compiler list:\n\n```\n$ cat ~/.spack/compilers.yaml\ncompilers:\n- compiler:\n    modules: []\n    operating_system: elcapitan\n    paths:\n      cc: /usr/bin/clang\n      cxx: /usr/bin/clang++\n      f77: null\n      fc: null\n    spec: clang@8.0.0-apple\n- compiler:\n    modules: []\n    operating_system: elcapitan\n    paths:\n      cc: /usr/bin/gcc\n      cxx: /usr/bin/g++\n      f77: null\n      fc: null\n    spec: gcc@4.2.1\n- compiler:\n    modules: []\n    operating_system: elcapitan\n    paths:\n      cc: /Users/eschnett/src/spack/opt/spack/darwin-elcapitan-x86_64/clang-8.0.0-apple/gcc-6.2.0-oqafsa4af6qaah553lcrsqlh2dczk2ic/bin/gcc\n      cxx: /Users/eschnett/src/spack/opt/spack/darwin-elcapitan-x86_64/clang-8.0.0-apple/gcc-6.2.0-oqafsa4af6qaah553lcrsqlh2dczk2ic/bin/g++\n      f77: /Users/eschnett/src/spack/opt/spack/darwin-elcapitan-x86_64/clang-8.0.0-apple/gcc-6.2.0-oqafsa4af6qaah553lcrsqlh2dczk2ic/bin/gfortran\n      fc: /Users/eschnett/src/spack/opt/spack/darwin-elcapitan-x86_64/clang-8.0.0-apple/gcc-6.2.0-oqafsa4af6qaah553lcrsqlh2dczk2ic/bin/gfortran\n    spec: gcc@6.2.0-spack\n```\n\nThis used to work fine, but doesn't any more: When I try to use this compiler, Spack produces an error:\n\n```\n$ spack spec cactusext +funhpc +julia +simulationio %gcc@6.2.0-spack\nInput spec\n------------------------------\n  cactusext%gcc@6.2.0-spack+funhpc+julia+simulationio\n\nNormalized\n------------------------------\n  cactusext%gcc@6.2.0-spack+funhpc+julia+simulationio\n      ^boost+mpi\n          ^openmpi%gcc@6.1.0-spack\n              ^hwloc%gcc@6.1.0-spack\n                  ^libpciaccess\n                      ^libtool\n                          ^m4\n      ^fftw%gcc@6.1.0-spack+mpi+openmp\n      ^funhpc%gcc@6.1.0-spack\n          ^cereal\n              ^cmake@2.8:\n          ^curl\n              ^openssl%gcc@6.1.0-spack\n                  ^zlib%gcc@6.1.0-spack\n          ^jemalloc%clang@7.3.0-apple\n          ^openmpi%gcc@6.1.0-spack\n          ^qthreads\n      ^git%clang@7.3.0-apple\n          ^autoconf\n          ^expat\n          ^gettext\n          ^libiconv\n          ^pcre\n          ^perl\n      ^gsl%gcc@6.1.0-spack\n      ^hdf5@1.10.0-patch1%gcc@6.1.0-spack+mpi\n      ^hdf5-blosc%gcc@6.1.0-spack\n          ^c-blosc\n              ^snappy\n      ^julia@master%gcc@6.1.0-spack+hdf5+mpi\n          ^python@2.7.12%clang@7.3.0-apple\n              ^bzip2\n              ^ncurses\n              ^readline\n              ^sqlite\n      ^lmod%gcc@6.1.0-spack\n          ^lua@5.2:%gcc@6.1.0-spack\n          ^lua-luafilesystem\n          ^lua-luaposix\n          ^tcl\n      ^openblas%gcc@6.1.0-spack\n      ^papi%gcc@6.1.0-spack\n      ^petsc%gcc@6.1.0-spack+boost+hdf5+mpi~mumps\n          ^openblas%gcc@6.1.0-spack\n      ^simulationio%gcc@6.1.0-spack\n          ^swig\n\nConcretized\n------------------------------\nTraceback (most recent call last):\n  File \"/Users/eschnett/src/spack/bin/spack\", line 192, in <module>\n    main()\n  File \"/Users/eschnett/src/spack/bin/spack\", line 169, in main\n    return_val = command(parser, args)\n  File \"/Users/eschnett/src/spack/lib/spack/spack/cmd/spec.py\", line 57, in spec\n    spec.concretize()\n  File \"/Users/eschnett/src/spack/lib/spack/spack/spec.py\", line 1256, in concretize\n    self._expand_virtual_packages(),\n  File \"/Users/eschnett/src/spack/lib/spack/spack/spec.py\", line 1173, in _expand_virtual_packages\n    spec)\n  File \"/Users/eschnett/src/spack/lib/spack/spack/concretize.py\", line 127, in choose_virtual_or_external\n    strict = [spack.abi.compatible(c, abi_exemplar) for c in candidates]\n  File \"/Users/eschnett/src/spack/lib/spack/spack/abi.py\", line 126, in compatible\n    self.compiler_compatible(parent, child, loose=loosematch)\n  File \"/Users/eschnett/src/spack/lib/spack/spack/abi.py\", line 115, in compiler_compatible\n    self._gcc_compiler_compare(pversion, cversion)):\n  File \"/Users/eschnett/src/spack/lib/spack/llnl/util/lang.py\", line 187, in __call__\n    self.cache[args] = self.func(*args)\n  File \"/Users/eschnett/src/spack/lib/spack/spack/abi.py\", line 79, in _gcc_compiler_compare\n    plib = self._gcc_get_libstdcxx_version(pversion)\n  File \"/Users/eschnett/src/spack/lib/spack/llnl/util/lang.py\", line 187, in __call__\n    self.cache[args] = self.func(*args)\n  File \"/Users/eschnett/src/spack/lib/spack/spack/abi.py\", line 70, in _gcc_get_libstdcxx_version\n    libpath = os.readlink(output.strip())\nOSError: [Errno 2] No such file or directory: 'libstdc++.so'\n```\n\n", "before_files": [{"content": "##############################################################################\n# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.\n# Produced at the Lawrence Livermore National Laboratory.\n#\n# This file is part of Spack.\n# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.\n# LLNL-CODE-647188\n#\n# For details, see https://github.com/llnl/spack\n# Please also see the LICENSE file for our notice and the LGPL.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU Lesser General Public License (as\n# published by the Free Software Foundation) version 2.1, February 1999.\n#\n# This program is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and\n# conditions of the GNU Lesser General Public License for more details.\n#\n# You should have received a copy of the GNU Lesser General Public\n# License along with this program; if not, write to the Free Software\n# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n##############################################################################\n\nimport os\nimport spack\nimport spack.spec\nfrom spack.spec import CompilerSpec\nfrom spack.util.executable import Executable, ProcessError\nfrom llnl.util.lang import memoized\n\n\nclass ABI(object):\n    \"\"\"This class provides methods to test ABI compatibility between specs.\n       The current implementation is rather rough and could be improved.\"\"\"\n\n    def architecture_compatible(self, parent, child):\n        \"\"\"Return true if parent and child have ABI compatible targets.\"\"\"\n        return not parent.architecture or not child.architecture or \\\n            parent.architecture == child.architecture\n\n    @memoized\n    def _gcc_get_libstdcxx_version(self, version):\n        \"\"\"Returns gcc ABI compatibility info by getting the library version of\n           a compiler's libstdc++.so or libgcc_s.so\"\"\"\n        spec = CompilerSpec(\"gcc\", version)\n        compilers = spack.compilers.compilers_for_spec(spec)\n        if not compilers:\n            return None\n        compiler = compilers[0]\n        rungcc = None\n        libname = None\n        output = None\n        if compiler.cxx:\n            rungcc = Executable(compiler.cxx)\n            libname = \"libstdc++.so\"\n        elif compiler.cc:\n            rungcc = Executable(compiler.cc)\n            libname = \"libgcc_s.so\"\n        else:\n            return None\n        try:\n            output = rungcc(\"--print-file-name=%s\" % libname,\n                            return_output=True)\n        except ProcessError:\n            return None\n        if not output:\n            return None\n        libpath = os.readlink(output.strip())\n        if not libpath:\n            return None\n        return os.path.basename(libpath)\n\n    @memoized\n    def _gcc_compiler_compare(self, pversion, cversion):\n        \"\"\"Returns true iff the gcc version pversion and cversion\n          are ABI compatible.\"\"\"\n        plib = self._gcc_get_libstdcxx_version(pversion)\n        clib = self._gcc_get_libstdcxx_version(cversion)\n        if not plib or not clib:\n            return False\n        return plib == clib\n\n    def _intel_compiler_compare(self, pversion, cversion):\n        \"\"\"Returns true iff the intel version pversion and cversion\n           are ABI compatible\"\"\"\n\n        # Test major and minor versions.  Ignore build version.\n        if (len(pversion.version) < 2 or len(cversion.version) < 2):\n            return False\n        return pversion.version[:2] == cversion.version[:2]\n\n    def compiler_compatible(self, parent, child, **kwargs):\n        \"\"\"Return true if compilers for parent and child are ABI compatible.\"\"\"\n        if not parent.compiler or not child.compiler:\n            return True\n\n        if parent.compiler.name != child.compiler.name:\n            # Different compiler families are assumed ABI incompatible\n            return False\n\n        if kwargs.get('loose', False):\n            return True\n\n        # TODO: Can we move the specialized ABI matching stuff\n        # TODO: into compiler classes?\n        for pversion in parent.compiler.versions:\n            for cversion in child.compiler.versions:\n                # For a few compilers use specialized comparisons.\n                # Otherwise match on version match.\n                if pversion.satisfies(cversion):\n                    return True\n                elif (parent.compiler.name == \"gcc\" and\n                      self._gcc_compiler_compare(pversion, cversion)):\n                    return True\n                elif (parent.compiler.name == \"intel\" and\n                      self._intel_compiler_compare(pversion, cversion)):\n                    return True\n        return False\n\n    def compatible(self, parent, child, **kwargs):\n        \"\"\"Returns true iff a parent and child spec are ABI compatible\"\"\"\n        loosematch = kwargs.get('loose', False)\n        return self.architecture_compatible(parent, child) and \\\n            self.compiler_compatible(parent, child, loose=loosematch)\n", "path": "lib/spack/spack/abi.py"}], "after_files": [{"content": "##############################################################################\n# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.\n# Produced at the Lawrence Livermore National Laboratory.\n#\n# This file is part of Spack.\n# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.\n# LLNL-CODE-647188\n#\n# For details, see https://github.com/llnl/spack\n# Please also see the LICENSE file for our notice and the LGPL.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU Lesser General Public License (as\n# published by the Free Software Foundation) version 2.1, February 1999.\n#\n# This program is distributed in the hope that it will be useful, but\n# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and\n# conditions of the GNU Lesser General Public License for more details.\n#\n# You should have received a copy of the GNU Lesser General Public\n# License along with this program; if not, write to the Free Software\n# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n##############################################################################\n\nimport os\nimport spack\nimport spack.spec\nfrom spack.spec import CompilerSpec\nfrom spack.util.executable import Executable, ProcessError\nfrom llnl.util.lang import memoized\n\n\nclass ABI(object):\n    \"\"\"This class provides methods to test ABI compatibility between specs.\n       The current implementation is rather rough and could be improved.\"\"\"\n\n    def architecture_compatible(self, parent, child):\n        \"\"\"Return true if parent and child have ABI compatible targets.\"\"\"\n        return not parent.architecture or not child.architecture or \\\n            parent.architecture == child.architecture\n\n    @memoized\n    def _gcc_get_libstdcxx_version(self, version):\n        \"\"\"Returns gcc ABI compatibility info by getting the library version of\n           a compiler's libstdc++.so or libgcc_s.so\"\"\"\n        spec = CompilerSpec(\"gcc\", version)\n        compilers = spack.compilers.compilers_for_spec(spec)\n        if not compilers:\n            return None\n        compiler = compilers[0]\n        rungcc = None\n        libname = None\n        output = None\n        if compiler.cxx:\n            rungcc = Executable(compiler.cxx)\n            libname = \"libstdc++.\" + dso_suffix\n        elif compiler.cc:\n            rungcc = Executable(compiler.cc)\n            libname = \"libgcc_s.\" + dso_suffix\n        else:\n            return None\n        try:\n            output = rungcc(\"--print-file-name=%s\" % libname,\n                            return_output=True)\n        except ProcessError:\n            return None\n        if not output:\n            return None\n        libpath = os.readlink(output.strip())\n        if not libpath:\n            return None\n        return os.path.basename(libpath)\n\n    @memoized\n    def _gcc_compiler_compare(self, pversion, cversion):\n        \"\"\"Returns true iff the gcc version pversion and cversion\n          are ABI compatible.\"\"\"\n        plib = self._gcc_get_libstdcxx_version(pversion)\n        clib = self._gcc_get_libstdcxx_version(cversion)\n        if not plib or not clib:\n            return False\n        return plib == clib\n\n    def _intel_compiler_compare(self, pversion, cversion):\n        \"\"\"Returns true iff the intel version pversion and cversion\n           are ABI compatible\"\"\"\n\n        # Test major and minor versions.  Ignore build version.\n        if (len(pversion.version) < 2 or len(cversion.version) < 2):\n            return False\n        return pversion.version[:2] == cversion.version[:2]\n\n    def compiler_compatible(self, parent, child, **kwargs):\n        \"\"\"Return true if compilers for parent and child are ABI compatible.\"\"\"\n        if not parent.compiler or not child.compiler:\n            return True\n\n        if parent.compiler.name != child.compiler.name:\n            # Different compiler families are assumed ABI incompatible\n            return False\n\n        if kwargs.get('loose', False):\n            return True\n\n        # TODO: Can we move the specialized ABI matching stuff\n        # TODO: into compiler classes?\n        for pversion in parent.compiler.versions:\n            for cversion in child.compiler.versions:\n                # For a few compilers use specialized comparisons.\n                # Otherwise match on version match.\n                if pversion.satisfies(cversion):\n                    return True\n                elif (parent.compiler.name == \"gcc\" and\n                      self._gcc_compiler_compare(pversion, cversion)):\n                    return True\n                elif (parent.compiler.name == \"intel\" and\n                      self._intel_compiler_compare(pversion, cversion)):\n                    return True\n        return False\n\n    def compatible(self, parent, child, **kwargs):\n        \"\"\"Returns true iff a parent and child spec are ABI compatible\"\"\"\n        loosematch = kwargs.get('loose', False)\n        return self.architecture_compatible(parent, child) and \\\n            self.compiler_compatible(parent, child, loose=loosematch)\n", "path": "lib/spack/spack/abi.py"}]}