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 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 26PETSC_DIR = None 27PETSC_ARCH = None 28 29init_py = """\ 30# Author: PETSc Team 31# Contact: petsc-users@mcs.anl.gov 32 33def get_petsc_dir(): 34 import os 35 return os.path.dirname(__file__) 36 37def get_petsc_arch(): 38 return '' 39 40def get_config(): 41 conf = {} 42 conf['petsc_dir'] = get_petsc_dir() 43 return conf 44""" 45 46metadata = { 47 'provides' : ['petsc'], 48 'requires' : [], 49} 50 51def bootstrap(): 52 # Set PETSC_DIR and PETSC_ARCH, 53 global PETSC_DIR, PETSC_ARCH 54 PETSC_DIR = os.path.abspath(os.getcwd()) 55 PETSC_ARCH = get_platform() + '-python' 56 os.environ['PETSC_DIR'] = PETSC_DIR 57 os.environ['PETSC_ARCH'] = PETSC_ARCH 58 sys.path.insert(0, os.path.join(PETSC_DIR, 'config')) 59 # Generate package __init__.py file 60 try: 61 if not os.path.exists(PETSC_ARCH): 62 os.mkdir(PETSC_ARCH) 63 pkgfile = os.path.join(PETSC_ARCH, '__init__.py') 64 if not os.path.exists(pkgfile): 65 open(pkgfile, 'wt').write(init_py) 66 except: 67 pass 68 # Simple-minded lookup for MPI and mpi4py 69 mpi4py = mpicc = None 70 try: 71 import mpi4py 72 conf = mpi4py.get_config() 73 mpicc = conf.get('mpicc') 74 except ImportError: # mpi4py is not installed 75 mpicc = os.environ.get('MPICC') or find_executable('mpicc') 76 except AttributeError: # mpi4py is too old 77 pass 78 if not mpi4py and mpicc: 79 if (('distribute' in sys.modules) or 80 ('setuptools' in sys.modules)): 81 metadata['install_requires']= ['mpi4py>=1.2.2'] 82 83def config(dry_run=False): 84 log.info('PETSc: configure') 85 if dry_run: return 86 options = [ 87 'PETSC_ARCH='+os.environ['PETSC_ARCH'], 88 '--with-shared-libraries', 89 '--with-cmake=0', # not needed 90 ] 91 # MPI 92 try: 93 import mpi4py 94 conf = mpi4py.get_config() 95 mpicc = conf.get('mpicc') 96 except (ImportError, AttributeError): 97 mpicc = os.environ.get('MPICC') or find_executable('mpicc') 98 if mpicc: 99 options.append('--with-cc='+mpicc) 100 else: 101 options.append('--with-mpi=0') 102 options.extend([ 103 '--with-fc=0', # XXX mpif90? 104 '--with-cxx=0', # XXX mpicxx? 105 ]) 106 # Run PETSc configure 107 import configure 108 configure.petsc_configure(options) 109 import logger 110 logger.Logger.defaultLog = None 111 112def build(dry_run=False): 113 log.info('PETSc: build') 114 if dry_run: return 115 # Run PETSc builder 116 import builder 117 builder.PETScMaker().run() 118 import logger 119 logger.Logger.defaultLog = None 120 121def install(dest_dir, prefix=None, dry_run=False): 122 log.info('PETSc: install') 123 if dry_run: return 124 if prefix is None: 125 prefix = dest_dir 126 options = [ 127 '--destDir=' + dest_dir, 128 '--prefix=' + prefix 129 ] 130 # Run PETSc installer 131 import install 132 install.Installer(options).run() 133 import logger 134 logger.Logger.defaultLog = None 135 # temporary hack - delete log files created by BuildSystem 136 delfiles=['RDict.db','RDict.log', 137 'build.log','default.log', 138 'build.log.bkp','default.log.bkp'] 139 for delfile in delfiles: 140 try: 141 if (os.path.exists(delfile) and 142 os.stat(delfile).st_uid==0): 143 os.remove(delfile) 144 except: 145 pass 146 147class cmd_build(_build): 148 149 def finalize_options(self): 150 if self.build_base is None: 151 self.build_base= 'build' 152 self.build_base = os.path.join( 153 os.environ['PETSC_ARCH'], self.build_base) 154 _build.finalize_options(self) 155 156 def run(self): 157 _build.run(self) 158 wdir = os.getcwd() 159 pdir = os.environ['PETSC_DIR'] 160 try: 161 os.chdir(pdir) 162 config(self.dry_run) 163 build(self.dry_run) 164 finally: 165 os.chdir(wdir) 166 167class cmd_install(_install): 168 169 def run(self): 170 _install.run(self) 171 root_dir = self.install_platlib 172 dest_dir = os.path.join(root_dir, 'petsc') 173 bdist_base = self.get_finalized_command('bdist').bdist_base 174 if dest_dir.startswith(bdist_base): 175 prefix = dest_dir[len(bdist_base)+1:] 176 prefix = prefix[prefix.index(os.path.sep):] 177 else: 178 prefix = dest_dir 179 dest_dir = os.path.abspath(dest_dir) 180 prefix = os.path.abspath(prefix) 181 wdir = os.getcwd() 182 pdir = os.environ['PETSC_DIR'] 183 try: 184 os.chdir(pdir) 185 install(dest_dir, prefix, self.dry_run) 186 finally: 187 os.chdir(wdir) 188 189class cmd_sdist(_sdist): 190 191 def initialize_options(self): 192 _sdist.initialize_options(self) 193 self.force_manifest = 1 194 self.template = os.path.join('config', 'MANIFEST.in') 195 196 def run(self): 197 _sdist.run(self) 198 try: 199 os.remove(self.manifest) 200 except Exception: 201 pass 202 203def version(): 204 return '3.2.dev1' # XXX should parse include/petscversion.h 205 206def tarball(): 207 return None 208 return ('http://ftp.mcs.anl.gov/pub/petsc/<XXX>/' # XXX fix this line 209 'petsc-lite-%s.tar.gz' % version() ) 210 211description = __doc__.split('\n')[1:-1]; del description[1:3] 212classifiers = """ 213License :: Public Domain 214Operating System :: POSIX 215Intended Audience :: Developers 216Intended Audience :: Science/Research 217Programming Language :: C 218Programming Language :: C++ 219Programming Language :: Fortran 220Programming Language :: Python 221Topic :: Scientific/Engineering 222Topic :: Software Development :: Libraries 223""" 224 225bootstrap() 226setup(name='petsc', 227 version=version(), 228 description=description.pop(0), 229 long_description='\n'.join(description), 230 classifiers= classifiers.split('\n')[1:-1], 231 keywords = ['PETSc', 'MPI'], 232 platforms=['POSIX'], 233 license='PETSc', 234 235 url='http://www.mcs.anl.gov/petsc/', 236 download_url=tarball(), 237 238 author='PETSc Team', 239 author_email='petsc-users@mcs.anl.gov', 240 maintainer='Lisandro Dalcin', 241 maintainer_email='dalcinl@gmail.com', 242 243 packages = ['petsc'], 244 package_dir = {'petsc': os.environ['PETSC_ARCH']}, 245 cmdclass={ 246 'build': cmd_build, 247 'install': cmd_install, 248 'sdist': cmd_sdist, 249 }, 250 **metadata) 251