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