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 for pth, dirs, files in walk(path.join('src', 'source')): 68 depends += glob(path.join(pth, '*.h')) 69 depends += glob(path.join(pth, '*.c')) 70 try: 71 import numpy 72 numpy_includes = [numpy.get_include()] 73 except ImportError: 74 numpy_includes = [] 75 return [Extension('petsc4py.lib.PETSc', 76 sources=['src/PETSc.c', 77 'src/source/libpetsc4py.c', 78 ], 79 include_dirs=['src/include', 80 'src/source', 81 ] + numpy_includes, 82 depends=depends)] 83 84# -------------------------------------------------------------------- 85# Setup 86# -------------------------------------------------------------------- 87 88from conf.petscconf import setup, Extension 89from conf.petscconf import config, build, build_src, build_ext 90from conf.petscconf import test, sdist 91 92def run_setup(): 93 if (('distribute' in sys.modules) or 94 ('setuptools' in sys.modules)): 95 metadata['install_requires'] = ['numpy'] 96 if not os.environ.get('PETSC_DIR'): 97 metadata['install_requires'].append('petsc') 98 if 'setuptools' in sys.modules: 99 metadata['zip_safe'] = False 100 setup(packages = ['petsc4py', 101 'petsc4py.lib',], 102 package_dir = {'petsc4py' : 'src', 103 'petsc4py.lib' : 'src/lib'}, 104 package_data = {'petsc4py' : ['include/petsc4py/*.h', 105 'include/petsc4py/*.i', 106 'include/petsc4py/*.pxd', 107 'include/petsc4py/*.pxi', 108 'include/petsc4py/*.pyx',], 109 'petsc4py.lib' : ['petsc.cfg'],}, 110 ext_modules = get_ext_modules(Extension), 111 cmdclass = {'config' : config, 112 'build' : build, 113 'build_src' : build_src, 114 'build_ext' : build_ext, 115 'test' : test, 116 'sdist' : sdist, 117 }, 118 **metadata) 119 120def chk_cython(CYTHON_VERSION_REQUIRED): 121 from distutils import log 122 from distutils.version import StrictVersion as Version 123 warn = lambda msg='': sys.stderr.write(msg+'\n') 124 # 125 cython_zip = 'cython.zip' 126 if os.path.isfile(cython_zip): 127 path = os.path.abspath(cython_zip) 128 if sys.path[0] != path: 129 sys.path.insert(0, os.path.abspath(cython_zip)) 130 log.info("adding '%s' to sys.path", cython_zip) 131 # 132 try: 133 import Cython 134 except ImportError: 135 warn("*"*80) 136 warn() 137 warn(" You need to generate C source files with Cython!!") 138 warn(" Download and install Cython <http://www.cython.org>") 139 warn() 140 warn("*"*80) 141 return False 142 # 143 try: 144 CYTHON_VERSION = Cython.__version__ 145 except AttributeError: 146 from Cython.Compiler.Version import version as CYTHON_VERSION 147 CYTHON_VERSION = CYTHON_VERSION.split('+', 1)[0] 148 for s in ('.alpha', 'alpha'): 149 CYTHON_VERSION = CYTHON_VERSION.replace(s, 'a') 150 for s in ('.beta', 'beta', '.rc', 'rc', '.c', 'c'): 151 CYTHON_VERSION = CYTHON_VERSION.replace(s, 'b') 152 if (CYTHON_VERSION_REQUIRED is not None and 153 Version(CYTHON_VERSION) < Version(CYTHON_VERSION_REQUIRED)): 154 warn("*"*80) 155 warn() 156 warn(" You need to install Cython %s (you have version %s)" 157 % (CYTHON_VERSION_REQUIRED, CYTHON_VERSION)) 158 warn(" Download and install Cython <http://www.cython.org>") 159 warn() 160 warn("*"*80) 161 return False 162 # 163 return True 164 165def run_cython(source, depends=(), includes=(), 166 destdir_c=None, destdir_h=None, wdir=None, 167 force=False, VERSION=None): 168 from glob import glob 169 from distutils import log 170 from distutils import dep_util 171 from distutils.errors import DistutilsError 172 target = os.path.splitext(source)[0]+".c" 173 cwd = os.getcwd() 174 try: 175 if wdir: os.chdir(wdir) 176 alldeps = [source] 177 for dep in depends: 178 alldeps += glob(dep) 179 if not (force or dep_util.newer_group(alldeps, target)): 180 log.debug("skipping '%s' -> '%s' (up-to-date)", 181 source, target) 182 return 183 finally: 184 os.chdir(cwd) 185 if not chk_cython(VERSION): 186 raise DistutilsError("requires Cython>=%s" % VERSION) 187 log.info("cythonizing '%s' -> '%s'", source, target) 188 from conf.cythonize import cythonize 189 err = cythonize(source, 190 includes=includes, 191 destdir_c=destdir_c, 192 destdir_h=destdir_h, 193 wdir=wdir) 194 if err: 195 raise DistutilsError( 196 "Cython failure: '%s' -> '%s'" % (source, target)) 197 198def build_sources(cmd): 199 CYTHON_VERSION_REQUIRED = '0.13' 200 if not (os.path.isdir('.hg') or 201 os.path.isdir('.git') or 202 cmd.force): return 203 # petsc4py.PETSc 204 source = 'petsc4py.PETSc.pyx' 205 depends = ("include/*/*.pxd", 206 "*/*.pyx", 207 "*/*.pxi",) 208 includes = ['include'] 209 destdir_h = os.path.join('include', 'petsc4py') 210 run_cython(source, depends, includes, 211 destdir_c=None, destdir_h=destdir_h, wdir='src', 212 force=cmd.force, VERSION=CYTHON_VERSION_REQUIRED) 213 214build_src.run = build_sources 215 216def run_testsuite(cmd): 217 from distutils.errors import DistutilsError 218 sys.path.insert(0, 'test') 219 try: 220 from runtests import main 221 finally: 222 del sys.path[-1] 223 err = main(cmd.args or []) 224 if err: 225 raise DistutilsError("test") 226 227test.run = run_testsuite 228 229# -------------------------------------------------------------------- 230 231def main(): 232 run_setup() 233 234if __name__ == '__main__': 235 main() 236 237# -------------------------------------------------------------------- 238