Repository: easybuilders/easybuild-easyblocks

Issue:
Latest suitesparse easyblock modified library paths and doesn't install CSparse libs 
Latest suitesparse easyblock modified library paths and doesn't install CSparse libs which might cause installations that depend on SuiteSparse to fail, installation of those should be modified to find the libraries. But the issue of the missing CSparse library remains. Why was this lib removed in [#3004](https://github.com/easybuilders/easybuild-easyblocks/pull/3004)? 
@appolloford

Installations that depend on SuiteSparse and might fail if not modified:
`AUGUSTUS`
`CVXOPT`
`Trilinos`
`PETSc`
`igraph`
`Octave`
`OpenSees`
`DOLFIN`
`FreeFEM`
`Yade`
`ARPACK++`
`pyGIMLi`


Discussion:
Installation of `PETSc` fails. Path to libs can be fixed but it also requires the CSparse lib.  
Hi, I found some description from the SuiteSparse README 

```
CSparse     a concise sparse matrix package, developed for my
            book, "Direct Methods for Sparse Linear Systems",
            published by SIAM.  Intended primarily for teaching.
            Note that the code is (c) Tim Davis, as stated in the book.
            For production, use CXSparse instead.  In particular, both
            CSparse and CXSparse have the same include filename: cs.h.
            This package is used for the built-in DMPERM in MATLAB.
            author: Tim Davis

CXSparse    CSparse Extended.  Includes support for complex matrices
            and both int or long integers.  Use this instead of CSparse
            for production use; it creates a libcsparse.so (or *dylib on
            the Mac) with the same name as CSparse.  It is a superset
            of CSparse.  Any code that links against CSparse should
            also be able to link against CXSparse instead.
            author: Tim Davis, David Bateman
```

CSparse looks like the only one which is not installed by cmake. Although I don't see a libcsparse.so from CXSparse (libcxsparse.so instead), I guess it does this intentionally to avoid some potential conflict with CXSparse. I am wondering whether the softwares in the list can be linked to CXSparse instead? Otherwise, I may copy those CSparse libs manually.
At least for `PETSc-3.19.2-foss-2022b.eb`. I can successfully install that without CSpase. (require editing petsc easyblock)

---
Success:
`AUGUSTUS/3.5.0-foss-2022b`
`CVXOPT-1.3.1-foss-2022a.eb` (require revising path in easyconfig)

Resolving patch:
diff --git a/easybuild/easyblocks/n/numpy.py b/easybuild/easyblocks/n/numpy.py
--- a/easybuild/easyblocks/n/numpy.py
+++ b/easybuild/easyblocks/n/numpy.py
@@ -183,23 +183,17 @@ def get_libs_for_mkl(varname):
 
         suitesparseroot = get_software_root('SuiteSparse')
         if suitesparseroot:
-            amddir = os.path.join(suitesparseroot, 'AMD')
-            umfpackdir = os.path.join(suitesparseroot, 'UMFPACK')
 
-            if not os.path.exists(amddir) or not os.path.exists(umfpackdir):
-                raise EasyBuildError("Expected SuiteSparse subdirectories are not both there: %s, %s",
-                                     amddir, umfpackdir)
-            else:
-                extrasiteconfig += '\n'.join([
-                    "[amd]",
-                    "library_dirs = %s" % os.path.join(amddir, 'Lib'),
-                    "include_dirs = %s" % os.path.join(amddir, 'Include'),
-                    "amd_libs = amd",
-                    "[umfpack]",
-                    "library_dirs = %s" % os.path.join(umfpackdir, 'Lib'),
-                    "include_dirs = %s" % os.path.join(umfpackdir, 'Include'),
-                    "umfpack_libs = umfpack",
-                ])
+            extrasiteconfig += '\n'.join([
+                "[amd]",
+                "library_dirs = %s" % os.path.join(suitesparseroot, 'lib'),
+                "include_dirs = %s" % os.path.join(suitesparseroot, 'include'),
+                "amd_libs = amd",
+                "[umfpack]",
+                "library_dirs = %s" % os.path.join(suitesparseroot, 'lib'),
+                "include_dirs = %s" % os.path.join(suitesparseroot, 'include'),
+                "umfpack_libs = umfpack",
+            ])
 
         self.sitecfg = '\n'.join([self.sitecfg, extrasiteconfig])
 
diff --git a/easybuild/easyblocks/p/petsc.py b/easybuild/easyblocks/p/petsc.py
--- a/easybuild/easyblocks/p/petsc.py
+++ b/easybuild/easyblocks/p/petsc.py
@@ -29,12 +29,12 @@
 """
 import os
 import re
-from easybuild.tools import LooseVersion
 
 import easybuild.tools.environment as env
 import easybuild.tools.toolchain as toolchain
 from easybuild.easyblocks.generic.configuremake import ConfigureMake
 from easybuild.framework.easyconfig import BUILD, CUSTOM
+from easybuild.tools import LooseVersion
 from easybuild.tools.build_log import EasyBuildError
 from easybuild.tools.filetools import symlink, apply_regex_substitutions
 from easybuild.tools.modules import get_software_root, get_software_version
@@ -254,26 +254,21 @@ def configure_step(self):
                     ss_libs = ["UMFPACK", "KLU", "CHOLMOD", "BTF", "CCOLAMD", "COLAMD", "CAMD", "AMD"]
                     # More libraries added after version 3.17
                     if LooseVersion(self.version) >= LooseVersion("3.17"):
-                        # specified order of libs matters!
                         ss_libs = ["UMFPACK", "KLU", "SPQR", "CHOLMOD", "BTF", "CCOLAMD",
-                                   "COLAMD", "CSparse", "CXSparse", "LDL", "RBio",
-                                   "SLIP_LU", "CAMD", "AMD"]
+                                   "COLAMD", "CXSparse", "LDL", "RBio", "SLIP_LU", "CAMD", "AMD"]
 
-                    suitesparse_inc = [os.path.join(suitesparse, x, "Include")
-                                       for x in ss_libs]
-                    suitesparse_inc.append(os.path.join(suitesparse, "SuiteSparse_config"))
-                    inc_spec = "-include=[%s]" % ','.join(suitesparse_inc)
+                    suitesparse_inc = os.path.join(suitesparse, "include")
+                    inc_spec = "-include=[%s]" % suitesparse_inc
 
-                    suitesparse_libs = [os.path.join(suitesparse, x, "Lib", "lib%s.a" % x.replace("_", "").lower())
+                    suitesparse_libs = [os.path.join(suitesparse, "lib", "lib%s.so" % x.replace("_", "").lower())
                                         for x in ss_libs]
-                    suitesparse_libs.append(os.path.join(suitesparse, "SuiteSparse_config", "libsuitesparseconfig.a"))
                     lib_spec = "-lib=[%s]" % ','.join(suitesparse_libs)
                 else:
                     # CHOLMOD and UMFPACK are part of SuiteSparse (PETSc < 3.5)
                     withdep = "--with-umfpack"
-                    inc_spec = "-include=%s" % os.path.join(suitesparse, "UMFPACK", "Include")
+                    inc_spec = "-include=%s" % os.path.join(suitesparse, "include")
                     # specified order of libs matters!
-                    umfpack_libs = [os.path.join(suitesparse, x, "Lib", "lib%s.a" % x.lower())
+                    umfpack_libs = [os.path.join(suitesparse, "lib", "lib%s.a" % x.lower())
                                     for x in ["UMFPACK", "CHOLMOD", "COLAMD", "AMD"]]
                     lib_spec = "-lib=[%s]" % ','.join(umfpack_libs)
 
diff --git a/easybuild/easyblocks/t/trilinos.py b/easybuild/easyblocks/t/trilinos.py
--- a/easybuild/easyblocks/t/trilinos.py
+++ b/easybuild/easyblocks/t/trilinos.py
@@ -31,11 +31,10 @@
 import random
 import re
 
-from easybuild.tools import LooseVersion
-
 import easybuild.tools.toolchain as toolchain
 from easybuild.easyblocks.generic.cmakemake import CMakeMake
 from easybuild.framework.easyconfig import CUSTOM
+from easybuild.tools import LooseVersion
 from easybuild.tools.build_log import EasyBuildError
 from easybuild.tools.config import build_path
 from easybuild.tools.filetools import mkdir, remove_dir, symlink
@@ -144,14 +143,12 @@ def configure_step(self):
         if suitesparse:
             self.cfg.update('configopts', "-DTPL_ENABLE_UMFPACK:BOOL=ON")
             self.cfg.update('configopts', "-DTPL_ENABLE_Cholmod:BOOL=ON")
-            incdirs, libdirs, libnames = [], [], []
-            for lib in ["UMFPACK", "CHOLMOD", "COLAMD", "AMD", "CCOLAMD", "CAMD"]:
-                incdirs.append(os.path.join(suitesparse, lib, "Include"))
-                libdirs.append(os.path.join(suitesparse, lib, "Lib"))
-                libnames.append(lib.lower())
+            incdir = os.path.join(suitesparse, "include")
+            libdir = os.path.join(suitesparse, "lib")
+            libs = ["UMFPACK", "CHOLMOD", "COLAMD", "AMD", "CCOLAMD", "CAMD"]
+            libnames = [lib.lower() for lib in libs]
 
             # add SuiteSparse config lib, it is in recent versions of suitesparse
-            libdirs.append(os.path.join(suitesparse, 'SuiteSparse_config'))
             libnames.append('suitesparseconfig')
             # because of "SuiteSparse_config.c:function SuiteSparse_tic: error: undefined reference to 'clock_gettime'"
             libnames.append('rt')
@@ -162,11 +159,11 @@ def configure_step(self):
             # see https://answers.launchpad.net/dorsal/+question/223167
             libnames.append('libmetis.a')
 
-            self.cfg.update('configopts', '-DUMFPACK_INCLUDE_DIRS:PATH="%s"' % ';'.join(incdirs))
-            self.cfg.update('configopts', '-DUMFPACK_LIBRARY_DIRS:PATH="%s"' % ';'.join(libdirs))
+            self.cfg.update('configopts', '-DUMFPACK_INCLUDE_DIRS:PATH="%s"' % incdir)
+            self.cfg.update('configopts', '-DUMFPACK_LIBRARY_DIRS:PATH="%s"' % libdir)
             self.cfg.update('configopts', '-DUMFPACK_LIBRARY_NAMES:STRING="%s"' % ';'.join(libnames))
-            self.cfg.update('configopts', '-DCholmod_INCLUDE_DIRS:PATH="%s"' % ';'.join(incdirs))
-            self.cfg.update('configopts', '-DCholmod_LIBRARY_DIRS:PATH="%s"' % ';'.join(libdirs))
+            self.cfg.update('configopts', '-DCholmod_INCLUDE_DIRS:PATH="%s"' % incdir)
+            self.cfg.update('configopts', '-DCholmod_LIBRARY_DIRS:PATH="%s"' % libdir)
             self.cfg.update('configopts', '-DCholmod_LIBRARY_NAMES:STRING="%s"' % ';'.join(libnames))
 
         # BLACS


Test patch: