diff --git a/ciimage/Dockerfile b/ciimage/Dockerfile index 520ce0fb2..980ed5340 100644 --- a/ciimage/Dockerfile +++ b/ciimage/Dockerfile @@ -20,6 +20,7 @@ RUN sed -i '/^#\sdeb-src /s/^#//' "/etc/apt/sources.list" \ && apt-get -y install --no-install-recommends wine-stable \ && apt-get -y install llvm-dev libclang-dev \ && apt-get -y install libgcrypt11-dev \ +&& apt-get -y install libhdf5-dev \ && dub fetch urld && dub build urld --compiler=gdc \ && dub fetch dubtestproject \ && dub build dubtestproject:test1 --compiler=ldc2 \ diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md index e3fedc48b..4ff5a2a18 100644 --- a/docs/markdown/Dependencies.md +++ b/docs/markdown/Dependencies.md @@ -269,6 +269,17 @@ e = executable('testprog', 'test.cc', dependencies : gtest_dep) test('gtest test', e) ``` +## HDF5 +HDF5 is supported for C, C++ and Fortran. Because dependencies are +language-specific, you must specify the requested language using the +`language` keyword argument, i.e., + * `dependency('hdf5', language: 'c')` for the C HDF5 headers and libraries + * `dependency('hdf5', language: 'cpp')` for the C++ HDF5 headers and libraries + * `dependency('hdf5', language: 'fortran')` for the Fortran HDF5 headers and libraries + +Meson uses pkg-config to find HDF5. The standard low-level HDF5 function and the `HL` high-level HDF5 functions are linked for each language. + + ## libwmf *(added 0.44.0)* diff --git a/docs/markdown/snippets/hdf5.md b/docs/markdown/snippets/hdf5.md new file mode 100644 index 000000000..8ebb4c034 --- /dev/null +++ b/docs/markdown/snippets/hdf5.md @@ -0,0 +1,3 @@ +## HDF5 + +HDF5 support is added via pkg-config. diff --git a/mesonbuild/dependencies/__init__.py b/mesonbuild/dependencies/__init__.py index afe2a3b73..f5034db48 100644 --- a/mesonbuild/dependencies/__init__.py +++ b/mesonbuild/dependencies/__init__.py @@ -18,7 +18,7 @@ from .base import ( # noqa: F401 ExternalDependency, NotFoundDependency, ExternalLibrary, ExtraFrameworkDependency, InternalDependency, PkgConfigDependency, CMakeDependency, find_external_dependency, get_dep_identifier, packages, _packages_accept_language) from .dev import GMockDependency, GTestDependency, LLVMDependency, ValgrindDependency -from .misc import (MPIDependency, OpenMPDependency, Python3Dependency, ThreadDependency, PcapDependency, CupsDependency, LibWmfDependency, LibGCryptDependency) +from .misc import (HDF5Dependency, MPIDependency, OpenMPDependency, Python3Dependency, ThreadDependency, PcapDependency, CupsDependency, LibWmfDependency, LibGCryptDependency) from .platform import AppleFrameworks from .ui import GLDependency, GnuStepDependency, Qt4Dependency, Qt5Dependency, SDL2Dependency, WxDependency, VulkanDependency @@ -33,6 +33,7 @@ packages.update({ # From misc: 'boost': BoostDependency, 'mpi': MPIDependency, + 'hdf5': HDF5Dependency, 'openmp': OpenMPDependency, 'python3': Python3Dependency, 'threads': ThreadDependency, @@ -54,6 +55,7 @@ packages.update({ 'vulkan': VulkanDependency, }) _packages_accept_language.update({ + 'hdf5', 'mpi', 'openmp', }) diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index d881f0e06..1f74de494 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -2095,6 +2095,7 @@ display_name_map = { 'dub': 'DUB', 'gmock': 'GMock', 'gtest': 'GTest', + 'hdf5': 'HDF5', 'llvm': 'LLVM', 'mpi': 'MPI', 'openmp': 'OpenMP', diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 4a5795220..fb2b9db9f 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -14,14 +14,13 @@ # This file contains the detection logic for miscellaneous external dependencies. +from pathlib import Path import functools import os import re import shlex import sysconfig -from pathlib import Path - from .. import mlog from .. import mesonlib from ..environment import detect_cpu_family @@ -33,6 +32,50 @@ from .base import ( ) +class HDF5Dependency(ExternalDependency): + + def __init__(self, environment, kwargs): + language = kwargs.get('language', 'c') + super().__init__('hdf5', environment, language, kwargs) + kwargs['required'] = False + kwargs['silent'] = True + self.is_found = False + + pkgconfig_files = ['hdf5'] + + if language not in ('c', 'cpp', 'fortran'): + raise DependencyException('Language {} is not supported with HDF5.'.format(language)) + + for pkg in pkgconfig_files: + try: + pkgdep = PkgConfigDependency(pkg, environment, kwargs, language=self.language) + if pkgdep.found(): + self.compile_args = pkgdep.get_compile_args() + # derive needed libraries by language + link_args = pkgdep.get_link_args() + lang_link_args = [] + for larg in link_args: + lpath = Path(larg) + if lpath.is_file(): + if language == 'cpp': + lang_link_args.append(str(lpath.parent / (lpath.stem + '_hl_cpp' + lpath.suffix))) + lang_link_args.append(str(lpath.parent / (lpath.stem + '_cpp' + lpath.suffix))) + elif language == 'fortran': + lang_link_args.append(str(lpath.parent / (lpath.stem + 'hl_fortran' + lpath.suffix))) + lang_link_args.append(str(lpath.parent / (lpath.stem + '_fortran' + lpath.suffix))) + + # C is used by other languages + lang_link_args.append(str(lpath.parent / (lpath.stem + '_hl' + lpath.suffix))) + lang_link_args.append(larg) + + self.link_args = lang_link_args + self.version = pkgdep.get_version() + self.is_found = True + self.pcdep = pkgdep + break + except Exception: + pass + class MPIDependency(ExternalDependency): def __init__(self, environment, kwargs): diff --git a/test cases/frameworks/25 hdf5/main.c b/test cases/frameworks/25 hdf5/main.c new file mode 100644 index 000000000..4c46310e1 --- /dev/null +++ b/test cases/frameworks/25 hdf5/main.c @@ -0,0 +1,30 @@ +#include +#include + +#include "hdf5.h" + +int main(void) +{ +herr_t ier; +unsigned maj, min, rel; + +ier = H5open(); +if (ier) { + fprintf(stderr,"Unable to initialize HDF5: %d\n", ier); + return EXIT_FAILURE; +} + +ier = H5get_libversion(&maj, &min, &rel); +if (ier) { + fprintf(stderr,"HDF5 did not initialize!\n"); + return EXIT_FAILURE; +} +printf("C HDF5 version %d.%d.%d\n", maj, min, rel); + +ier = H5close(); +if (ier) { + fprintf(stderr,"Unable to close HDF5: %d\n", ier); + return EXIT_FAILURE; +} +return EXIT_SUCCESS; +} diff --git a/test cases/frameworks/25 hdf5/main.cpp b/test cases/frameworks/25 hdf5/main.cpp new file mode 100644 index 000000000..2baff3658 --- /dev/null +++ b/test cases/frameworks/25 hdf5/main.cpp @@ -0,0 +1,29 @@ +#include +#include "hdf5.h" + + +int main(void) +{ +herr_t ier; +unsigned maj, min, rel; + +ier = H5open(); +if (ier) { + std::cerr << "Unable to initialize HDF5: %d" << ier << std::endl; + return EXIT_FAILURE; +} + +ier = H5get_libversion(&maj, &min, &rel); +if (ier) { + std::cerr << "HDF5 did not initialize!" << std::endl; + return EXIT_FAILURE; +} +printf("C++ HDF5 version %d.%d.%d\n", maj, min, rel); + +ier = H5close(); +if (ier) { + std::cerr << "Unable to close HDF5: %d" << ier << std::endl; + return EXIT_FAILURE; +} +return EXIT_SUCCESS; +} diff --git a/test cases/frameworks/25 hdf5/main.f90 b/test cases/frameworks/25 hdf5/main.f90 new file mode 100644 index 000000000..b21abf186 --- /dev/null +++ b/test cases/frameworks/25 hdf5/main.f90 @@ -0,0 +1,17 @@ +use hdf5 + +implicit none + +integer :: ier, major, minor, rel + +call h5open_f(ier) +if (ier /= 0) error stop 'Unable to initialize HDF5' + +call h5get_libversion_f(major, minor, rel, ier) +if (ier /= 0) error stop 'Unable to check HDF5 version' +print '(A,I1,A1,I0.2,A1,I1)','Fortran HDF5 version ',major,'.',minor,'.',rel + +call h5close_f(ier) +if (ier /= 0) error stop 'Unable to close HDF5 library' + +end program diff --git a/test cases/frameworks/25 hdf5/meson.build b/test cases/frameworks/25 hdf5/meson.build new file mode 100644 index 000000000..e225a3576 --- /dev/null +++ b/test cases/frameworks/25 hdf5/meson.build @@ -0,0 +1,44 @@ +project('hdf5_test', 'c', 'cpp') + +if build_machine.system() == 'darwin' + error('MESON_SKIP_TEST: HDF5 CI image not setup for OSX.') +endif + +if build_machine.system() == 'cygwin' + error('MESON_SKIP_TEST: HDF5 CI image not setup for Cygwin.') +endif + + +# --- C tests +h5c = dependency('hdf5', language : 'c', required : false) +if not h5c.found() + error('MESON_SKIP_TEST: HDF5 not found, skipping.') +endif +exec = executable('exec', 'main.c', + dependencies : h5c) + +test('HDF5 C', exec) + +# --- C++ tests +h5cpp = dependency('hdf5', language : 'cpp') +execpp = executable('execpp', 'main.cpp', + dependencies : h5cpp) + +test('HDF5 C++', execpp) + + +# --- Fortran tests +if build_machine.system() != 'windows' + add_languages('fortran') + + h5f = dependency('hdf5', language : 'fortran') + exef = executable('exef', 'main.f90', + dependencies : h5f) + + test('HDF5 Fortran', exef) +endif + +# Check we can apply a version constraint +if h5c.version() != 'unknown' + dependency('hdf5', version: '>=@0@'.format(h5c.version())) +endif