setup.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. ########################################################################
  2. #
  3. # License: BSD
  4. # Created: August 16, 2012
  5. # Author: Francesc Alted - francesc@blosc.org
  6. #
  7. ########################################################################
  8. from __future__ import absolute_import
  9. from sys import version_info as v
  10. # Check this Python version is supported
  11. if any([v < (2, 6), (3,) < v < (3, 3)]):
  12. raise Exception("Unsupported Python version %d.%d. Requires Python >= 2.6 "
  13. "or >= 3.3." % v[:2])
  14. import platform
  15. import os
  16. from glob import glob
  17. import sys
  18. import re
  19. from setuptools import setup, Extension, find_packages
  20. from pkg_resources import resource_filename
  21. # For guessing the capabilities of the CPU for C-Blosc
  22. import cpuinfo
  23. class LazyCommandClass(dict):
  24. """
  25. Lazy command class that defers operations requiring Cython and numpy until
  26. they've actually been downloaded and installed by setup_requires.
  27. """
  28. def __contains__(self, key):
  29. return (
  30. key == 'build_ext'
  31. or super(LazyCommandClass, self).__contains__(key)
  32. )
  33. def __setitem__(self, key, value):
  34. if key == 'build_ext':
  35. raise AssertionError("build_ext overridden!")
  36. super(LazyCommandClass, self).__setitem__(key, value)
  37. def __getitem__(self, key):
  38. if key != 'build_ext':
  39. return super(LazyCommandClass, self).__getitem__(key)
  40. from Cython.Distutils import build_ext as cython_build_ext
  41. class build_ext(cython_build_ext):
  42. """
  43. Custom build_ext command that lazily adds numpy's include_dir to
  44. extensions.
  45. """
  46. def build_extensions(self):
  47. """
  48. Lazily append numpy's include directory to Extension includes.
  49. This is done here rather than at module scope because setup.py
  50. may be run before numpy has been installed, in which case
  51. importing numpy and calling `numpy.get_include()` will fail.
  52. """
  53. numpy_incl = resource_filename('numpy', 'core/include')
  54. for ext in self.extensions:
  55. ext.include_dirs.append(numpy_incl)
  56. # This explicitly calls the superclass method rather than the
  57. # usual super() invocation because distutils' build_class, of
  58. # which Cython's build_ext is a subclass, is an old-style class
  59. # in Python 2, which doesn't support `super`.
  60. cython_build_ext.build_extensions(self)
  61. return build_ext
  62. # Global variables
  63. CFLAGS = os.environ.get('CFLAGS', '').split()
  64. LFLAGS = os.environ.get('LFLAGS', '').split()
  65. # Allow setting the Blosc dir if installed in the system
  66. BLOSC_DIR = os.environ.get('BLOSC_DIR', '')
  67. # Sources & libraries
  68. inc_dirs = ['bcolz']
  69. lib_dirs = []
  70. libs = []
  71. def_macros = []
  72. sources = ['bcolz/carray_ext.pyx']
  73. optional_libs = []
  74. # Handle --blosc=[PATH] --lflags=[FLAGS] --cflags=[FLAGS]
  75. args = sys.argv[:]
  76. for arg in args:
  77. if arg.find('--blosc=') == 0:
  78. BLOSC_DIR = os.path.expanduser(arg.split('=')[1])
  79. sys.argv.remove(arg)
  80. if arg.find('--lflags=') == 0:
  81. LFLAGS = arg.split('=')[1].split()
  82. sys.argv.remove(arg)
  83. if arg.find('--cflags=') == 0:
  84. CFLAGS = arg.split('=')[1].split()
  85. sys.argv.remove(arg)
  86. if BLOSC_DIR != '':
  87. # Using the Blosc library
  88. lib_dirs += [os.path.join(BLOSC_DIR, 'lib')]
  89. inc_dirs += [os.path.join(BLOSC_DIR, 'include')]
  90. libs += ['blosc']
  91. else:
  92. # Compiling everything from sources
  93. sources += [f for f in glob('c-blosc/blosc/*.c')
  94. if 'avx2' not in f and 'sse2' not in f]
  95. sources += glob('c-blosc/internal-complibs/lz4*/*.c')
  96. sources += glob('c-blosc/internal-complibs/snappy*/*.cc')
  97. sources += glob('c-blosc/internal-complibs/zlib*/*.c')
  98. inc_dirs += [os.path.join('c-blosc', 'blosc')]
  99. inc_dirs += glob('c-blosc/internal-complibs/*')
  100. def_macros += [('HAVE_LZ4', 1), ('HAVE_SNAPPY', 1), ('HAVE_ZLIB', 1)]
  101. # Guess SSE2 or AVX2 capabilities
  102. cpu_info = cpuinfo.get_cpu_info()
  103. # SSE2
  104. if 'sse2' in cpu_info['flags']:
  105. print('SSE2 detected')
  106. CFLAGS.append('-DSHUFFLE_SSE2_ENABLED')
  107. sources += [f for f in glob('c-blosc/blosc/*.c') if 'sse2' in f]
  108. if os.name == 'posix':
  109. CFLAGS.append('-msse2')
  110. elif os.name == 'nt':
  111. def_macros += [('__SSE2__', 1)]
  112. # AVX2
  113. if 'avx2' in cpu_info['flags']:
  114. print('AVX2 detected')
  115. CFLAGS.append('-DSHUFFLE_AVX2_ENABLED')
  116. sources += [f for f in glob('c-blosc/blosc/*.c') if 'avx2' in f]
  117. if os.name == 'posix':
  118. CFLAGS.append('-mavx2')
  119. elif os.name == 'nt':
  120. def_macros += [('__AVX2__', 1)]
  121. tests_require = []
  122. if v < (3,):
  123. tests_require.extend(['unittest2', 'mock'])
  124. # compile and link code instrumented for coverage analysis
  125. if os.getenv('TRAVIS') and os.getenv('CI') and v[0:2] == (2, 7):
  126. CFLAGS.extend(["-fprofile-arcs", "-ftest-coverage"])
  127. LFLAGS.append("-lgcov")
  128. setup(
  129. name="bcolz",
  130. use_scm_version={
  131. 'version_scheme': 'guess-next-dev',
  132. 'local_scheme': 'dirty-tag',
  133. 'write_to': 'bcolz/version.py'
  134. },
  135. description='columnar and compressed data containers.',
  136. long_description="""\
  137. bcolz provides columnar and compressed data containers. Column
  138. storage allows for efficiently querying tables with a large number of
  139. columns. It also allows for cheap addition and removal of column. In
  140. addition, bcolz objects are compressed by default for reducing
  141. memory/disk I/O needs. The compression process is carried out
  142. internally by Blosc, a high-performance compressor that is optimized
  143. for binary data.
  144. """,
  145. classifiers=[
  146. 'Development Status :: 5 - Production/Stable',
  147. 'Intended Audience :: Developers',
  148. 'Intended Audience :: Information Technology',
  149. 'Intended Audience :: Science/Research',
  150. 'License :: OSI Approved :: BSD License',
  151. 'Programming Language :: Python',
  152. 'Topic :: Software Development :: Libraries :: Python Modules',
  153. 'Operating System :: Microsoft :: Windows',
  154. 'Operating System :: Unix',
  155. 'Programming Language :: Python :: 2',
  156. 'Programming Language :: Python :: 2.6',
  157. 'Programming Language :: Python :: 2.7',
  158. 'Programming Language :: Python :: 3',
  159. 'Programming Language :: Python :: 3.3',
  160. 'Programming Language :: Python :: 3.4',
  161. 'Programming Language :: Python :: 3.5',
  162. ],
  163. author='Francesc Alted',
  164. author_email='francesc@blosc.org',
  165. maintainer='Francesc Alted',
  166. maintainer_email='francesc@blosc.org',
  167. url='https://github.com/Blosc/bcolz',
  168. license='BSD',
  169. platforms=['any'],
  170. ext_modules=[
  171. Extension(
  172. 'bcolz.carray_ext',
  173. include_dirs=inc_dirs,
  174. define_macros=def_macros,
  175. sources=sources,
  176. library_dirs=lib_dirs,
  177. libraries=libs,
  178. extra_link_args=LFLAGS,
  179. extra_compile_args=CFLAGS
  180. )
  181. ],
  182. install_requires=['numpy>=1.7'],
  183. setup_requires=[
  184. 'cython>=0.22',
  185. 'numpy>=1.7',
  186. 'setuptools>18.0',
  187. 'setuptools-scm>1.5.4'
  188. ],
  189. tests_require=tests_require,
  190. extras_require=dict(
  191. optional=[
  192. 'numexpr>=2.5.2',
  193. 'dask>=0.9.0',
  194. 'pandas',
  195. 'tables'
  196. ],
  197. test=tests_require
  198. ),
  199. packages=find_packages(),
  200. package_data={'bcolz': ['carray_ext.pxd']},
  201. cmdclass=LazyCommandClass(),
  202. )