dependencies: refactor to use methods properly

pull/6355/head
Michael Hirsch, Ph.D 5 years ago
parent 06821755d2
commit f1d370247f
No known key found for this signature in database
GPG Key ID: 6D23CDADAB0294F9
  1. 25
      mesonbuild/dependencies/coarrays.py
  2. 29
      mesonbuild/dependencies/hdf5.py
  3. 19
      mesonbuild/dependencies/misc.py
  4. 19
      mesonbuild/dependencies/mpi.py
  5. 8
      mesonbuild/dependencies/scalapack.py

@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from .base import CMakeDependency, ExternalDependency, PkgConfigDependency from ..mesonlib import listify
from .base import CMakeDependency, DependencyMethods, ExternalDependency, PkgConfigDependency
class CoarrayDependency(ExternalDependency): class CoarrayDependency(ExternalDependency):
@ -29,11 +30,13 @@ class CoarrayDependency(ExternalDependency):
kwargs['required'] = False kwargs['required'] = False
kwargs['silent'] = True kwargs['silent'] = True
self.is_found = False self.is_found = False
methods = listify(self.methods)
cid = self.get_compiler().get_id() cid = self.get_compiler().get_id()
if cid == 'gcc': if cid == 'gcc':
""" OpenCoarrays is the most commonly used method for Fortran Coarray with GCC """ """ OpenCoarrays is the most commonly used method for Fortran Coarray with GCC """
# first try pkg-config
if set([DependencyMethods.AUTO, DependencyMethods.PKGCONFIG]).intersection(methods):
for pkg in ['caf-openmpi', 'caf']: for pkg in ['caf-openmpi', 'caf']:
pkgdep = PkgConfigDependency(pkg, environment, kwargs, language=self.language) pkgdep = PkgConfigDependency(pkg, environment, kwargs, language=self.language)
if pkgdep.found(): if pkgdep.found():
@ -43,19 +46,25 @@ class CoarrayDependency(ExternalDependency):
self.is_found = True self.is_found = True
self.pcdep = pkgdep self.pcdep = pkgdep
return return
# second try CMake
if set([DependencyMethods.AUTO, DependencyMethods.CMAKE]).intersection(methods):
if not kwargs.get('modules'):
kwargs['modules'] = 'OpenCoarrays::caf_mpi' kwargs['modules'] = 'OpenCoarrays::caf_mpi'
cmakedep = CMakeDependency('OpenCoarrays', environment, kwargs) cmakedep = CMakeDependency('OpenCoarrays', environment, kwargs, language=self.language)
if cmakedep.found(): if cmakedep.found():
self.compile_args = cmakedep.get_compile_args() self.compile_args = cmakedep.get_compile_args()
self.link_args = cmakedep.get_link_args() self.link_args = cmakedep.get_link_args()
self.version = cmakedep.get_version() self.version = cmakedep.get_version()
self.is_found = True self.is_found = True
return return
# give up, just run as single image fallback
if DependencyMethods.AUTO in methods:
# fallback to single image
self.compile_args = ['-fcoarray=single'] self.compile_args = ['-fcoarray=single']
self.version = 'single image' self.version = 'single image (fallback)'
self.is_found = True self.is_found = True
return
elif cid == 'intel': elif cid == 'intel':
""" Coarrays are built into Intel compilers, no external library needed """ """ Coarrays are built into Intel compilers, no external library needed """
self.is_found = True self.is_found = True
@ -68,3 +77,7 @@ class CoarrayDependency(ExternalDependency):
elif cid == 'nagfor': elif cid == 'nagfor':
""" NAG doesn't require any special arguments for Coarray """ """ NAG doesn't require any special arguments for Coarray """
self.is_found = True self.is_found = True
@staticmethod
def get_methods():
return [DependencyMethods.AUTO, DependencyMethods.CMAKE, DependencyMethods.PKGCONFIG]

@ -15,11 +15,13 @@
# This file contains the detection logic for miscellaneous external dependencies. # This file contains the detection logic for miscellaneous external dependencies.
import subprocess import subprocess
import shutil
from pathlib import Path from pathlib import Path
from .. import mlog from .. import mlog
from ..mesonlib import split_args from ..mesonlib import split_args, listify
from .base import DependencyException, ExternalDependency, ExternalProgram, PkgConfigDependency from .base import (DependencyException, DependencyMethods, ExternalDependency, ExternalProgram,
PkgConfigDependency)
class HDF5Dependency(ExternalDependency): class HDF5Dependency(ExternalDependency):
@ -29,23 +31,23 @@ class HDF5Dependency(ExternalDependency):
kwargs['required'] = False kwargs['required'] = False
kwargs['silent'] = True kwargs['silent'] = True
self.is_found = False self.is_found = False
methods = listify(self.methods)
# 1. pkg-config if language not in ('c', 'cpp', 'fortran'):
raise DependencyException('Language {} is not supported with HDF5.'.format(language))
if set([DependencyMethods.AUTO, DependencyMethods.PKGCONFIG]).intersection(methods):
PCEXE = shutil.which('pkg-config')
if PCEXE:
pkgconfig_files = ['hdf5', 'hdf5-serial'] pkgconfig_files = ['hdf5', 'hdf5-serial']
# some distros put hdf5-1.2.3.pc with version number in .pc filename. # some distros put hdf5-1.2.3.pc with version number in .pc filename.
try: ret = subprocess.run([PCEXE, '--list-all'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
ret = subprocess.run(['pkg-config', '--list-all'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
universal_newlines=True) universal_newlines=True)
if ret.returncode == 0: if ret.returncode == 0:
for pkg in ret.stdout.split('\n'): for pkg in ret.stdout.split('\n'):
if pkg.startswith(('hdf5')): if pkg.startswith(('hdf5')):
pkgconfig_files.append(pkg.split(' ', 1)[0]) pkgconfig_files.append(pkg.split(' ', 1)[0])
pkgconfig_files = list(set(pkgconfig_files)) # dedupe pkgconfig_files = list(set(pkgconfig_files)) # dedupe
except FileNotFoundError:
# pkg-config was not available
pass
if language not in ('c', 'cpp', 'fortran'):
raise DependencyException('Language {} is not supported with HDF5.'.format(language))
for pkg in pkgconfig_files: for pkg in pkgconfig_files:
pkgdep = PkgConfigDependency(pkg, environment, kwargs, language=self.language) pkgdep = PkgConfigDependency(pkg, environment, kwargs, language=self.language)
@ -94,7 +96,7 @@ class HDF5Dependency(ExternalDependency):
self.pcdep = pkgdep self.pcdep = pkgdep
return return
# 2. compiler wrapper fallback if DependencyMethods.AUTO in methods:
wrappers = {'c': 'h5cc', 'cpp': 'h5c++', 'fortran': 'h5fc'} wrappers = {'c': 'h5cc', 'cpp': 'h5c++', 'fortran': 'h5fc'}
comp_args = [] comp_args = []
link_args = [] link_args = []
@ -121,3 +123,8 @@ class HDF5Dependency(ExternalDependency):
self.compile_args = comp_args self.compile_args = comp_args
self.link_args = link_args self.link_args = link_args
self.is_found = True self.is_found = True
return
@staticmethod
def get_methods():
return [DependencyMethods.AUTO, DependencyMethods.PKGCONFIG]

@ -39,12 +39,14 @@ class NetCDFDependency(ExternalDependency):
kwargs['required'] = False kwargs['required'] = False
kwargs['silent'] = True kwargs['silent'] = True
self.is_found = False self.is_found = False
methods = listify(self.methods)
pkgconfig_files = ['netcdf']
if language not in ('c', 'cpp', 'fortran'): if language not in ('c', 'cpp', 'fortran'):
raise DependencyException('Language {} is not supported with NetCDF.'.format(language)) raise DependencyException('Language {} is not supported with NetCDF.'.format(language))
if set([DependencyMethods.AUTO, DependencyMethods.PKGCONFIG]).intersection(methods):
pkgconfig_files = ['netcdf']
if language == 'fortran': if language == 'fortran':
pkgconfig_files.append('netcdf-fortran') pkgconfig_files.append('netcdf-fortran')
@ -60,6 +62,19 @@ class NetCDFDependency(ExternalDependency):
self.is_found = True self.is_found = True
self.pcdep.append(pkgdep) self.pcdep.append(pkgdep)
if set([DependencyMethods.AUTO, DependencyMethods.CMAKE]).intersection(methods):
cmakedep = CMakeDependency('NetCDF', environment, kwargs, language=self.language)
if cmakedep.found():
self.compile_args = cmakedep.get_compile_args()
self.link_args = cmakedep.get_link_args()
self.version = cmakedep.get_version()
self.is_found = True
return
@staticmethod
def get_methods():
return [DependencyMethods.AUTO, DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE]
class OpenMPDependency(ExternalDependency): class OpenMPDependency(ExternalDependency):
# Map date of specification release (which is the macro value) to a version. # Map date of specification release (which is the macro value) to a version.

@ -19,9 +19,10 @@ import subprocess
from .. import mlog from .. import mlog
from .. import mesonlib from .. import mesonlib
from ..mesonlib import split_args from ..mesonlib import split_args, listify
from ..environment import detect_cpu_family from ..environment import detect_cpu_family
from .base import DependencyException, ExternalDependency, ExternalProgram, PkgConfigDependency from .base import (DependencyException, DependencyMethods, ExternalDependency, ExternalProgram,
PkgConfigDependency)
class MPIDependency(ExternalDependency): class MPIDependency(ExternalDependency):
@ -32,6 +33,8 @@ class MPIDependency(ExternalDependency):
kwargs['required'] = False kwargs['required'] = False
kwargs['silent'] = True kwargs['silent'] = True
self.is_found = False self.is_found = False
methods = listify(self.methods)
env_vars = [] env_vars = []
default_wrappers = [] default_wrappers = []
pkgconfig_files = [] pkgconfig_files = []
@ -68,9 +71,8 @@ class MPIDependency(ExternalDependency):
else: else:
raise DependencyException('Language {} is not supported with MPI.'.format(language)) raise DependencyException('Language {} is not supported with MPI.'.format(language))
# 1. try pkg-config if set([DependencyMethods.AUTO, DependencyMethods.PKGCONFIG]).intersection(methods):
for pkg in pkgconfig_files: for pkg in pkgconfig_files:
try:
pkgdep = PkgConfigDependency(pkg, environment, kwargs, language=self.language) pkgdep = PkgConfigDependency(pkg, environment, kwargs, language=self.language)
if pkgdep.found(): if pkgdep.found():
self.compile_args = pkgdep.get_compile_args() self.compile_args = pkgdep.get_compile_args()
@ -79,10 +81,8 @@ class MPIDependency(ExternalDependency):
self.is_found = True self.is_found = True
self.pcdep = pkgdep self.pcdep = pkgdep
return return
except Exception:
pass
# 2. Try environment variables if DependencyMethods.AUTO in methods:
for var in env_vars: for var in env_vars:
if var in os.environ: if var in os.environ:
wrappers = [os.environ[var]] wrappers = [os.environ[var]]
@ -116,6 +116,7 @@ class MPIDependency(ExternalDependency):
if result is not None: if result is not None:
self.is_found = True self.is_found = True
self.version, self.compile_args, self.link_args = result self.version, self.compile_args, self.link_args = result
return
def _filter_compile_args(self, args: typing.Sequence[str]) -> typing.List[str]: def _filter_compile_args(self, args: typing.Sequence[str]) -> typing.List[str]:
""" """
@ -272,3 +273,7 @@ class MPIDependency(ExternalDependency):
return (None, return (None,
['-I' + incdir, '-I' + os.path.join(incdir, post)], ['-I' + incdir, '-I' + os.path.join(incdir, post)],
[os.path.join(libdir, 'msmpi.lib')]) [os.path.join(libdir, 'msmpi.lib')])
@staticmethod
def get_methods():
return [DependencyMethods.AUTO, DependencyMethods.PKGCONFIG]

@ -21,14 +21,14 @@ from .base import CMakeDependency, DependencyMethods, ExternalDependency, PkgCon
class ScalapackDependency(ExternalDependency): class ScalapackDependency(ExternalDependency):
def __init__(self, environment, kwargs: dict): def __init__(self, environment, kwargs: dict):
methods = mesonlib.listify(kwargs.get('method', 'auto'))
super().__init__('scalapack', environment, None, kwargs) super().__init__('scalapack', environment, None, kwargs)
kwargs['required'] = False kwargs['required'] = False
kwargs['silent'] = True kwargs['silent'] = True
self.is_found = False self.is_found = False
self.static = kwargs.get('static', False) self.static = kwargs.get('static', False)
methods = mesonlib.listify(self.methods)
if set(methods).intersection(['auto', 'pkg-config']): if set([DependencyMethods.AUTO, DependencyMethods.PKGCONFIG]).intersection(methods):
pkgconfig_files = [] pkgconfig_files = []
mklroot = None mklroot = None
is_gcc = self.clib_compiler.get_id() == 'gcc' is_gcc = self.clib_compiler.get_id() == 'gcc'
@ -106,8 +106,8 @@ class ScalapackDependency(ExternalDependency):
self.pcdep = pkgdep self.pcdep = pkgdep
return return
if set(methods).intersection(['auto', 'cmake']): if set([DependencyMethods.AUTO, DependencyMethods.CMAKE]).intersection(methods):
cmakedep = CMakeDependency('Scalapack', environment, kwargs) cmakedep = CMakeDependency('Scalapack', environment, kwargs, language=self.language)
if cmakedep.found(): if cmakedep.found():
self.compile_args = cmakedep.get_compile_args() self.compile_args = cmakedep.get_compile_args()
self.link_args = cmakedep.get_link_args() self.link_args = cmakedep.get_link_args()

Loading…
Cancel
Save