forked from h5py/h5py
-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup.py
executable file
·315 lines (253 loc) · 10.4 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
#!/usr/bin/env python
try:
# If possible, use setuptools.Extension so we get setup_requires
from setuptools import Extension, setup
except ImportError:
from distutils.core import setup
from distutils.extension import Extension
from distutils.cmd import Command
from distutils.dist import Distribution
from distutils.version import LooseVersion
import warnings
import sys, os
import os.path as op
from functools import reduce
import configure # Sticky-options configuration and version auto-detect
VERSION = '2.2.0'
# --- Encapsulate NumPy imports in a specialized Extension type ---------------
# https://mail.python.org/pipermail/distutils-sig/2007-September/008253.html
class NumpyExtension(Extension, object):
"""Extension type that adds the NumPy include directory to include_dirs."""
def __init__(self, *args, **kwargs):
super(NumpyExtension, self).__init__(*args, **kwargs)
@property
def include_dirs(self):
from numpy import get_include
return self._include_dirs + [get_include()]
@include_dirs.setter
def include_dirs(self, include_dirs):
self._include_dirs = include_dirs
# --- Autodetect Cython -------------------------------------------------------
HAVE_CYTHON = False
try:
import Cython.Compiler.Version
s = LooseVersion(Cython.Compiler.Version.version)
if s.version[0:2] < [0, 13]:
warnings.warn("Cython version %s too old; not used" % s.vstring)
raise ImportError
from Cython.Distutils import build_ext
SUFFIX = '.pyx'
HAVE_CYTHON = True
except ImportError:
from distutils.command.build_ext import build_ext
SUFFIX = '.c'
if sys.version_info[0] >= 3:
# Shamelessly stolen from Cython 0.14
import lib2to3.refactor
from distutils.command.build_py \
import build_py_2to3 as build_py
else:
from distutils.command.build_py import build_py
# --- Support functions and "super-option" configuring ------------------------
def localpath(*args):
return op.abspath(reduce(op.join, (op.dirname(__file__),)+args))
def configure_cython(settings, modules):
""" Set up the Cython build environment.
If configuration settings have changed since the last time Cython was
run, re-write the file "config.pxi". Also bump the utime of all the
Cython modules to trigger a rebuild.
"""
try:
f = open(localpath('h5py/config.pxi'),'rb')
oldcontents = f.read()
except IOError:
oldcontents = b""
else:
f.close()
newcontents = """\
# This file is automatically generated by the h5py setup script. Don't modify.
DEF MPI = %(mpi)s
DEF HDF5_VERSION = %(hdf5_version)s
"""
newcontents %= settings
newcontents = newcontents.encode('utf-8')
# Only reconfigure and rebuild if settings have actually changed.
if newcontents != oldcontents:
with open(localpath('h5py/config.pxi'),'wb') as f:
f.write(newcontents)
for m in MODULES:
os.utime(localpath('h5py',m+'.pyx'),None)
# --- Pre-compiling API generation --------------------------------------------
if not op.isfile(localpath('h5py','defs.pyx')):
if not HAVE_CYTHON:
raise ValueError("A modern version of Cython is required to build from source")
import api_gen
api_gen.run()
# --- Determine configuration settings ----------------------------------------
settings = configure.scrape_eargs() # lowest priority
settings.update(configure.scrape_cargs()) # highest priority
HDF5 = settings.get('hdf5')
HDF5_VERSION = settings.get('hdf5_version')
MPI = settings.setdefault('mpi', False)
if MPI:
if not HAVE_CYTHON:
raise ValueError("Cython is required to compile h5py in MPI mode")
try:
import mpi4py
except ImportError:
raise ImportError("mpi4py is required to compile h5py in MPI mode")
# --- Configure Cython and create extensions ----------------------------------
if sys.platform.startswith('win'):
COMPILER_SETTINGS = {
'libraries' : ['hdf5dll18','hdf5_hldll'],
'include_dirs' : [localpath('lzf'),
localpath('win_include')],
'library_dirs' : [],
'define_macros' : [('H5_USE_16_API', None), ('_HDF5USEDLL_', None)]
}
if HDF5 is not None:
COMPILER_SETTINGS['include_dirs'] += [op.join(HDF5, 'include')]
COMPILER_SETTINGS['library_dirs'] += [op.join(HDF5, 'dll')]
else:
COMPILER_SETTINGS = {
'libraries' : ['hdf5', 'hdf5_hl'],
'include_dirs' : [localpath('lzf')],
'library_dirs' : [],
'define_macros' : [('H5_USE_16_API', None)]
}
if HDF5 is not None:
COMPILER_SETTINGS['include_dirs'] += [op.join(HDF5, 'include')]
COMPILER_SETTINGS['library_dirs'] += [op.join(HDF5, 'lib'), op.join(HDF5, 'lib64')]
elif sys.platform == 'darwin':
# putting here both macports and homebrew paths will generate
# "ld: warning: dir not found" at the linking phase
COMPILER_SETTINGS['include_dirs'] += ['/opt/local/include'] # macports
COMPILER_SETTINGS['library_dirs'] += ['/opt/local/lib'] # macports
COMPILER_SETTINGS['include_dirs'] += ['/usr/local/include'] # homebrew
COMPILER_SETTINGS['library_dirs'] += ['/usr/local/lib'] # homebrew
elif sys.platform.startswith('freebsd'):
COMPILER_SETTINGS['include_dirs'] += ['/usr/local/include'] # homebrew
COMPILER_SETTINGS['library_dirs'] += ['/usr/local/lib'] # homebrew
if MPI:
COMPILER_SETTINGS['include_dirs'] += [mpi4py.get_include()]
COMPILER_SETTINGS['runtime_library_dirs'] = [op.abspath(x) for x in COMPILER_SETTINGS['library_dirs']]
MODULES = ['defs','_errors','_objects','_proxy', 'h5fd', 'h5z',
'h5','h5i','h5r','utils',
'_conv', 'h5t','h5s',
'h5p',
'h5d', 'h5a', 'h5f', 'h5g',
'h5l', 'h5o',
'h5ds', 'h5ac']
# No Cython, no point in configuring
if HAVE_CYTHON:
# Don't autodetect if version is manually given
if HDF5_VERSION is None:
HDF5_VERSION = configure.autodetect(COMPILER_SETTINGS['library_dirs'])
if HDF5_VERSION is None:
HDF5_VERSION = (1, 8, 4)
configure.printerr("HDF5 autodetection failed; building for 1.8.4+")
settings['hdf5_version'] = HDF5_VERSION
configure_cython(settings, MODULES)
else:
configure.printerr("Cython not present; building for HDF5 1.8.4+")
EXTRA_SRC = {'h5z': [ localpath("lzf/lzf_filter.c"),
localpath("lzf/lzf/lzf_c.c"),
localpath("lzf/lzf/lzf_d.c")]}
def make_extension(module):
sources = [op.join('h5py', module+SUFFIX)] + EXTRA_SRC.get(module, [])
return NumpyExtension('h5py.'+module, sources, **COMPILER_SETTINGS)
EXTENSIONS = [make_extension(m) for m in MODULES]
# --- Custom distutils commands -----------------------------------------------
class test(Command):
"""Run the test suite."""
description = "Run the test suite"
user_options = [('verbosity=', 'V', 'set test report verbosity')]
def initialize_options(self):
self.verbosity = 0
def finalize_options(self):
try:
self.verbosity = int(self.verbosity)
except ValueError:
raise ValueError('verbosity must be an integer.')
def run(self):
import sys
py_version = sys.version_info[:2]
if py_version == (2,7) or py_version >= (3,2):
import unittest
else:
try:
import unittest2 as unittest
except ImportError:
raise ImportError(
"unittest2 is required to run tests with python-%d.%d"
% py_version
)
buildobj = self.distribution.get_command_obj('build')
buildobj.run()
oldpath = sys.path
try:
sys.path = [op.abspath(buildobj.build_lib)] + oldpath
suite = unittest.TestLoader().discover(op.join(buildobj.build_lib,'h5py'))
result = unittest.TextTestRunner(verbosity=self.verbosity+1).run(suite)
if not result.wasSuccessful():
sys.exit(1)
finally:
sys.path = oldpath
# --- Distutils setup and metadata --------------------------------------------
cls_txt = \
"""
Development Status :: 5 - Production/Stable
Intended Audience :: Developers
Intended Audience :: Information Technology
Intended Audience :: Science/Research
License :: OSI Approved :: BSD License
Programming Language :: Python
Topic :: Scientific/Engineering
Topic :: Database
Topic :: Software Development :: Libraries :: Python Modules
Operating System :: Unix
Operating System :: POSIX :: Linux
Operating System :: MacOS :: MacOS X
Operating System :: Microsoft :: Windows
"""
short_desc = "Read and write HDF5 files from Python"
long_desc = \
"""
The h5py package provides both a high- and low-level interface to the HDF5
library from Python. The low-level interface is intended to be a complete
wrapping of the HDF5 API, while the high-level component supports access to
HDF5 files, datasets and groups using established Python and NumPy concepts.
A strong emphasis on automatic conversion between Python (Numpy) datatypes and
data structures and their HDF5 equivalents vastly simplifies the process of
reading and writing data from Python.
Supports HDF5 versions 1.8.3 and higher. On Windows, HDF5 is included with
the installer.
"""
if os.name == 'nt':
package_data = {'h5py': ['*.pyx', '*.dll']}
else:
package_data = {'h5py': ['*.pyx']}
# Avoid going off and installing NumPy if the user only queries for information
if any('--' + opt in sys.argv for opt in Distribution.display_option_names + ['help']):
setup_requires = []
else:
setup_requires = ['numpy >=1.0.1']
setup(
name = 'h5py',
version = VERSION,
description = short_desc,
long_description = long_desc,
classifiers = [x for x in cls_txt.split("\n") if x],
author = 'Andrew Collette',
author_email = 'andrew dot collette at gmail dot com',
maintainer = 'Andrew Collette',
maintainer_email = 'andrew dot collette at gmail dot com',
url = 'http://www.h5py.org',
download_url = 'http://code.google.com/p/h5py/downloads/list',
packages = ['h5py', 'h5py._hl', 'h5py._hl.tests', 'h5py.lowtest'],
package_data = package_data,
ext_modules = EXTENSIONS,
requires = ['numpy (>=1.0.1)'],
setup_requires = setup_requires,
cmdclass = {'build_ext': build_ext, 'test': test, 'build_py':build_py}
)