PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/setup.py

https://bitbucket.org/karpeev/petsc
Python | 307 lines | 272 code | 5 blank | 30 comment | 5 complexity | f3aefeb0ef04577dbfd66ca821d1a2c9 MD5 | raw file
  1. #!/usr/bin/env python
  2. """
  3. PETSc: Portable, Extensible Toolkit for Scientific Computation
  4. ==============================================================
  5. The Portable, Extensible Toolkit for Scientific Computation (PETSc),
  6. is a suite of data structures and routines for the scalable (parallel)
  7. solution of scientific applications modeled by partial differential
  8. equations. It employs the Message Passing Interface (MPI) standard for
  9. all message-passing communication.
  10. .. note::
  11. To install ``PETSc`` and ``petsc4py`` (``mpi4py`` is optional
  12. but highly recommended) use::
  13. $ pip install numpy mpi4py
  14. $ pip install petsc petsc4py
  15. .. tip::
  16. You can also install the in-development versions with::
  17. $ pip install Cython numpy mpi4py
  18. $ pip install --no-deps https://bitbucket.org/petsc/petsc/get/master.tar.gz
  19. $ pip install --no-deps https://bitbucket.org/petsc/petsc4py/get/master.tar.gz
  20. """
  21. import sys, os
  22. from setuptools import setup
  23. from setuptools.command.install import install as _install
  24. from distutils.util import get_platform, split_quoted
  25. from distutils.spawn import find_executable
  26. from distutils import log
  27. init_py = """\
  28. # Author: PETSc Team
  29. # Contact: petsc-maint@mcs.anl.gov
  30. def get_petsc_dir():
  31. import os
  32. return os.path.dirname(__file__)
  33. def get_config():
  34. conf = {}
  35. conf['PETSC_DIR'] = get_petsc_dir()
  36. return conf
  37. """
  38. metadata = {
  39. 'provides' : ['petsc'],
  40. 'zip_safe' : False,
  41. }
  42. CONFIGURE_OPTIONS = []
  43. def bootstrap():
  44. # Set PETSC_DIR and PETSC_ARCH
  45. PETSC_DIR = os.path.abspath(os.getcwd())
  46. PETSC_ARCH = 'arch-python-' + get_platform()
  47. os.environ['PETSC_DIR'] = PETSC_DIR
  48. os.environ['PETSC_ARCH'] = PETSC_ARCH
  49. sys.path.insert(0, os.path.join(PETSC_DIR, 'config'))
  50. sys.path.insert(0, os.path.join(PETSC_DIR, 'lib','petsc','conf'))
  51. # Generate package __init__.py file
  52. from distutils.dir_util import mkpath
  53. pkgdir = os.path.join('config', 'pypi')
  54. if not os.path.exists(pkgdir): mkpath(pkgdir)
  55. pkgfile = os.path.join(pkgdir, '__init__.py')
  56. fh = open(pkgfile, 'w')
  57. fh.write(init_py)
  58. fh.close()
  59. # Configure options
  60. options = os.environ.get('PETSC_CONFIGURE_OPTIONS', '')
  61. CONFIGURE_OPTIONS.extend(split_quoted(options))
  62. if '--with-mpi=0' not in CONFIGURE_OPTIONS:
  63. # Simple-minded lookup for MPI and mpi4py
  64. mpi4py = mpicc = None
  65. try:
  66. import mpi4py
  67. conf = mpi4py.get_config()
  68. mpicc = conf.get('mpicc')
  69. except ImportError: # mpi4py is not installed
  70. mpi4py = None
  71. mpicc = (os.environ.get('MPICC') or
  72. find_executable('mpicc'))
  73. except AttributeError: # mpi4py is too old
  74. pass
  75. if not mpi4py and mpicc:
  76. metadata['install_requires'] = ['mpi4py>=1.2.2']
  77. def config(prefix, dry_run=False):
  78. log.info('PETSc: configure')
  79. options = [
  80. '--prefix=' + prefix,
  81. 'PETSC_ARCH='+os.environ['PETSC_ARCH'],
  82. '--with-shared-libraries=1',
  83. '--with-debugging=0',
  84. '--with-c2html=0', # not needed
  85. ]
  86. if '--with-fc=0' in CONFIGURE_OPTIONS:
  87. options.append('--with-sowing=0')
  88. if '--with-mpi=0' not in CONFIGURE_OPTIONS:
  89. try:
  90. import mpi4py
  91. conf = mpi4py.get_config()
  92. mpicc = conf.get('mpicc')
  93. mpicxx = conf.get('mpicxx')
  94. mpif90 = conf.get('mpif90')
  95. except (ImportError, AttributeError):
  96. mpicc = os.environ.get('MPICC') or find_executable('mpicc')
  97. mpicxx = os.environ.get('MPICXX') or find_executable('mpicxx')
  98. mpif90 = os.environ.get('MPIF90') or find_executable('mpif90')
  99. if mpicc:
  100. options.append('--with-cc='+mpicc)
  101. if '--with-cxx=0' not in CONFIGURE_OPTIONS:
  102. if mpicxx:
  103. options.append('--with-cxx='+mpicxx)
  104. else:
  105. options.append('--with-cxx=0')
  106. if '--with-fc=0' not in CONFIGURE_OPTIONS:
  107. if mpif90:
  108. options.append('--with-fc='+mpif90)
  109. else:
  110. options.append('--with-fc=0')
  111. options.append('--with-sowing=0')
  112. else:
  113. options.append('--with-mpi=0')
  114. options.extend(CONFIGURE_OPTIONS)
  115. #
  116. log.info('configure options:')
  117. for opt in options:
  118. log.info(' '*4 + opt)
  119. # Run PETSc configure
  120. if dry_run: return
  121. use_config_py = True
  122. if use_config_py:
  123. import configure
  124. configure.petsc_configure(options)
  125. import logger
  126. logger.Logger.defaultLog = None
  127. else:
  128. command = ['./configure'] + options
  129. status = os.system(" ".join(command))
  130. if status != 0: raise RuntimeError(status)
  131. def build(dry_run=False):
  132. log.info('PETSc: build')
  133. # Run PETSc build
  134. if dry_run: return
  135. use_builder_py = False
  136. if use_builder_py:
  137. import builder
  138. builder.PETScMaker().run()
  139. import logger
  140. logger.Logger.defaultLog = None
  141. else:
  142. make = find_executable('make')
  143. command = [make, 'all']
  144. status = os.system(" ".join(command))
  145. if status != 0: raise RuntimeError(status)
  146. def install(dest_dir, dry_run=False):
  147. log.info('PETSc: install')
  148. options = [
  149. '--destDir=' + dest_dir,
  150. ]
  151. log.info('install options:')
  152. for opt in options:
  153. log.info(' '*4 + opt)
  154. # Run PETSc installer
  155. if dry_run: return
  156. use_install_py = True
  157. if use_install_py:
  158. import install
  159. install.Installer(options).run()
  160. import logger
  161. logger.Logger.defaultLog = None
  162. else:
  163. make = find_executable('make')
  164. command = [make, 'install', 'DESTDIR='+dest_dir]
  165. status = os.system(" ".join(command))
  166. if status != 0: raise RuntimeError(status)
  167. class context(object):
  168. def __init__(self):
  169. self.sys_argv = sys.argv[:]
  170. self.wdir = os.getcwd()
  171. def enter(self):
  172. del sys.argv[1:]
  173. pdir = os.environ['PETSC_DIR']
  174. os.chdir(pdir)
  175. return self
  176. def exit(self):
  177. sys.argv[:] = self.sys_argv
  178. os.chdir(self.wdir)
  179. class cmd_install(_install):
  180. def initialize_options(self):
  181. _install.initialize_options(self)
  182. self.optimize = 1
  183. def finalize_options(self):
  184. _install.finalize_options(self)
  185. self.install_lib = self.install_platlib
  186. self.install_libbase = self.install_lib
  187. def run(self):
  188. root_dir = os.path.abspath(self.install_lib)
  189. dest_dir = prefix = os.path.join(root_dir, 'petsc')
  190. #
  191. ctx = context().enter()
  192. try:
  193. config(prefix, self.dry_run)
  194. build(self.dry_run)
  195. install(dest_dir, self.dry_run)
  196. finally:
  197. ctx.exit()
  198. #
  199. self.outputs = []
  200. for dirpath, _, filenames in os.walk(dest_dir):
  201. for fn in filenames:
  202. self.outputs.append(os.path.join(dirpath, fn))
  203. #
  204. _install.run(self)
  205. def get_outputs(self):
  206. outputs = getattr(self, 'outputs', [])
  207. outputs += _install.get_outputs(self)
  208. return outputs
  209. def version():
  210. import re
  211. version_re = {
  212. 'major' : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"),
  213. 'minor' : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"),
  214. 'micro' : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"),
  215. 'patch' : re.compile(r"#define\s+PETSC_VERSION_PATCH\s+(\d+)"),
  216. 'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+(\d+)"),
  217. }
  218. petscversion_h = os.path.join('include','petscversion.h')
  219. data = open(petscversion_h, 'r').read()
  220. major = int(version_re['major'].search(data).groups()[0])
  221. minor = int(version_re['minor'].search(data).groups()[0])
  222. micro = int(version_re['micro'].search(data).groups()[0])
  223. patch = int(version_re['patch'].search(data).groups()[0])
  224. release = int(version_re['release'].search(data).groups()[0])
  225. if release:
  226. v = "%d.%d" % (major, minor)
  227. if micro > 0:
  228. v += ".%d" % micro
  229. #if patch > 0:
  230. # v += ".post%d" % patch
  231. else:
  232. v = "%d.%d.dev%d" % (major, minor+1, 0)
  233. return v
  234. def tarball():
  235. VERSION = version()
  236. if '.dev' in VERSION:
  237. return None
  238. bits = VERSION.split('.')
  239. if len(bits) == 2: bits.append('0')
  240. PETSC_VERSION = '.'.join(bits[:3])
  241. return ('http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/'
  242. 'petsc-lite-%s.tar.gz#egg=petsc-%s' % (PETSC_VERSION, VERSION))
  243. description = __doc__.split('\n')[1:-1]; del description[1:3]
  244. classifiers = """
  245. Development Status :: 5 - Production/Stable
  246. Intended Audience :: Developers
  247. Intended Audience :: Science/Research
  248. License :: OSI Approved :: BSD License
  249. Operating System :: POSIX
  250. Programming Language :: C
  251. Programming Language :: C++
  252. Programming Language :: Fortran
  253. Programming Language :: Python
  254. Topic :: Scientific/Engineering
  255. Topic :: Software Development :: Libraries
  256. """
  257. bootstrap()
  258. setup(name='petsc',
  259. version=version(),
  260. description=description.pop(0),
  261. long_description='\n'.join(description),
  262. classifiers= classifiers.split('\n')[1:-1],
  263. keywords = ['PETSc', 'MPI'],
  264. platforms=['POSIX'],
  265. license='PETSc',
  266. url='http://www.mcs.anl.gov/petsc/',
  267. download_url=tarball(),
  268. author='PETSc Team',
  269. author_email='petsc-maint@mcs.anl.gov',
  270. maintainer='Lisandro Dalcin',
  271. maintainer_email='dalcinl@gmail.com',
  272. packages = ['petsc'],
  273. package_dir = {'petsc': 'config/pypi'},
  274. cmdclass={'install': cmd_install},
  275. **metadata)