2016-01-20 22:22:49 +08:00
|
|
|
##############################################################################
|
2016-05-12 12:22:25 +08:00
|
|
|
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
|
2016-01-20 22:22:49 +08:00
|
|
|
# Produced at the Lawrence Livermore National Laboratory.
|
|
|
|
#
|
|
|
|
# This file is part of Spack.
|
2016-05-12 12:22:25 +08:00
|
|
|
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
2016-01-20 22:22:49 +08:00
|
|
|
# LLNL-CODE-647188
|
|
|
|
#
|
|
|
|
# For details, see https://github.com/llnl/spack
|
|
|
|
# Please also see the LICENSE file for our notice and the LGPL.
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
2016-05-12 12:22:25 +08:00
|
|
|
# it under the terms of the GNU Lesser General Public License (as
|
|
|
|
# published by the Free Software Foundation) version 2.1, February 1999.
|
2016-01-20 22:22:49 +08:00
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful, but
|
|
|
|
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
|
2016-05-12 12:22:25 +08:00
|
|
|
# conditions of the GNU Lesser General Public License for more details.
|
2016-01-20 22:22:49 +08:00
|
|
|
#
|
2016-05-12 12:22:25 +08:00
|
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
|
|
# License along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2016-01-20 22:22:49 +08:00
|
|
|
##############################################################################
|
2014-06-02 23:35:01 +08:00
|
|
|
from spack import *
|
2016-04-21 04:33:59 +08:00
|
|
|
import shutil
|
2014-06-02 23:35:01 +08:00
|
|
|
|
2016-01-20 22:22:49 +08:00
|
|
|
|
2016-07-13 03:28:09 +08:00
|
|
|
class Hdf5(AutotoolsPackage):
|
2014-06-02 23:35:01 +08:00
|
|
|
"""HDF5 is a data model, library, and file format for storing and managing
|
2016-07-13 15:21:49 +08:00
|
|
|
data. It supports an unlimited variety of datatypes, and is designed for
|
|
|
|
flexible and efficient I/O and for high volume and complex data.
|
2014-06-02 23:35:01 +08:00
|
|
|
"""
|
|
|
|
|
|
|
|
homepage = "http://www.hdfgroup.org/HDF5/"
|
2016-01-20 22:22:49 +08:00
|
|
|
url = "http://www.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8.13/src/hdf5-1.8.13.tar.gz"
|
2014-06-02 23:35:01 +08:00
|
|
|
list_url = "http://www.hdfgroup.org/ftp/HDF5/releases"
|
|
|
|
list_depth = 3
|
2015-12-24 11:49:42 +08:00
|
|
|
|
2016-06-01 00:18:17 +08:00
|
|
|
version('1.10.0-patch1', '9180ff0ef8dc2ef3f61bd37a7404f295')
|
2016-04-05 02:42:36 +08:00
|
|
|
version('1.10.0', 'bdc935337ee8282579cd6bc4270ad199')
|
2016-12-02 06:31:27 +08:00
|
|
|
version('1.8.18', 'dd2148b740713ca0295442ec683d7b1c',
|
|
|
|
# The link for the latest version differs from the links for
|
|
|
|
# the previous releases. Do not forget to remove this once
|
|
|
|
# the version 1.8.18 is not the latest one for the 1.8.* branch.
|
|
|
|
url='http://hdfgroup.org/ftp/HDF5/current18/src/hdf5-1.8.18.tar.gz')
|
|
|
|
version('1.8.17', '7d572f8f3b798a628b8245af0391a0ca')
|
2016-07-19 08:14:44 +08:00
|
|
|
version('1.8.16', 'b8ed9a36ae142317f88b0c7ef4b9c618')
|
2015-09-25 16:44:47 +08:00
|
|
|
version('1.8.15', '03cccb5b33dbe975fdcd8ae9dc021f24')
|
2017-01-08 01:03:50 +08:00
|
|
|
version('1.8.14', 'a482686e733514a51cde12d6fe5c5d95')
|
2014-07-31 14:30:07 +08:00
|
|
|
version('1.8.13', 'c03426e9e77d7766944654280b467289')
|
2016-09-09 04:27:47 +08:00
|
|
|
version('1.8.12', 'd804802feb99b87fc668a90e6fa34411')
|
2014-06-02 23:35:01 +08:00
|
|
|
|
2016-08-10 16:50:00 +08:00
|
|
|
variant('debug', default=False,
|
|
|
|
description='Builds a debug version of the library')
|
|
|
|
variant('shared', default=True,
|
|
|
|
description='Builds a shared version of the library')
|
2016-01-20 22:22:49 +08:00
|
|
|
|
2016-01-02 06:26:49 +08:00
|
|
|
variant('cxx', default=True, description='Enable C++ support')
|
|
|
|
variant('fortran', default=True, description='Enable Fortran support')
|
2016-01-20 22:22:49 +08:00
|
|
|
|
2016-08-19 03:40:21 +08:00
|
|
|
variant('mpi', default=True, description='Enable MPI support')
|
2016-01-26 04:57:33 +08:00
|
|
|
variant('szip', default=False, description='Enable szip support')
|
2016-08-10 16:50:00 +08:00
|
|
|
variant('threadsafe', default=False,
|
|
|
|
description='Enable thread-safe capabilities')
|
2016-12-06 03:57:04 +08:00
|
|
|
variant('pic', default=True,
|
|
|
|
description='Produce position-independent code (for shared libs)')
|
2015-11-17 06:00:11 +08:00
|
|
|
|
2016-07-13 15:21:49 +08:00
|
|
|
depends_on('mpi', when='+mpi')
|
|
|
|
depends_on('szip', when='+szip')
|
2016-10-11 22:28:08 +08:00
|
|
|
depends_on('zlib@1.1.2:')
|
2014-06-02 23:35:01 +08:00
|
|
|
|
2016-07-13 03:28:09 +08:00
|
|
|
@AutotoolsPackage.precondition('configure')
|
|
|
|
def validate(self):
|
2016-01-20 22:22:49 +08:00
|
|
|
"""
|
|
|
|
Checks if incompatible variants have been activated at the same time
|
|
|
|
|
|
|
|
:param spec: spec of the package
|
|
|
|
:raises RuntimeError: in case of inconsistencies
|
|
|
|
"""
|
2016-07-13 03:28:09 +08:00
|
|
|
spec = self.spec
|
2016-01-20 22:22:49 +08:00
|
|
|
if '+fortran' in spec and not self.compiler.fc:
|
|
|
|
msg = 'cannot build a fortran variant without a fortran compiler'
|
|
|
|
raise RuntimeError(msg)
|
|
|
|
|
|
|
|
if '+threadsafe' in spec and ('+cxx' in spec or '+fortran' in spec):
|
2016-06-23 04:22:42 +08:00
|
|
|
msg = 'cannot use variant +threadsafe with either +cxx or +fortran'
|
|
|
|
raise RuntimeError(msg)
|
2016-01-20 22:22:49 +08:00
|
|
|
|
2016-07-13 03:28:09 +08:00
|
|
|
def configure_args(self):
|
|
|
|
spec = self.spec
|
2016-01-20 22:22:49 +08:00
|
|
|
# Handle compilation after spec validation
|
2015-11-17 06:00:11 +08:00
|
|
|
extra_args = []
|
2016-03-10 03:16:35 +08:00
|
|
|
|
|
|
|
# Always enable this option. This does not actually enable any
|
|
|
|
# features: it only *allows* the user to specify certain
|
|
|
|
# combinations of other arguments. Enabling it just skips a
|
|
|
|
# sanity check in configure, so this doesn't merit a variant.
|
|
|
|
extra_args.append("--enable-unsupported")
|
|
|
|
|
2016-04-03 08:21:56 +08:00
|
|
|
if spec.satisfies('@1.10:'):
|
|
|
|
if '+debug' in spec:
|
|
|
|
extra_args.append('--enable-build-mode=debug')
|
|
|
|
else:
|
|
|
|
extra_args.append('--enable-build-mode=production')
|
2016-01-20 22:22:49 +08:00
|
|
|
else:
|
2016-04-03 08:21:56 +08:00
|
|
|
if '+debug' in spec:
|
|
|
|
extra_args.append('--enable-debug=all')
|
|
|
|
else:
|
|
|
|
extra_args.append('--enable-production')
|
2016-01-20 22:22:49 +08:00
|
|
|
|
2016-02-18 03:51:24 +08:00
|
|
|
if '+shared' in spec:
|
|
|
|
extra_args.append('--enable-shared')
|
|
|
|
else:
|
2016-02-17 08:43:24 +08:00
|
|
|
extra_args.append('--enable-static-exec')
|
|
|
|
|
2015-12-24 11:49:42 +08:00
|
|
|
if '+cxx' in spec:
|
2016-01-20 22:22:49 +08:00
|
|
|
extra_args.append('--enable-cxx')
|
|
|
|
|
2015-12-24 11:49:42 +08:00
|
|
|
if '+fortran' in spec:
|
2016-04-14 04:03:03 +08:00
|
|
|
extra_args.append('--enable-fortran')
|
|
|
|
# '--enable-fortran2003' no longer exists as of version 1.10.0
|
|
|
|
if spec.satisfies('@:1.8.16'):
|
|
|
|
extra_args.append('--enable-fortran2003')
|
2016-01-20 22:22:49 +08:00
|
|
|
|
2016-12-06 03:57:04 +08:00
|
|
|
if '+pic' in spec:
|
|
|
|
extra_args.append('CFLAGS={0}'.format(self.compiler.pic_flag))
|
|
|
|
extra_args.append('CXXFLAGS={0}'.format(self.compiler.pic_flag))
|
|
|
|
extra_args.append('FFLAGS={0}'.format(self.compiler.pic_flag))
|
|
|
|
|
2015-11-17 06:00:11 +08:00
|
|
|
if '+mpi' in spec:
|
2015-12-24 11:49:42 +08:00
|
|
|
# The HDF5 configure script warns if cxx and mpi are enabled
|
|
|
|
# together. There doesn't seem to be a real reason for this, except
|
|
|
|
# that parts of the MPI interface are not accessible via the C++
|
|
|
|
# interface. Since they are still accessible via the C interface,
|
|
|
|
# this is not actually a problem.
|
2015-11-17 06:00:11 +08:00
|
|
|
extra_args.extend([
|
|
|
|
"--enable-parallel",
|
2016-10-11 06:33:00 +08:00
|
|
|
"CC=%s" % spec['mpi'].mpicc
|
2015-12-24 11:49:42 +08:00
|
|
|
])
|
2016-01-20 22:22:49 +08:00
|
|
|
|
|
|
|
if '+cxx' in spec:
|
2016-10-11 06:33:00 +08:00
|
|
|
extra_args.append("CXX=%s" % spec['mpi'].mpicxx)
|
2016-01-20 22:22:49 +08:00
|
|
|
|
|
|
|
if '+fortran' in spec:
|
2016-10-11 06:33:00 +08:00
|
|
|
extra_args.append("FC=%s" % spec['mpi'].mpifc)
|
2016-01-20 22:22:49 +08:00
|
|
|
|
2016-01-26 04:57:33 +08:00
|
|
|
if '+szip' in spec:
|
|
|
|
extra_args.append("--with-szlib=%s" % spec['szip'].prefix)
|
|
|
|
|
2016-01-20 22:22:49 +08:00
|
|
|
if '+threadsafe' in spec:
|
2015-12-24 11:49:42 +08:00
|
|
|
extra_args.extend([
|
|
|
|
'--enable-threadsafe',
|
|
|
|
'--disable-hl',
|
2015-11-17 06:00:11 +08:00
|
|
|
])
|
2015-01-23 03:50:01 +08:00
|
|
|
|
2016-07-13 03:28:09 +08:00
|
|
|
return ["--with-zlib=%s" % spec['zlib'].prefix] + extra_args
|
|
|
|
|
2017-01-08 01:03:50 +08:00
|
|
|
def configure(self, spec, prefix):
|
|
|
|
# Run the default autotools package configure
|
|
|
|
super(Hdf5, self).configure(spec, prefix)
|
|
|
|
|
|
|
|
if '@:1.8.14' in spec:
|
|
|
|
# On Ubuntu14, HDF5 1.8.12 (and maybe other versions)
|
|
|
|
# mysteriously end up with "-l -l" in the postdeps in the
|
|
|
|
# libtool script. Patch this by removing the spurious -l's.
|
|
|
|
filter_file(
|
|
|
|
r'postdeps="([^"]*)"',
|
|
|
|
lambda m: 'postdeps="%s"' % ' '.join(
|
|
|
|
arg for arg in m.group(1).split(' ') if arg != '-l'),
|
|
|
|
'libtool')
|
|
|
|
|
2016-11-11 13:50:32 +08:00
|
|
|
@AutotoolsPackage.sanity_check('install')
|
|
|
|
def check_install(self):
|
2016-10-24 01:02:46 +08:00
|
|
|
# Build and run a small program to test the installed HDF5 library
|
2016-07-13 03:28:09 +08:00
|
|
|
spec = self.spec
|
2016-08-11 15:08:00 +08:00
|
|
|
print("Checking HDF5 installation...")
|
2016-04-21 04:33:59 +08:00
|
|
|
checkdir = "spack-check"
|
|
|
|
with working_dir(checkdir, create=True):
|
|
|
|
source = r"""
|
|
|
|
#include <hdf5.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
unsigned majnum, minnum, relnum;
|
|
|
|
herr_t herr = H5get_libversion(&majnum, &minnum, &relnum);
|
|
|
|
assert(!herr);
|
|
|
|
printf("HDF5 version %d.%d.%d %u.%u.%u\n", H5_VERS_MAJOR, H5_VERS_MINOR,
|
|
|
|
H5_VERS_RELEASE, majnum, minnum, relnum);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
expected = """\
|
|
|
|
HDF5 version {version} {version}
|
2016-06-23 03:40:51 +08:00
|
|
|
""".format(version=str(spec.version.up_to(3)))
|
2016-04-21 04:33:59 +08:00
|
|
|
with open("check.c", 'w') as f:
|
|
|
|
f.write(source)
|
|
|
|
if '+mpi' in spec:
|
2016-10-11 06:33:00 +08:00
|
|
|
cc = which('%s' % spec['mpi'].mpicc)
|
2016-04-21 04:33:59 +08:00
|
|
|
else:
|
|
|
|
cc = which('cc')
|
2016-04-21 05:01:26 +08:00
|
|
|
# TODO: Automate these path and library settings
|
2016-04-21 04:33:59 +08:00
|
|
|
cc('-c', "-I%s" % join_path(spec.prefix, "include"), "check.c")
|
|
|
|
cc('-o', "check", "check.o",
|
2016-11-29 01:12:48 +08:00
|
|
|
"-L%s" % join_path(spec.prefix, "lib"),
|
|
|
|
"-L%s" % join_path(spec.prefix, "lib64"),
|
|
|
|
"-lhdf5",
|
2016-04-21 04:33:59 +08:00
|
|
|
"-lz")
|
|
|
|
try:
|
2016-04-23 09:52:11 +08:00
|
|
|
check = Executable('./check')
|
|
|
|
output = check(return_output=True)
|
2016-04-21 04:33:59 +08:00
|
|
|
except:
|
|
|
|
output = ""
|
|
|
|
success = output == expected
|
|
|
|
if not success:
|
2016-08-11 15:08:00 +08:00
|
|
|
print("Produced output does not match expected output.")
|
|
|
|
print("Expected output:")
|
|
|
|
print('-' * 80)
|
|
|
|
print(expected)
|
|
|
|
print('-' * 80)
|
|
|
|
print("Produced output:")
|
|
|
|
print('-' * 80)
|
|
|
|
print(output)
|
|
|
|
print('-' * 80)
|
2016-04-21 04:33:59 +08:00
|
|
|
raise RuntimeError("HDF5 install check failed")
|
|
|
|
shutil.rmtree(checkdir)
|
2014-06-02 23:35:01 +08:00
|
|
|
|
|
|
|
def url_for_version(self, version):
|
2016-12-02 06:31:27 +08:00
|
|
|
# If we have a specific URL for this version, return it.
|
|
|
|
version_urls = self.version_urls()
|
|
|
|
if version in version_urls:
|
|
|
|
return version_urls[version]
|
|
|
|
|
2016-06-23 04:22:42 +08:00
|
|
|
base_url = "http://www.hdfgroup.org/ftp/HDF5/releases"
|
2014-06-02 23:35:01 +08:00
|
|
|
|
|
|
|
if version == Version("1.2.2"):
|
2016-06-23 04:22:42 +08:00
|
|
|
return "{0}/hdf5-{1}.tar.gz".format(base_url, version)
|
|
|
|
elif version < Version("1.6.6"):
|
|
|
|
return "{0}/hdf5-{1}/hdf5-{2}.tar.gz".format(
|
|
|
|
base_url, version.up_to(2), version)
|
2014-06-02 23:35:01 +08:00
|
|
|
elif version < Version("1.7"):
|
2016-06-23 04:22:42 +08:00
|
|
|
return "{0}/hdf5-{1}/hdf5-{2}/src/hdf5-{2}.tar.gz".format(
|
|
|
|
base_url, version.up_to(2), version)
|
2016-04-05 02:42:36 +08:00
|
|
|
elif version < Version("1.10"):
|
2016-06-23 04:22:42 +08:00
|
|
|
return "{0}/hdf5-{1}/src/hdf5-{1}.tar.gz".format(
|
|
|
|
base_url, version)
|
2016-04-05 02:42:36 +08:00
|
|
|
else:
|
2016-06-23 04:22:42 +08:00
|
|
|
return "{0}/hdf5-{1}/hdf5-{2}/src/hdf5-{2}.tar.gz".format(
|
|
|
|
base_url, version.up_to(2), version)
|