15808f684SSatish Balay#!/usr/bin/env python 25808f684SSatish Balay# Author: Lisandro Dalcin 35808f684SSatish Balay# Contact: dalcinl@gmail.com 45808f684SSatish Balay 55808f684SSatish Balay""" 65808f684SSatish BalayPETSc for Python 75808f684SSatish Balay""" 85808f684SSatish Balay 95808f684SSatish Balayimport sys 105808f684SSatish Balayimport os 115808f684SSatish Balayimport re 125808f684SSatish Balay 135808f684SSatish Balaytry: 145808f684SSatish Balay import setuptools 155808f684SSatish Balayexcept ImportError: 165808f684SSatish Balay setuptools = None 175808f684SSatish Balay 185808f684SSatish Balaypyver = sys.version_info[:2] 195808f684SSatish Balayif pyver < (2, 6) or (3, 0) <= pyver < (3, 2): 205808f684SSatish Balay raise RuntimeError("Python version 2.6, 2.7 or >= 3.2 required") 215808f684SSatish Balayif pyver == (2, 6) or pyver == (3, 2): 225808f684SSatish Balay sys.stderr.write( 235808f684SSatish Balay "WARNING: Python %d.%d is not supported.\n" % pyver) 245808f684SSatish Balay 255808f684SSatish Balay# -------------------------------------------------------------------- 265808f684SSatish Balay# Metadata 275808f684SSatish Balay# -------------------------------------------------------------------- 285808f684SSatish Balay 295808f684SSatish Balaytopdir = os.path.abspath(os.path.dirname(__file__)) 30*a9c71d45SLisandro Dalcinsys.path.insert(0, topdir) 315808f684SSatish Balay 325808f684SSatish Balayfrom conf.metadata import metadata 335808f684SSatish Balay 345808f684SSatish Balaydef name(): 355808f684SSatish Balay return 'petsc4py' 365808f684SSatish Balay 375808f684SSatish Balaydef version(): 385808f684SSatish Balay with open(os.path.join(topdir, 'src', '__init__.py')) as f: 395808f684SSatish Balay m = re.search(r"__version__\s*=\s*'(.*)'", f.read()) 405808f684SSatish Balay return m.groups()[0] 415808f684SSatish Balay 425808f684SSatish Balaydef description(): 435808f684SSatish Balay with open(os.path.join(topdir, 'DESCRIPTION.rst')) as f: 445808f684SSatish Balay return f.read() 455808f684SSatish Balay 465808f684SSatish Balayname = name() 475808f684SSatish Balayversion = version() 485808f684SSatish Balay 495808f684SSatish Balayurl = 'https://gitlab.com/petsc/petsc4py' 505808f684SSatish Balaypypiroot = 'https://pypi.io/packages/source/%s/%s/' % (name[0], name) 515808f684SSatish Balaydownload = pypiroot + '%(name)s-%(version)s.tar.gz' % vars() 525808f684SSatish Balay 535808f684SSatish Balaydevstat = ['Development Status :: 5 - Production/Stable'] 545808f684SSatish Balaykeywords = ['PETSc', 'MPI'] 555808f684SSatish Balay 565808f684SSatish Balaymetadata['name'] = name 575808f684SSatish Balaymetadata['version'] = version 585808f684SSatish Balaymetadata['description'] = __doc__.strip() 595808f684SSatish Balaymetadata['long_description'] = description() 605808f684SSatish Balaymetadata['keywords'] += keywords 615808f684SSatish Balaymetadata['classifiers'] += devstat 625808f684SSatish Balaymetadata['url'] = url 635808f684SSatish Balaymetadata['download_url'] = download 645808f684SSatish Balay 655808f684SSatish Balaymetadata['provides'] = ['petsc4py'] 665808f684SSatish Balaymetadata['requires'] = ['numpy'] 675808f684SSatish Balay 685808f684SSatish Balay# -------------------------------------------------------------------- 695808f684SSatish Balay# Extension modules 705808f684SSatish Balay# -------------------------------------------------------------------- 715808f684SSatish Balay 725808f684SSatish Balaydef get_ext_modules(Extension): 735808f684SSatish Balay from os import walk, path 745808f684SSatish Balay from glob import glob 755808f684SSatish Balay depends = [] 765808f684SSatish Balay for pth, dirs, files in walk('src'): 775808f684SSatish Balay depends += glob(path.join(pth, '*.h')) 785808f684SSatish Balay depends += glob(path.join(pth, '*.c')) 795808f684SSatish Balay try: 805808f684SSatish Balay import numpy 815808f684SSatish Balay numpy_includes = [numpy.get_include()] 825808f684SSatish Balay except ImportError: 835808f684SSatish Balay numpy_includes = [] 845808f684SSatish Balay return [Extension('petsc4py.lib.PETSc', 855808f684SSatish Balay sources=['src/PETSc.c', 865808f684SSatish Balay 'src/libpetsc4py.c', 875808f684SSatish Balay ], 885808f684SSatish Balay include_dirs=['src/include', 895808f684SSatish Balay ] + numpy_includes, 905808f684SSatish Balay depends=depends)] 915808f684SSatish Balay 925808f684SSatish Balay# -------------------------------------------------------------------- 935808f684SSatish Balay# Setup 945808f684SSatish Balay# -------------------------------------------------------------------- 955808f684SSatish Balay 965808f684SSatish Balayfrom conf.petscconf import setup, Extension 975808f684SSatish Balayfrom conf.petscconf import config, build, build_src, build_ext, install 985808f684SSatish Balayfrom conf.petscconf import clean, test, sdist 995808f684SSatish Balay 100*a9c71d45SLisandro DalcinCYTHON = '0.24' 1015808f684SSatish Balay 1025808f684SSatish Balaydef run_setup(): 1035808f684SSatish Balay setup_args = metadata.copy() 1045808f684SSatish Balay if setuptools: 1055808f684SSatish Balay setup_args['zip_safe'] = False 1065808f684SSatish Balay setup_args['install_requires'] = ['numpy'] 1075808f684SSatish Balay PETSC_DIR = os.environ.get('PETSC_DIR') 1085808f684SSatish Balay if not (PETSC_DIR and os.path.isdir(PETSC_DIR)): 1095808f684SSatish Balay vstr = setup_args['version'].split('.')[:2] 1105808f684SSatish Balay x, y = int(vstr[0]), int(vstr[1]) 1115808f684SSatish Balay PETSC = ">=%s.%s,<%s.%s" % (x, y, x, y+1) 1125808f684SSatish Balay setup_args['install_requires'] += ['petsc'+PETSC] 1135808f684SSatish Balay if setuptools: 1145808f684SSatish Balay src = os.path.join('src', 'petsc4py.PETSc.c') 1155808f684SSatish Balay has_src = os.path.exists(os.path.join(topdir, src)) 1165808f684SSatish Balay has_git = os.path.isdir(os.path.join(topdir, '.git')) 1175808f684SSatish Balay has_hg = os.path.isdir(os.path.join(topdir, '.hg')) 1183594a89dSLisandro Dalcin suffix = os.path.join('src', 'binding', 'petsc4py') 1193594a89dSLisandro Dalcin in_petsc = topdir.endswith(os.path.sep + suffix) 1203594a89dSLisandro Dalcin if not has_src or has_git or has_hg or in_petsc: 1215808f684SSatish Balay setup_args['setup_requires'] = ['Cython>='+CYTHON] 1225808f684SSatish Balay # 1235808f684SSatish Balay setup(packages = ['petsc4py', 1245808f684SSatish Balay 'petsc4py.lib',], 1255808f684SSatish Balay package_dir = {'petsc4py' : 'src', 1265808f684SSatish Balay 'petsc4py.lib' : 'src/lib'}, 1275808f684SSatish Balay package_data = {'petsc4py' : ['include/petsc4py/*.h', 1285808f684SSatish Balay 'include/petsc4py/*.i', 1295808f684SSatish Balay 'include/petsc4py/*.pxd', 1305808f684SSatish Balay 'include/petsc4py/*.pxi', 1315808f684SSatish Balay 'include/petsc4py/*.pyx', 1325808f684SSatish Balay 'PETSc.pxd',], 1335808f684SSatish Balay 'petsc4py.lib' : ['petsc.cfg'],}, 1345808f684SSatish Balay ext_modules = get_ext_modules(Extension), 1355808f684SSatish Balay cmdclass = {'config' : config, 1365808f684SSatish Balay 'build' : build, 1375808f684SSatish Balay 'build_src' : build_src, 1385808f684SSatish Balay 'build_ext' : build_ext, 1395808f684SSatish Balay 'install' : install, 1405808f684SSatish Balay 'clean' : clean, 1415808f684SSatish Balay 'test' : test, 1425808f684SSatish Balay 'sdist' : sdist, 1435808f684SSatish Balay }, 1445808f684SSatish Balay **setup_args) 1455808f684SSatish Balay 1465808f684SSatish Balaydef chk_cython(VERSION): 1475808f684SSatish Balay from distutils import log 1485808f684SSatish Balay from distutils.version import LooseVersion 1495808f684SSatish Balay from distutils.version import StrictVersion 1505808f684SSatish Balay warn = lambda msg='': sys.stderr.write(msg+'\n') 1515808f684SSatish Balay # 1525808f684SSatish Balay try: 1535808f684SSatish Balay import Cython 1545808f684SSatish Balay except ImportError: 1555808f684SSatish Balay warn("*"*80) 1565808f684SSatish Balay warn() 1575808f684SSatish Balay warn(" You need to generate C source files with Cython!!") 1585808f684SSatish Balay warn(" Download and install Cython <http://www.cython.org>") 1595808f684SSatish Balay warn() 1605808f684SSatish Balay warn("*"*80) 1615808f684SSatish Balay return False 1625808f684SSatish Balay # 1635808f684SSatish Balay try: 1645808f684SSatish Balay CYTHON_VERSION = Cython.__version__ 1655808f684SSatish Balay except AttributeError: 1665808f684SSatish Balay from Cython.Compiler.Version import version as CYTHON_VERSION 1675808f684SSatish Balay REQUIRED = VERSION 1685808f684SSatish Balay m = re.match(r"(\d+\.\d+(?:\.\d+)?).*", CYTHON_VERSION) 1695808f684SSatish Balay if m: 1705808f684SSatish Balay Version = StrictVersion 1715808f684SSatish Balay AVAILABLE = m.groups()[0] 1725808f684SSatish Balay else: 1735808f684SSatish Balay Version = LooseVersion 1745808f684SSatish Balay AVAILABLE = CYTHON_VERSION 1755808f684SSatish Balay if (REQUIRED is not None and 1765808f684SSatish Balay Version(AVAILABLE) < Version(REQUIRED)): 1775808f684SSatish Balay warn("*"*80) 1785808f684SSatish Balay warn() 1795808f684SSatish Balay warn(" You need to install Cython %s (you have version %s)" 1805808f684SSatish Balay % (REQUIRED, CYTHON_VERSION)) 1815808f684SSatish Balay warn(" Download and install Cython <http://www.cython.org>") 1825808f684SSatish Balay warn() 1835808f684SSatish Balay warn("*"*80) 1845808f684SSatish Balay return False 1855808f684SSatish Balay # 1865808f684SSatish Balay return True 1875808f684SSatish Balay 188*a9c71d45SLisandro Dalcindef run_cython(source, target=None, 189*a9c71d45SLisandro Dalcin depends=(), includes=(), 1905808f684SSatish Balay destdir_c=None, destdir_h=None, 1915808f684SSatish Balay wdir=None, force=False, VERSION=None): 1925808f684SSatish Balay from glob import glob 1935808f684SSatish Balay from distutils import log 1945808f684SSatish Balay from distutils import dep_util 1955808f684SSatish Balay from distutils.errors import DistutilsError 196*a9c71d45SLisandro Dalcin if target is None: 1975808f684SSatish Balay target = os.path.splitext(source)[0]+'.c' 1985808f684SSatish Balay cwd = os.getcwd() 1995808f684SSatish Balay try: 2005808f684SSatish Balay if wdir: os.chdir(wdir) 2015808f684SSatish Balay alldeps = [source] 2025808f684SSatish Balay for dep in depends: 2035808f684SSatish Balay alldeps += glob(dep) 2045808f684SSatish Balay if not (force or dep_util.newer_group(alldeps, target)): 2055808f684SSatish Balay log.debug("skipping '%s' -> '%s' (up-to-date)", 2065808f684SSatish Balay source, target) 2075808f684SSatish Balay return 2085808f684SSatish Balay finally: 2095808f684SSatish Balay os.chdir(cwd) 2105808f684SSatish Balay if not chk_cython(VERSION): 2115808f684SSatish Balay raise DistutilsError("requires Cython>=%s" % VERSION) 2125808f684SSatish Balay log.info("cythonizing '%s' -> '%s'", source, target) 2135808f684SSatish Balay from conf.cythonize import cythonize 214*a9c71d45SLisandro Dalcin err = cythonize(source, target, 2155808f684SSatish Balay includes=includes, 2165808f684SSatish Balay destdir_c=destdir_c, 2175808f684SSatish Balay destdir_h=destdir_h, 2185808f684SSatish Balay wdir=wdir) 2195808f684SSatish Balay if err: 2205808f684SSatish Balay raise DistutilsError( 2215808f684SSatish Balay "Cython failure: '%s' -> '%s'" % (source, target)) 2225808f684SSatish Balay 2235808f684SSatish Balaydef build_sources(cmd): 2245808f684SSatish Balay from os.path import exists, isdir, join 2255808f684SSatish Balay if (exists(join('src', 'petsc4py.PETSc.c')) and 2265808f684SSatish Balay not (isdir('.hg') or isdir('.git')) and 2275808f684SSatish Balay not cmd.force): return 2285808f684SSatish Balay # petsc4py.PETSc 2295808f684SSatish Balay source = 'petsc4py.PETSc.pyx' 230*a9c71d45SLisandro Dalcin target = 'petsc4py.PETSc.c' 2315808f684SSatish Balay depends = ('include/*/*.pxd', 2325808f684SSatish Balay 'PETSc/*.pyx', 2335808f684SSatish Balay 'PETSc/*.pxi',) 2345808f684SSatish Balay includes = ['include'] 2355808f684SSatish Balay destdir_h = os.path.join('include', 'petsc4py') 236*a9c71d45SLisandro Dalcin run_cython(source, target, 237*a9c71d45SLisandro Dalcin depends=depends, includes=includes, 2385808f684SSatish Balay destdir_c=None, destdir_h=destdir_h, wdir='src', 2395808f684SSatish Balay force=cmd.force, VERSION=CYTHON) 2405808f684SSatish Balay # libpetsc4py 2415808f684SSatish Balay source = os.path.join('libpetsc4py', 'libpetsc4py.pyx') 2425808f684SSatish Balay depends = ['include/petsc4py/*.pxd', 2435808f684SSatish Balay 'libpetsc4py/*.pyx', 2445808f684SSatish Balay 'libpetsc4py/*.pxi'] 2455808f684SSatish Balay includes = ['include'] 246*a9c71d45SLisandro Dalcin run_cython(source, 247*a9c71d45SLisandro Dalcin depends=depends, includes=includes, 2485808f684SSatish Balay destdir_c=None, destdir_h=None, wdir='src', 2495808f684SSatish Balay force=cmd.force, VERSION=CYTHON) 2505808f684SSatish Balay 2515808f684SSatish Balaybuild_src.run = build_sources 2525808f684SSatish Balay 2535808f684SSatish Balaydef run_testsuite(cmd): 2545808f684SSatish Balay from distutils.errors import DistutilsError 2555808f684SSatish Balay sys.path.insert(0, 'test') 2565808f684SSatish Balay try: 2575808f684SSatish Balay from runtests import main 2585808f684SSatish Balay finally: 2595808f684SSatish Balay del sys.path[0] 2605808f684SSatish Balay if cmd.dry_run: 2615808f684SSatish Balay return 2625808f684SSatish Balay args = cmd.args[:] or [] 2635808f684SSatish Balay if cmd.verbose < 1: 2645808f684SSatish Balay args.insert(0,'-q') 2655808f684SSatish Balay if cmd.verbose > 1: 2665808f684SSatish Balay args.insert(0,'-v') 2675808f684SSatish Balay err = main(args) 2685808f684SSatish Balay if err: 2695808f684SSatish Balay raise DistutilsError("test") 2705808f684SSatish Balay 2715808f684SSatish Balaytest.run = run_testsuite 2725808f684SSatish Balay 2735808f684SSatish Balay# -------------------------------------------------------------------- 2745808f684SSatish Balay 2755808f684SSatish Balaydef main(): 2765808f684SSatish Balay run_setup() 2775808f684SSatish Balay 2785808f684SSatish Balayif __name__ == '__main__': 2795808f684SSatish Balay main() 2805808f684SSatish Balay 2815808f684SSatish Balay# -------------------------------------------------------------------- 282