1#!/usr/bin/env python 2 3""" 4PETSc for Python 5================ 6 7Python bindings for PETSc libraries. 8""" 9 10 11## try: 12## import setuptools 13## except ImportError: 14## pass 15 16import sys, os 17 18# -------------------------------------------------------------------- 19# Metadata 20# -------------------------------------------------------------------- 21 22from conf.metadata import metadata 23 24def name(): 25 return 'petsc4py' 26 27def version(): 28 import re 29 fh = open(os.path.join('src', '__init__.py')) 30 try: data = fh.read() 31 finally: fh.close() 32 m = re.search(r"__version__\s*=\s*'(.*)'", data) 33 return m.groups()[0] 34 35name = name() 36version = version() 37 38url = 'http://%(name)s.googlecode.com/' % vars() 39download = url + 'files/%(name)s-%(version)s.tar.gz' % vars() 40 41descr = __doc__.strip().split('\n'); del descr[1:3] 42devstat = ['Development Status :: 3 - Alpha'] 43keywords = ['PETSc', 'MPI'] 44 45metadata['name'] = name 46metadata['version'] = version 47metadata['description'] = descr.pop(0) 48metadata['long_description'] = '\n'.join(descr) 49metadata['keywords'] += keywords 50metadata['classifiers'] += devstat 51metadata['url'] = url 52metadata['download_url'] = download 53 54metadata['provides'] = ['petsc4py'] 55metadata['requires'] = ['numpy'] 56 57# -------------------------------------------------------------------- 58# Extension modules 59# -------------------------------------------------------------------- 60 61def get_ext_modules(Extension): 62 from os import walk, path 63 from glob import glob 64 depends = [] 65 for pth, dirs, files in walk('src'): 66 depends += glob(path.join(pth, '*.h')) 67 depends += glob(path.join(pth, '*.c')) 68 try: 69 import numpy 70 numpy_includes = [numpy.get_include()] 71 except ImportError: 72 numpy_includes = [] 73 return [Extension('petsc4py.lib.PETSc', 74 sources=['src/PETSc.c', 75 'src/libpetsc4py.c', 76 ], 77 include_dirs=['src/include', 78 ] + numpy_includes, 79 depends=depends)] 80 81# -------------------------------------------------------------------- 82# Setup 83# -------------------------------------------------------------------- 84 85from conf.petscconf import setup, Extension 86from conf.petscconf import config, build, build_src, build_ext 87from conf.petscconf import test, sdist 88 89def run_setup(): 90 if (('distribute' in sys.modules) or 91 ('setuptools' in sys.modules)): 92 metadata['install_requires'] = ['numpy'] 93 if not os.environ.get('PETSC_DIR'): 94 metadata['install_requires'].append('petsc') 95 if 'setuptools' in sys.modules: 96 metadata['zip_safe'] = False 97 setup(packages = ['petsc4py', 98 'petsc4py.lib',], 99 package_dir = {'petsc4py' : 'src', 100 'petsc4py.lib' : 'src/lib'}, 101 package_data = {'petsc4py' : ['include/petsc4py/*.h', 102 'include/petsc4py/*.i', 103 'include/petsc4py/*.pxd', 104 'include/petsc4py/*.pxi', 105 'include/petsc4py/*.pyx',], 106 'petsc4py.lib' : ['petsc.cfg'],}, 107 ext_modules = get_ext_modules(Extension), 108 cmdclass = {'config' : config, 109 'build' : build, 110 'build_src' : build_src, 111 'build_ext' : build_ext, 112 'test' : test, 113 'sdist' : sdist, 114 }, 115 **metadata) 116 117def chk_cython(CYTHON_VERSION_REQUIRED): 118 from distutils import log 119 from distutils.version import StrictVersion as Version 120 warn = lambda msg='': sys.stderr.write(msg+'\n') 121 # 122 cython_zip = 'cython.zip' 123 if os.path.isfile(cython_zip): 124 path = os.path.abspath(cython_zip) 125 if sys.path[0] != path: 126 sys.path.insert(0, os.path.abspath(cython_zip)) 127 log.info("adding '%s' to sys.path", cython_zip) 128 # 129 try: 130 import Cython 131 except ImportError: 132 warn("*"*80) 133 warn() 134 warn(" You need to generate C source files with Cython!!") 135 warn(" Download and install Cython <http://www.cython.org>") 136 warn() 137 warn("*"*80) 138 return False 139 # 140 try: 141 CYTHON_VERSION = Cython.__version__ 142 except AttributeError: 143 from Cython.Compiler.Version import version as CYTHON_VERSION 144 CYTHON_VERSION = CYTHON_VERSION.split('+', 1)[0] 145 for s in ('.alpha', 'alpha'): 146 CYTHON_VERSION = CYTHON_VERSION.replace(s, 'a') 147 for s in ('.beta', 'beta', '.rc', 'rc', '.c', 'c'): 148 CYTHON_VERSION = CYTHON_VERSION.replace(s, 'b') 149 if (CYTHON_VERSION_REQUIRED is not None and 150 Version(CYTHON_VERSION) < Version(CYTHON_VERSION_REQUIRED)): 151 warn("*"*80) 152 warn() 153 warn(" You need to install Cython %s (you have version %s)" 154 % (CYTHON_VERSION_REQUIRED, CYTHON_VERSION)) 155 warn(" Download and install Cython <http://www.cython.org>") 156 warn() 157 warn("*"*80) 158 return False 159 # 160 return True 161 162def run_cython(source, depends=(), includes=(), 163 destdir_c=None, destdir_h=None, wdir=None, 164 force=False, VERSION=None): 165 from glob import glob 166 from distutils import log 167 from distutils import dep_util 168 from distutils.errors import DistutilsError 169 target = os.path.splitext(source)[0]+".c" 170 cwd = os.getcwd() 171 try: 172 if wdir: os.chdir(wdir) 173 alldeps = [source] 174 for dep in depends: 175 alldeps += glob(dep) 176 if not (force or dep_util.newer_group(alldeps, target)): 177 log.debug("skipping '%s' -> '%s' (up-to-date)", 178 source, target) 179 return 180 finally: 181 os.chdir(cwd) 182 if not chk_cython(VERSION): 183 raise DistutilsError("requires Cython>=%s" % VERSION) 184 log.info("cythonizing '%s' -> '%s'", source, target) 185 from conf.cythonize import cythonize 186 err = cythonize(source, 187 includes=includes, 188 destdir_c=destdir_c, 189 destdir_h=destdir_h, 190 wdir=wdir) 191 if err: 192 raise DistutilsError( 193 "Cython failure: '%s' -> '%s'" % (source, target)) 194 195def build_sources(cmd): 196 CYTHON_VERSION_REQUIRED = '0.13' 197 if not (os.path.isdir('.hg') or 198 os.path.isdir('.git') or 199 cmd.force): return 200 # petsc4py.PETSc 201 source = 'petsc4py.PETSc.pyx' 202 depends = ("include/*/*.pxd", 203 "*/*.pyx", 204 "*/*.pxi",) 205 includes = ['include'] 206 destdir_h = os.path.join('include', 'petsc4py') 207 run_cython(source, depends, includes, 208 destdir_c=None, destdir_h=destdir_h, wdir='src', 209 force=cmd.force, VERSION=CYTHON_VERSION_REQUIRED) 210 # libpetsc4py 211 source = os.path.join('libpetsc4py', 'libpetsc4py.pyx') 212 depends = ["include/petsc4py/*.pxd", 213 "libpetsc4py/*.pyx", 214 "libpetsc4py/*.pxi"] 215 includes = ['include'] 216 run_cython(source, depends, includes, 217 destdir_c=None, destdir_h=None, wdir='src', 218 force=cmd.force, VERSION=CYTHON_VERSION_REQUIRED) 219 220build_src.run = build_sources 221 222def run_testsuite(cmd): 223 from distutils.errors import DistutilsError 224 sys.path.insert(0, 'test') 225 try: 226 from runtests import main 227 finally: 228 del sys.path[-1] 229 err = main(cmd.args or []) 230 if err: 231 raise DistutilsError("test") 232 233test.run = run_testsuite 234 235# -------------------------------------------------------------------- 236 237def main(): 238 run_setup() 239 240if __name__ == '__main__': 241 main() 242 243# -------------------------------------------------------------------- 244