|
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
# Copyright 2013-2020 The Meson development team
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
import functools
|
|
|
|
import os
|
|
|
|
import typing as T
|
|
|
|
|
|
|
|
from ..mesonlib import OptionKey
|
|
|
|
from .base import DependencyMethods
|
|
|
|
from .cmake import CMakeDependency
|
|
|
|
from .detect import packages
|
|
|
|
from .pkgconfig import PkgConfigDependency
|
|
|
|
from .factory import factory_methods
|
|
|
|
|
|
|
|
if T.TYPE_CHECKING:
|
|
|
|
from ..environment import Environment
|
|
|
|
from ..mesonlib import MachineChoice
|
|
|
|
from .factory import DependencyGenerator
|
|
|
|
|
|
|
|
|
|
|
|
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE})
|
|
|
|
def scalapack_factory(env: 'Environment', for_machine: 'MachineChoice',
|
|
|
|
kwargs: T.Dict[str, T.Any],
|
|
|
|
methods: T.List[DependencyMethods]) -> T.List['DependencyGenerator']:
|
|
|
|
candidates: T.List['DependencyGenerator'] = []
|
|
|
|
|
|
|
|
if DependencyMethods.PKGCONFIG in methods:
|
|
|
|
static_opt = kwargs.get('static', env.coredata.get_option(OptionKey('prefer_static')))
|
|
|
|
mkl = 'mkl-static-lp64-iomp' if static_opt else 'mkl-dynamic-lp64-iomp'
|
|
|
|
candidates.append(functools.partial(
|
|
|
|
MKLPkgConfigDependency, mkl, env, kwargs))
|
|
|
|
|
|
|
|
for pkg in ['scalapack-openmpi', 'scalapack']:
|
|
|
|
candidates.append(functools.partial(
|
|
|
|
PkgConfigDependency, pkg, env, kwargs))
|
|
|
|
|
|
|
|
if DependencyMethods.CMAKE in methods:
|
|
|
|
candidates.append(functools.partial(
|
|
|
|
CMakeDependency, 'Scalapack', env, kwargs))
|
|
|
|
|
|
|
|
return candidates
|
|
|
|
|
|
|
|
packages['scalapack'] = scalapack_factory
|
|
|
|
|
|
|
|
|
|
|
|
class MKLPkgConfigDependency(PkgConfigDependency):
|
|
|
|
|
|
|
|
"""PkgConfigDependency for Intel MKL.
|
|
|
|
|
|
|
|
MKL's pkg-config is pretty much borked in every way. We need to apply a
|
|
|
|
bunch of fixups to make it work correctly.
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any],
|
|
|
|
language: T.Optional[str] = None):
|
|
|
|
_m = os.environ.get('MKLROOT')
|
|
|
|
self.__mklroot = Path(_m).resolve() if _m else None
|
|
|
|
|
|
|
|
# We need to call down into the normal super() method even if we don't
|
|
|
|
# find mklroot, otherwise we won't have all of the instance variables
|
|
|
|
# initialized that meson expects.
|
|
|
|
super().__init__(name, env, kwargs, language=language)
|
|
|
|
|
|
|
|
# Doesn't work with gcc on windows, but does on Linux
|
|
|
|
if (not self.__mklroot or (env.machines[self.for_machine].is_windows()
|
|
|
|
and self.clib_compiler.id == 'gcc')):
|
|
|
|
self.is_found = False
|
|
|
|
|
|
|
|
# This can happen either because we're using GCC, we couldn't find the
|
|
|
|
# mklroot, or the pkg-config couldn't find it.
|
|
|
|
if not self.is_found:
|
|
|
|
return
|
|
|
|
|
|
|
|
assert self.version != '', 'This should not happen if we didn\'t return above'
|
|
|
|
|
|
|
|
if self.version == 'unknown':
|
|
|
|
# At least by 2020 the version is in the pkg-config, just not with
|
|
|
|
# the correct name
|
|
|
|
v = self.get_variable(pkgconfig='Version', default_value='')
|
|
|
|
|
|
|
|
if not v and self.__mklroot:
|
|
|
|
try:
|
|
|
|
v = (
|
|
|
|
self.__mklroot.as_posix()
|
|
|
|
.split('compilers_and_libraries_')[1]
|
|
|
|
.split('/', 1)[0]
|
|
|
|
)
|
|
|
|
except IndexError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
if v:
|
|
|
|
assert isinstance(v, str)
|
|
|
|
self.version = v
|
|
|
|
|
|
|
|
def _set_libs(self) -> None:
|
|
|
|
super()._set_libs()
|
|
|
|
|
|
|
|
if self.env.machines[self.for_machine].is_windows():
|
|
|
|
suffix = '.lib'
|
|
|
|
elif self.static:
|
|
|
|
suffix = '.a'
|
|
|
|
else:
|
|
|
|
suffix = ''
|
|
|
|
libdir = self.__mklroot / 'lib/intel64'
|
|
|
|
|
|
|
|
if self.clib_compiler.id == 'gcc':
|
|
|
|
for i, a in enumerate(self.link_args):
|
|
|
|
# only replace in filename, not in directory names
|
|
|
|
dirname, basename = os.path.split(a)
|
|
|
|
if 'mkl_intel_lp64' in basename:
|
|
|
|
basename = basename.replace('intel', 'gf')
|
|
|
|
self.link_args[i] = '/' + os.path.join(dirname, basename)
|
|
|
|
# MKL pkg-config omits scalapack
|
|
|
|
# be sure "-L" and "-Wl" are first if present
|
|
|
|
i = 0
|
|
|
|
for j, a in enumerate(self.link_args):
|
|
|
|
if a.startswith(('-L', '-Wl')):
|
|
|
|
i = j + 1
|
|
|
|
elif j > 3:
|
|
|
|
break
|
|
|
|
if self.env.machines[self.for_machine].is_windows() or self.static:
|
|
|
|
self.link_args.insert(
|
|
|
|
i, str(libdir / ('mkl_scalapack_lp64' + suffix))
|
|
|
|
)
|
|
|
|
self.link_args.insert(
|
|
|
|
i + 1, str(libdir / ('mkl_blacs_intelmpi_lp64' + suffix))
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.link_args.insert(i, '-lmkl_scalapack_lp64')
|
|
|
|
self.link_args.insert(i + 1, '-lmkl_blacs_intelmpi_lp64')
|
|
|
|
|
|
|
|
def _set_cargs(self) -> None:
|
|
|
|
allow_system = False
|
|
|
|
if self.language == 'fortran':
|
|
|
|
# gfortran doesn't appear to look in system paths for INCLUDE files,
|
|
|
|
# so don't allow pkg-config to suppress -I flags for system paths
|
|
|
|
allow_system = True
|
dependencies: allow get_variable to define multiple pkgconfig defines
It was previously impossible to do this:
```
dep.get_pkgconfig_variable(
'foo',
define_variable: ['prefix', '/usr', 'datadir', '/usr/share'],
)
```
since get_pkgconfig_variable mandated exactly two (if any) arguments.
However, you could do this:
```
dep.get_variable(
'foo',
pkgconfig_define: ['prefix', '/usr', 'datadir', '/usr/share'],
)
```
It would silently do the wrong thing, by defining "prefix" as
`/usr=datadir=/usr/share`, which might not "matter" if only datadir was
used in the "foo" variable as the unmodified value might be adequate.
The actual intention of anyone writing such a meson.build is that they
aren't sure whether the .pc file uses ${prefix} or ${datadir} (or which
one gets used, might have changed between versions of that .pc file,
even).
A recent refactor made this into a hard error, which broke some projects
that were doing this and inadvertently depending on some .pc file that
only used the second variable. (This was "fine" since the result was
essentially meaningful, and even resulted in behavior identical to the
intended behavior if both projects were installed into the same prefix
-- in which case there's nothing to remap.)
Re-allow this. There are two ways we could re-allow this:
- ignore it with a warning
- add a new feature to allow actually doing this
Since the use case which triggered this bug actually has a pretty good
reason to want to do this, it makes sense to add the new feature.
Fixes https://bugs.gentoo.org/916576
Fixes https://github.com/containers/bubblewrap/issues/609
1 year ago
|
|
|
cflags = self.pkgconfig.cflags(self.name, allow_system, define_variable=(('prefix', self.__mklroot.as_posix()),))
|
|
|
|
self.compile_args = self._convert_mingw_paths(cflags)
|