xref: /petsc/config/BuildSystem/config/packages/HDF5.py (revision 7b5fd022a6ba26727040df7457b27566b4c6742d)
1import config.package
2import os
3
4class Configure(config.package.CMakePackage):
5  def __init__(self, framework):
6    config.package.CMakePackage.__init__(self, framework)
7    self.minversion       = '1.8'
8    self.versionname      = 'H5_VERSION'
9    self.version          = '1.14.6'
10    self.download         = ['https://github.com/HDFGroup/hdf5/archive/hdf5_'+self.version+'/hdf5-'+self.version+'.tar.gz',
11                             'https://web.cels.anl.gov/projects/petsc/download/externalpackages/hdf5-'+self.version+'.tar.gz']
12# David Moulton reports that HDF5 configure can fail on NERSC systems and this can be worked around by removing the
13#   getpwuid from the test for ac_func in gethostname getpwuid getrusage lstat
14    self.functions        = ['H5T_init']
15    self.includes         = ['hdf5.h']
16    self.liblist          = [['libhdf5_hl.a', 'libhdf5.a']]
17    self.hastests         = 1
18    self.precisions       = ['single','double']
19    self.installwithbatch = 0
20
21  def setupHelp(self, help):
22    config.package.CMakePackage.setupHelp(self, help)
23    import nargs
24    # PETSc does not need the Fortran/CXX interface.
25    # We currently need it to be disabled by default as HDF5 has bugs in their build process as of hdf5-1.12.0.
26    # Not all dependencies for Fortran bindings are given in the makefiles, hence a parallel build can fail
27    # when it starts a Fortran file before all its needed modules are finished.
28    # Barry has reported this to them and they acknowledged it.
29    help.addArgument('HDF5', '-with-hdf5-fortran-bindings', nargs.ArgBool(None, 0, 'Use/build HDF5 Fortran interface (PETSc does not need it)'))
30    help.addArgument('HDF5', '-with-hdf5-cxx-bindings', nargs.ArgBool(None, 0, 'Use/build HDF5 Cxx interface (PETSc does not need it)'))
31
32  def setupDependencies(self, framework):
33    config.package.CMakePackage.setupDependencies(self, framework)
34    self.mpi            = framework.require('config.packages.MPI',self)
35    self.mathlib        = framework.require('config.packages.mathlib',self)
36    self.zlib           = framework.require('config.packages.zlib',self)
37    self.szlib          = framework.require('config.packages.szlib',self)
38    self.flibs          = framework.require('config.packages.flibs',self)
39    self.deps           = [self.mathlib]
40    self.odeps          = [self.mpi, self.zlib,self.szlib,self.flibs]
41    return
42
43  def applyPatches(self):
44    try:
45      with open(self.packageDir+'/config/cmake/HDFMacros.cmake') as f_in:
46        content = f_in.readlines()
47      with open(self.packageDir+'/config/cmake/HDFMacros.cmake','w') as f_out:
48        f_out.writelines(c.replace('(CMAKE_DEBUG_POSTFIX "_debug")','(CMAKE_DEBUG_POSTFIX "")') for c in content)
49    except:
50      self.logPrintWarning("Patching HDF5 failed! Continuing with build")
51
52  def versionToStandardForm(self,ver):
53    '''HDF5 indicates patches by appending a -patch<n> after the regular part of the version'''
54    return ver.replace('-patch','.')
55
56  def formCMakeConfigureArgs(self):
57    ''' Add HDF5 specific --enable-parallel flag and enable Fortran if available '''
58    args = config.package.CMakePackage.formCMakeConfigureArgs(self)
59    args.append('-DHDF5_BUILD_HL_LIB=ON')
60    args.append('-DHDF5_BUILD_TOOLS=OFF')
61    args.append('-DBUILD_TESTING=OFF')
62
63    if not self.mpi.usingMPIUni:
64      args.append('-DHDF5_ENABLE_PARALLEL=ON')
65    if self.argDB['with-hdf5-fortran-bindings']:
66      if hasattr(self.compilers, 'FC'):
67        args.append('-DHDF5_BUILD_FORTRAN=ON')
68      else:
69        raise RuntimeError('Cannot build HDF5 Fortran bindings --with-fc=0 or with a malfunctioning Fortran compiler.')
70    if self.argDB['with-hdf5-cxx-bindings']:
71      if hasattr(self.compilers, 'CXX'):
72        args.extend(['-DHDF5_BUILD_CPP_LIB=ON', '-DALLOW_UNSUPPORTED=ON'])
73      else:
74        raise RuntimeError('Cannot build HDF5 Cxx bindings --with-cxx=0 or with a malfunctioning Cxx compiler.')
75
76    args.append('-DHDF5_ENABLE_Z_LIB_SUPPORT='+('ON' if self.zlib.found else 'OFF'))
77    args.append('-DHDF5_ENABLE_SZIP_SUPPORT='+('ON' if self.szlib.found else 'OFF'))
78
79    return args
80
81  def configureLibrary(self):
82    # PETSc does not need the Fortran/CXX interface, but some users will use them
83    # and expect our standard linking to be sufficient.  Thus we try to link the Fortran/CXX
84    # libraries, but fall back to linking only C.
85    if hasattr(self.compilers, 'FC') and self.argDB['with-hdf5-fortran-bindings']:
86      self.liblist = [['libhdf5_hl_fortran.a','libhdf5_fortran.a', 'libhdf5_hl_f90cstub.a', 'libhdf5_f90cstub.a'] + libs for libs in self.liblist] \
87                   + [['libhdf5_hl_fortran.a','libhdf5_fortran.a'] + libs for libs in self.liblist] \
88                   + [['libhdf5hl_fortran.a','libhdf5_fortran.a'] + libs for libs in self.liblist] \
89                   + self.liblist
90    if hasattr(self.compilers, 'CXX') and self.argDB['with-hdf5-cxx-bindings']:
91      self.liblist = [['libhdf5_hl_cpp.a','libhdf5_cpp.a'] + libs for libs in self.liblist] + self.liblist
92    config.package.GNUPackage.configureLibrary(self)
93
94    for i in ['ZLIB_H','SZLIB_H','PARALLEL']:
95      oldFlags = self.compilers.CPPFLAGS
96      self.compilers.CPPFLAGS += ' '+self.headers.toString(self.include)
97      try:
98        output = self.outputPreprocess('#include "H5pubconf.h"\n#if defined(H5_HAVE_'+i+')\nfoundbeast\n#endif\n')
99      except:
100        self.log.write('Unable to run preprocessor to obtain '+i+' information\n')
101        self.compilers.CPPFLAGS = oldFlags
102        return
103      self.compilers.CPPFLAGS = oldFlags
104      if output.find('foundbeast') > -1:
105        if i.endswith('_H'): i = i[0:-2]
106        self.addDefine('HDF5_HAVE_'+i, 1)
107