diff options
-rw-r--r-- | lib/spack/spack/build_systems/oneapi.py | 41 | ||||
-rw-r--r-- | lib/spack/spack/pkgkit.py | 6 | ||||
-rw-r--r-- | var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py | 33 |
3 files changed, 73 insertions, 7 deletions
diff --git a/lib/spack/spack/build_systems/oneapi.py b/lib/spack/spack/build_systems/oneapi.py index 0ff77d729b..e50e921915 100644 --- a/lib/spack/spack/build_systems/oneapi.py +++ b/lib/spack/spack/build_systems/oneapi.py @@ -99,7 +99,13 @@ class IntelOneApiPackage(Package): class IntelOneApiLibraryPackage(IntelOneApiPackage): - """Base class for Intel oneAPI library packages.""" + """Base class for Intel oneAPI library packages. + + Contains some convenient default implementations for libraries. + Implement the method directly in the package if something + different is needed. + + """ @property def headers(self): @@ -111,3 +117,36 @@ class IntelOneApiLibraryPackage(IntelOneApiPackage): lib_path = join_path(self.component_path, 'lib', 'intel64') lib_path = lib_path if isdir(lib_path) else dirname(lib_path) return find_libraries('*', root=lib_path, shared=True, recursive=True) + + +class IntelOneApiStaticLibraryList(object): + """Provides ld_flags when static linking is needed + + Oneapi puts static and dynamic libraries in the same directory, so + -l will default to finding the dynamic library. Use absolute + paths, as recommended by oneapi documentation. + + Allow both static and dynamic libraries to be supplied by the + package. + """ + + def __init__(self, static_libs, dynamic_libs): + self.static_libs = static_libs + self.dynamic_libs = dynamic_libs + + @property + def directories(self): + return self.dynamic_libs.directories + + @property + def search_flags(self): + return self.dynamic_libs.search_flags + + @property + def link_flags(self): + return '-Wl,--start-group {0} -Wl,--end-group {1}'.format( + ' '.join(self.static_libs.libraries), self.dynamic_libs.link_flags) + + @property + def ld_flags(self): + return '{0} {1}'.format(self.search_flags, self.link_flags) diff --git a/lib/spack/spack/pkgkit.py b/lib/spack/spack/pkgkit.py index fc056f14ad..19c5fac500 100644 --- a/lib/spack/spack/pkgkit.py +++ b/lib/spack/spack/pkgkit.py @@ -29,7 +29,11 @@ from spack.build_systems.makefile import MakefilePackage from spack.build_systems.maven import MavenPackage from spack.build_systems.meson import MesonPackage from spack.build_systems.octave import OctavePackage -from spack.build_systems.oneapi import IntelOneApiLibraryPackage, IntelOneApiPackage +from spack.build_systems.oneapi import ( + IntelOneApiLibraryPackage, + IntelOneApiPackage, + IntelOneApiStaticLibraryList, +) from spack.build_systems.perl import PerlPackage from spack.build_systems.python import PythonPackage from spack.build_systems.qmake import QMakePackage diff --git a/var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py b/var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py index 44d443f7b9..581c015b76 100644 --- a/var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py +++ b/var/spack/repos/builtin/packages/intel-oneapi-mkl/package.py @@ -34,13 +34,18 @@ class IntelOneapiMkl(IntelOneApiLibraryPackage): sha256='818b6bd9a6c116f4578cda3151da0612ec9c3ce8b2c8a64730d625ce5b13cc0c', expand=False) + variant('shared', default=True, description='Builds shared library') variant('ilp64', default=False, description='Build with ILP64 support') + variant('cluster', default=False, + description='Build with cluster support: scalapack, blacs, etc') depends_on('intel-oneapi-tbb') + # cluster libraries need mpi + depends_on('mpi', when='+cluster') provides('fftw-api@3') - provides('scalapack') + provides('scalapack', when='+cluster') provides('mkl') provides('lapack') provides('blas') @@ -59,13 +64,31 @@ class IntelOneapiMkl(IntelOneApiLibraryPackage): include_path = join_path(self.component_path, 'include') return find_headers('*', include_path) + # provide cluster libraries if +cluster variant is used or + # the scalapack virtual package was requested + def cluster(self): + return '+cluster' in self.spec + @property def libs(self): - mkl_libs = [self.xlp64_lib('libmkl_intel'), 'libmkl_sequential', 'libmkl_core'] + shared = '+shared' in self.spec + mkl_libs = [] + if self.cluster(): + mkl_libs += [self.xlp64_lib('libmkl_scalapack'), + 'libmkl_cdft_core'] + mkl_libs += [self.xlp64_lib('libmkl_intel'), + 'libmkl_sequential', + 'libmkl_core'] + if self.cluster(): + mkl_libs += [self.xlp64_lib('libmkl_blacs_intelmpi')] libs = find_libraries(mkl_libs, - join_path(self.component_path, 'lib', 'intel64')) - libs += find_system_libraries(['libpthread', 'libm', 'libdl']) - return libs + join_path(self.component_path, 'lib', 'intel64'), + shared=shared) + system_libs = find_system_libraries(['libpthread', 'libm', 'libdl']) + if shared: + return libs + system_libs + else: + return IntelOneApiStaticLibraryList(libs, system_libs) def setup_dependent_build_environment(self, env, dependent_spec): env.set('MKLROOT', self.component_path) |