# Buggy code
def install(self, spec, prefix):
    options = [
        "--with-ssl=0",
        "--download-c2html=0",
        "--download-sowing=0",
        "--download-hwloc=0",
        "CFLAGS=%s" % " ".join(spec.compiler_flags["cflags"]),
        "FFLAGS=%s" % " ".join(spec.compiler_flags["fflags"]),
        "CXXFLAGS=%s" % " ".join(spec.compiler_flags["cxxflags"]),
    ]
    options.extend(self.mpi_dependent_options())
    options.extend(
        [
            "--with-precision=%s" % ("double" if "+double" in spec else "single"),
            "--with-scalar-type=%s" % ("complex" if "+complex" in spec else "real"),
            "--with-shared-libraries=%s" % ("1" if "+shared" in spec else "0"),
            "--with-debugging=%s" % ("1" if "+debug" in spec else "0"),
            "--with-64-bit-indices=%s" % ("1" if "+int64" in spec else "0"),
        ]
    )
    if "+debug" not in spec:
        options.extend(["COPTFLAGS=", "FOPTFLAGS=", "CXXOPTFLAGS="])

    # Make sure we use exactly the same Blas/Lapack libraries
    # across the DAG. To that end list them explicitly
    lapack_blas = spec["lapack"].libs + spec["blas"].libs
    options.extend(["--with-blas-lapack-lib=%s" % lapack_blas.joined()])

    if "+knl" in spec:
        options.append("--with-avx-512-kernels")
        options.append("--with-memalign=64")
    if "+X" in spec:
        options.append("--with-x=1")
    else:
        options.append("--with-x=0")

    if "trilinos" in spec:
        options.append("--with-cxx-dialect=C++11")
        if spec.satisfies("^trilinos+boost"):
            options.append("--with-boost=1")

    if self.spec.satisfies("clanguage=C++"):
        options.append("--with-clanguage=C++")
    else:
        options.append("--with-clanguage=C")

    # PETSc depends on scalapack when '+mumps+mpi~int64' (see depends())
    # help PETSc pick up Scalapack from MKL
    if spec.satisfies("+mumps+mpi~int64"):
        scalapack = spec["scalapack"].libs
        options.extend(
            ["--with-scalapack-lib=%s" % scalapack.joined(), "--with-scalapack=1"]
        )
    else:
        options.extend(["--with-scalapack=0"])

    # Activates library support if needed
    for library in ("metis", "hdf5", "hypre", "parmetis", "mumps", "trilinos", "fftw"):
        options.append(
            "--with-{library}={value}".format(
                library=library, value=("1" if library in spec else "0")
            )
        )
        if library in spec:
            options.append(
                "--with-{library}-dir={path}".format(
                    library=library, path=spec[library].prefix
                )
            )
    # PETSc does not pick up SuperluDist from the dir as they look for
    # superlu_dist_4.1.a
    if "superlu-dist" in spec:
        if spec.satisfies("@3.10.3:"):
            options.append("--with-cxx-dialect=C++11")
        options.extend(
            [
                "--with-superlu_dist-include=%s" % spec["superlu-dist"].prefix.include,
                "--with-superlu_dist-lib=%s"
                % join_path(spec["superlu-dist"].prefix.lib, "libsuperlu_dist.a"),
                "--with-superlu_dist=1",
            ]
        )
    else:
        options.append("--with-superlu_dist=0")
    # SuiteSparse: configuring using '--with-suitesparse-dir=...' has some
    # issues, so specify directly the include path and the libraries.
    if "+suite-sparse" in spec:
        ss_spec = (
            "suite-sparse:umfpack,klu,cholmod,btf,ccolamd,colamd,"
            "camd,amd,suitesparseconfig"
        )
        options.extend(
            [
                "--with-suitesparse-include=%s" % spec[ss_spec].prefix.include,
                "--with-suitesparse-lib=%s" % spec[ss_spec].libs.joined(),
                "--with-suitesparse=1",
            ]
        )
    else:
        options.append("--with-suitesparse=0")

    # zlib: configuring using '--with-zlib-dir=...' has some issues with
    # SuiteSparse so specify directly the include path and the libraries.
    if "zlib" in spec:
        options.extend(
            [
                "--with-zlib-include=%s" % spec["zlib"].prefix.include,
                "--with-zlib-lib=%s" % spec["zlib"].libs.ld_flags,
                "--with-zlib=1",
            ]
        )
    else:
        options.append("--with-zlib=0")

    python("configure", "--prefix=%s" % prefix, *options)

    # PETSc has its own way of doing parallel make.
    make("MAKE_NP=%s" % make_jobs, parallel=False)
    make("install")

    # solve Poisson equation in 2D to make sure nothing is broken:
    if ("mpi" in spec) and self.run_tests:
        with working_dir("src/ksp/ksp/examples/tutorials"):
            env["PETSC_DIR"] = self.prefix
            cc = Executable(spec["mpi"].mpicc)
            cc(
                "ex50.c",
                "-I%s" % prefix.include,
                "-L%s" % prefix.lib,
                "-lpetsc",
                "-lm",
                "-o",
                "ex50",
            )
            run = Executable(join_path(spec["mpi"].prefix.bin, "mpirun"))
            # For Spectrum MPI, if -np is omitted, the default behavior is
            # to assign one process per process slot, where the default
            # process slot allocation is one per core. On systems with
            # many cores, the number of processes can exceed the size of
            # the grid specified when the testcase is run and the test case
            # fails. Specify a small number of processes to prevent
            # failure.
            # For more information about Spectrum MPI invocation, see URL
            # https://www.ibm.com/support/knowledgecenter/en/SSZTET_10.1.0/smpi02/smpi02_mpirun_options.html
            if "spectrum-mpi" in spec:
                run.add_default_arg("-np")
                run.add_default_arg("4")
            run("ex50", "-da_grid_x", "4", "-da_grid_y", "4")
            if "superlu-dist" in spec:
                run(
                    "ex50",
                    "-da_grid_x",
                    "4",
                    "-da_grid_y",
                    "4",
                    "-pc_type",
                    "lu",
                    "-pc_factor_mat_solver_package",
                    "superlu_dist",
                )

            if "mumps" in spec:
                run(
                    "ex50",
                    "-da_grid_x",
                    "4",
                    "-da_grid_y",
                    "4",
                    "-pc_type",
                    "lu",
                    "-pc_factor_mat_solver_package",
                    "mumps",
                )

            if "hypre" in spec:
                run(
                    "ex50",
                    "-da_grid_x",
                    "4",
                    "-da_grid_y",
                    "4",
                    "-pc_type",
                    "hypre",
                    "-pc_hypre_type",
                    "boomeramg",
                )


# Traceback (ImportError)
hron@r0d0$ python
Python 3.6.5 (default, Feb  9 2019, 12:35:34)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
import sys
import petsc4py
petsc4py.init(sys.argv)
import matplotlib.pyplot as plt
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/pkg/Installs/linux-ubuntu16.04-x86_64-gcc7.4.0/py-matplotlib/3.0.0/56bf2zhzyqlj2lpa/lib/python3.6/site-packages/matplotlib/pyplot.py", line 32, in <module>
import matplotlib.colorbar
File "/usr/local/pkg/Installs/linux-ubuntu16.04-x86_64-gcc7.4.0/py-matplotlib/3.0.0/56bf2zhzyqlj2lpa/lib/python3.6/site-packages/matplotlib/colorbar.py", line 32, in <module>
import matplotlib.contour as contour
File "/usr/local/pkg/Installs/linux-ubuntu16.04-x86_64-gcc7.4.0/py-matplotlib/3.0.0/56bf2zhzyqlj2lpa/lib/python3.6/site-packages/matplotlib/contour.py", line 18, in <module>
import matplotlib.font_manager as font_manager
File "/usr/local/pkg/Installs/linux-ubuntu16.04-x86_64-gcc7.4.0/py-matplotlib/3.0.0/56bf2zhzyqlj2lpa/lib/python3.6/site-packages/matplotlib/font_manager.py", line 48, in <module>
from matplotlib import afm, cbook, ft2font, rcParams, get_cachedir
ImportError: /lib/x86_64-linux-gnu/libz.so.1: version `ZLIB_1.2.9' not found (required by /usr/local/pkg/Installs/linux-ubuntu16.04-x86_64-gcc7.4.0/libpng/1.6.34/uzwwmyb42qhkd7jr/lib/libpng16.so.16)

# Fixed code
def install(self, spec, prefix):
    options = [
        "--with-ssl=0",
        "--download-c2html=0",
        "--download-sowing=0",
        "--download-hwloc=0",
        "CFLAGS=%s" % " ".join(spec.compiler_flags["cflags"]),
        "FFLAGS=%s" % " ".join(spec.compiler_flags["fflags"]),
        "CXXFLAGS=%s" % " ".join(spec.compiler_flags["cxxflags"]),
    ]
    options.extend(self.mpi_dependent_options())
    options.extend(
        [
            "--with-precision=%s" % ("double" if "+double" in spec else "single"),
            "--with-scalar-type=%s" % ("complex" if "+complex" in spec else "real"),
            "--with-shared-libraries=%s" % ("1" if "+shared" in spec else "0"),
            "--with-debugging=%s" % ("1" if "+debug" in spec else "0"),
            "--with-64-bit-indices=%s" % ("1" if "+int64" in spec else "0"),
        ]
    )
    if "+debug" not in spec:
        options.extend(["COPTFLAGS=", "FOPTFLAGS=", "CXXOPTFLAGS="])

    # Make sure we use exactly the same Blas/Lapack libraries
    # across the DAG. To that end list them explicitly
    lapack_blas = spec["lapack"].libs + spec["blas"].libs
    options.extend(["--with-blas-lapack-lib=%s" % lapack_blas.joined()])

    if "+knl" in spec:
        options.append("--with-avx-512-kernels")
        options.append("--with-memalign=64")
    if "+X" in spec:
        options.append("--with-x=1")
    else:
        options.append("--with-x=0")

    if "trilinos" in spec:
        options.append("--with-cxx-dialect=C++11")
        if spec.satisfies("^trilinos+boost"):
            options.append("--with-boost=1")

    if self.spec.satisfies("clanguage=C++"):
        options.append("--with-clanguage=C++")
    else:
        options.append("--with-clanguage=C")

    # PETSc depends on scalapack when '+mumps+mpi~int64' (see depends())
    # help PETSc pick up Scalapack from MKL
    if spec.satisfies("+mumps+mpi~int64"):
        scalapack = spec["scalapack"].libs
        options.extend(
            ["--with-scalapack-lib=%s" % scalapack.joined(), "--with-scalapack=1"]
        )
    else:
        options.extend(["--with-scalapack=0"])

    # Activates library support if needed
    for library in ("metis", "hdf5", "hypre", "parmetis", "mumps", "trilinos", "fftw"):
        options.append(
            "--with-{library}={value}".format(
                library=library, value=("1" if library in spec else "0")
            )
        )
        if library in spec:
            options.append(
                "--with-{library}-dir={path}".format(
                    library=library, path=spec[library].prefix
                )
            )
    # PETSc does not pick up SuperluDist from the dir as they look for
    # superlu_dist_4.1.a
    if "superlu-dist" in spec:
        if spec.satisfies("@3.10.3:"):
            options.append("--with-cxx-dialect=C++11")
        options.extend(
            [
                "--with-superlu_dist-include=%s" % spec["superlu-dist"].prefix.include,
                "--with-superlu_dist-lib=%s"
                % join_path(spec["superlu-dist"].prefix.lib, "libsuperlu_dist.a"),
                "--with-superlu_dist=1",
            ]
        )
    else:
        options.append("--with-superlu_dist=0")
    # SuiteSparse: configuring using '--with-suitesparse-dir=...' has some
    # issues, so specify directly the include path and the libraries.
    if "+suite-sparse" in spec:
        ss_spec = (
            "suite-sparse:umfpack,klu,cholmod,btf,ccolamd,colamd,"
            "camd,amd,suitesparseconfig"
        )
        options.extend(
            [
                "--with-suitesparse-include=%s" % spec[ss_spec].prefix.include,
                "--with-suitesparse-lib=%s" % spec[ss_spec].libs.joined(),
                "--with-suitesparse=1",
            ]
        )
    else:
        options.append("--with-suitesparse=0")

    # zlib: configuring using '--with-zlib-dir=...' has some issues with
    # SuiteSparse so specify directly the include path and the libraries.
    if "zlib" in spec:
        options.extend(
            [
                "--with-zlib-include=%s" % spec["zlib"].prefix.include,
                "--with-zlib-lib=%s" % spec["zlib"].libs.joined(),
                "--with-zlib=1",
            ]
        )
    else:
        options.append("--with-zlib=0")

    python("configure", "--prefix=%s" % prefix, *options)

    # PETSc has its own way of doing parallel make.
    make("MAKE_NP=%s" % make_jobs, parallel=False)
    make("install")

    # solve Poisson equation in 2D to make sure nothing is broken:
    if ("mpi" in spec) and self.run_tests:
        with working_dir("src/ksp/ksp/examples/tutorials"):
            env["PETSC_DIR"] = self.prefix
            cc = Executable(spec["mpi"].mpicc)
            cc(
                "ex50.c",
                "-I%s" % prefix.include,
                "-L%s" % prefix.lib,
                "-lpetsc",
                "-lm",
                "-o",
                "ex50",
            )
            run = Executable(join_path(spec["mpi"].prefix.bin, "mpirun"))
            # For Spectrum MPI, if -np is omitted, the default behavior is
            # to assign one process per process slot, where the default
            # process slot allocation is one per core. On systems with
            # many cores, the number of processes can exceed the size of
            # the grid specified when the testcase is run and the test case
            # fails. Specify a small number of processes to prevent
            # failure.
            # For more information about Spectrum MPI invocation, see URL
            # https://www.ibm.com/support/knowledgecenter/en/SSZTET_10.1.0/smpi02/smpi02_mpirun_options.html
            if "spectrum-mpi" in spec:
                run.add_default_arg("-np")
                run.add_default_arg("4")
            run("ex50", "-da_grid_x", "4", "-da_grid_y", "4")
            if "superlu-dist" in spec:
                run(
                    "ex50",
                    "-da_grid_x",
                    "4",
                    "-da_grid_y",
                    "4",
                    "-pc_type",
                    "lu",
                    "-pc_factor_mat_solver_package",
                    "superlu_dist",
                )

            if "mumps" in spec:
                run(
                    "ex50",
                    "-da_grid_x",
                    "4",
                    "-da_grid_y",
                    "4",
                    "-pc_type",
                    "lu",
                    "-pc_factor_mat_solver_package",
                    "mumps",
                )

            if "hypre" in spec:
                run(
                    "ex50",
                    "-da_grid_x",
                    "4",
                    "-da_grid_y",
                    "4",
                    "-pc_type",
                    "hypre",
                    "-pc_hypre_type",
                    "boomeramg",
                )