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__)) 30a9c71d45SLisandro 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 49eaf87d4bSBarry Smithurl = 'https://gitlab.com/petsc/petsc' 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): 73*8885bf16SLisandro Dalcin from os import walk 745808f684SSatish Balay from glob import glob 75*8885bf16SLisandro Dalcin from os.path import join 76*8885bf16SLisandro Dalcin glob_join = lambda *args: glob(join(*args)) 775808f684SSatish Balay depends = [] 785808f684SSatish Balay for pth, dirs, files in walk('src'): 79*8885bf16SLisandro Dalcin depends += glob_join(pth, '*.h') 80*8885bf16SLisandro Dalcin depends += glob_join(pth, '*.c') 81*8885bf16SLisandro Dalcin if 'PETSC_DIR' in os.environ: 82*8885bf16SLisandro Dalcin pd = os.environ['PETSC_DIR'] 83*8885bf16SLisandro Dalcin pa = os.environ.get('PETSC_ARCH', '') 84*8885bf16SLisandro Dalcin depends += glob_join(pd, 'include', '*.h') 85*8885bf16SLisandro Dalcin depends += glob_join(pd, 'include', 'petsc', 'private', '*.h') 86*8885bf16SLisandro Dalcin depends += glob_join(pd, pa, 'include', 'petscconf.h') 875808f684SSatish Balay try: 885808f684SSatish Balay import numpy 895808f684SSatish Balay numpy_includes = [numpy.get_include()] 905808f684SSatish Balay except ImportError: 915808f684SSatish Balay numpy_includes = [] 925808f684SSatish Balay return [Extension('petsc4py.lib.PETSc', 935808f684SSatish Balay sources=['src/PETSc.c', 945808f684SSatish Balay 'src/libpetsc4py.c', 955808f684SSatish Balay ], 965808f684SSatish Balay include_dirs=['src/include', 975808f684SSatish Balay ] + numpy_includes, 985808f684SSatish Balay depends=depends)] 995808f684SSatish Balay 1005808f684SSatish Balay# -------------------------------------------------------------------- 1015808f684SSatish Balay# Setup 1025808f684SSatish Balay# -------------------------------------------------------------------- 1035808f684SSatish Balay 1045808f684SSatish Balayfrom conf.petscconf import setup, Extension 1055808f684SSatish Balayfrom conf.petscconf import config, build, build_src, build_ext, install 1065808f684SSatish Balayfrom conf.petscconf import clean, test, sdist 1075808f684SSatish Balay 108a9c71d45SLisandro DalcinCYTHON = '0.24' 1095808f684SSatish Balay 1105808f684SSatish Balaydef run_setup(): 1115808f684SSatish Balay setup_args = metadata.copy() 1125808f684SSatish Balay if setuptools: 1135808f684SSatish Balay setup_args['zip_safe'] = False 1145808f684SSatish Balay setup_args['install_requires'] = ['numpy'] 1155808f684SSatish Balay PETSC_DIR = os.environ.get('PETSC_DIR') 1165808f684SSatish Balay if not (PETSC_DIR and os.path.isdir(PETSC_DIR)): 1175808f684SSatish Balay vstr = setup_args['version'].split('.')[:2] 1185808f684SSatish Balay x, y = int(vstr[0]), int(vstr[1]) 1195808f684SSatish Balay PETSC = ">=%s.%s,<%s.%s" % (x, y, x, y+1) 1205808f684SSatish Balay setup_args['install_requires'] += ['petsc'+PETSC] 1215808f684SSatish Balay if setuptools: 1225808f684SSatish Balay src = os.path.join('src', 'petsc4py.PETSc.c') 1235808f684SSatish Balay has_src = os.path.exists(os.path.join(topdir, src)) 1245808f684SSatish Balay has_git = os.path.isdir(os.path.join(topdir, '.git')) 1255808f684SSatish Balay has_hg = os.path.isdir(os.path.join(topdir, '.hg')) 1263594a89dSLisandro Dalcin suffix = os.path.join('src', 'binding', 'petsc4py') 1273594a89dSLisandro Dalcin in_petsc = topdir.endswith(os.path.sep + suffix) 1283594a89dSLisandro Dalcin if not has_src or has_git or has_hg or in_petsc: 1295808f684SSatish Balay setup_args['setup_requires'] = ['Cython>='+CYTHON] 1305808f684SSatish Balay # 1315808f684SSatish Balay setup(packages = ['petsc4py', 1325808f684SSatish Balay 'petsc4py.lib',], 1335808f684SSatish Balay package_dir = {'petsc4py' : 'src', 1345808f684SSatish Balay 'petsc4py.lib' : 'src/lib'}, 1355808f684SSatish Balay package_data = {'petsc4py' : ['include/petsc4py/*.h', 1365808f684SSatish Balay 'include/petsc4py/*.i', 1375808f684SSatish Balay 'include/petsc4py/*.pxd', 1385808f684SSatish Balay 'include/petsc4py/*.pxi', 1395808f684SSatish Balay 'include/petsc4py/*.pyx', 1405808f684SSatish Balay 'PETSc.pxd',], 1415808f684SSatish Balay 'petsc4py.lib' : ['petsc.cfg'],}, 1425808f684SSatish Balay ext_modules = get_ext_modules(Extension), 1435808f684SSatish Balay cmdclass = {'config' : config, 1445808f684SSatish Balay 'build' : build, 1455808f684SSatish Balay 'build_src' : build_src, 1465808f684SSatish Balay 'build_ext' : build_ext, 1475808f684SSatish Balay 'install' : install, 1485808f684SSatish Balay 'clean' : clean, 1495808f684SSatish Balay 'test' : test, 1505808f684SSatish Balay 'sdist' : sdist, 1515808f684SSatish Balay }, 1525808f684SSatish Balay **setup_args) 1535808f684SSatish Balay 1545808f684SSatish Balaydef chk_cython(VERSION): 1555808f684SSatish Balay from distutils import log 1565808f684SSatish Balay from distutils.version import LooseVersion 1575808f684SSatish Balay from distutils.version import StrictVersion 1585808f684SSatish Balay warn = lambda msg='': sys.stderr.write(msg+'\n') 1595808f684SSatish Balay # 1605808f684SSatish Balay try: 1615808f684SSatish Balay import Cython 1625808f684SSatish Balay except ImportError: 1635808f684SSatish Balay warn("*"*80) 1645808f684SSatish Balay warn() 1655808f684SSatish Balay warn(" You need to generate C source files with Cython!!") 1665808f684SSatish Balay warn(" Download and install Cython <http://www.cython.org>") 1675808f684SSatish Balay warn() 1685808f684SSatish Balay warn("*"*80) 1695808f684SSatish Balay return False 1705808f684SSatish Balay # 1715808f684SSatish Balay try: 1725808f684SSatish Balay CYTHON_VERSION = Cython.__version__ 1735808f684SSatish Balay except AttributeError: 1745808f684SSatish Balay from Cython.Compiler.Version import version as CYTHON_VERSION 1755808f684SSatish Balay REQUIRED = VERSION 1765808f684SSatish Balay m = re.match(r"(\d+\.\d+(?:\.\d+)?).*", CYTHON_VERSION) 1775808f684SSatish Balay if m: 1785808f684SSatish Balay Version = StrictVersion 1795808f684SSatish Balay AVAILABLE = m.groups()[0] 1805808f684SSatish Balay else: 1815808f684SSatish Balay Version = LooseVersion 1825808f684SSatish Balay AVAILABLE = CYTHON_VERSION 1835808f684SSatish Balay if (REQUIRED is not None and 1845808f684SSatish Balay Version(AVAILABLE) < Version(REQUIRED)): 1855808f684SSatish Balay warn("*"*80) 1865808f684SSatish Balay warn() 1875808f684SSatish Balay warn(" You need to install Cython %s (you have version %s)" 1885808f684SSatish Balay % (REQUIRED, CYTHON_VERSION)) 1895808f684SSatish Balay warn(" Download and install Cython <http://www.cython.org>") 1905808f684SSatish Balay warn() 1915808f684SSatish Balay warn("*"*80) 1925808f684SSatish Balay return False 1935808f684SSatish Balay # 1945808f684SSatish Balay return True 1955808f684SSatish Balay 196a9c71d45SLisandro Dalcindef run_cython(source, target=None, 197a9c71d45SLisandro Dalcin depends=(), includes=(), 1985808f684SSatish Balay destdir_c=None, destdir_h=None, 1995808f684SSatish Balay wdir=None, force=False, VERSION=None): 2005808f684SSatish Balay from glob import glob 2015808f684SSatish Balay from distutils import log 2025808f684SSatish Balay from distutils import dep_util 2035808f684SSatish Balay from distutils.errors import DistutilsError 204a9c71d45SLisandro Dalcin if target is None: 2055808f684SSatish Balay target = os.path.splitext(source)[0]+'.c' 2065808f684SSatish Balay cwd = os.getcwd() 2075808f684SSatish Balay try: 2085808f684SSatish Balay if wdir: os.chdir(wdir) 2095808f684SSatish Balay alldeps = [source] 2105808f684SSatish Balay for dep in depends: 2115808f684SSatish Balay alldeps += glob(dep) 2125808f684SSatish Balay if not (force or dep_util.newer_group(alldeps, target)): 2135808f684SSatish Balay log.debug("skipping '%s' -> '%s' (up-to-date)", 2145808f684SSatish Balay source, target) 2155808f684SSatish Balay return 2165808f684SSatish Balay finally: 2175808f684SSatish Balay os.chdir(cwd) 2185808f684SSatish Balay if not chk_cython(VERSION): 2195808f684SSatish Balay raise DistutilsError("requires Cython>=%s" % VERSION) 2205808f684SSatish Balay log.info("cythonizing '%s' -> '%s'", source, target) 2215808f684SSatish Balay from conf.cythonize import cythonize 222a9c71d45SLisandro Dalcin err = cythonize(source, target, 2235808f684SSatish Balay includes=includes, 2245808f684SSatish Balay destdir_c=destdir_c, 2255808f684SSatish Balay destdir_h=destdir_h, 2265808f684SSatish Balay wdir=wdir) 2275808f684SSatish Balay if err: 2285808f684SSatish Balay raise DistutilsError( 2295808f684SSatish Balay "Cython failure: '%s' -> '%s'" % (source, target)) 2305808f684SSatish Balay 2315808f684SSatish Balaydef build_sources(cmd): 2325808f684SSatish Balay from os.path import exists, isdir, join 233ccd2fb5eSBarry Smith 2345808f684SSatish Balay # petsc4py.PETSc 2355808f684SSatish Balay source = 'petsc4py.PETSc.pyx' 236a9c71d45SLisandro Dalcin target = 'petsc4py.PETSc.c' 237ccd2fb5eSBarry Smith depends = ['include/*/*.pxd', 2385808f684SSatish Balay 'PETSc/*.pyx', 239ccd2fb5eSBarry Smith 'PETSc/*.pxi'] 2405808f684SSatish Balay includes = ['include'] 2415808f684SSatish Balay destdir_h = os.path.join('include', 'petsc4py') 242a9c71d45SLisandro Dalcin run_cython(source, target, 243a9c71d45SLisandro Dalcin depends=depends, includes=includes, 2445808f684SSatish Balay destdir_c=None, destdir_h=destdir_h, wdir='src', 2455808f684SSatish Balay force=cmd.force, VERSION=CYTHON) 2465808f684SSatish Balay # libpetsc4py 2475808f684SSatish Balay source = os.path.join('libpetsc4py', 'libpetsc4py.pyx') 2485808f684SSatish Balay depends = ['include/petsc4py/*.pxd', 2495808f684SSatish Balay 'libpetsc4py/*.pyx', 2505808f684SSatish Balay 'libpetsc4py/*.pxi'] 2515808f684SSatish Balay includes = ['include'] 252a9c71d45SLisandro Dalcin run_cython(source, 253a9c71d45SLisandro Dalcin depends=depends, includes=includes, 2545808f684SSatish Balay destdir_c=None, destdir_h=None, wdir='src', 2555808f684SSatish Balay force=cmd.force, VERSION=CYTHON) 2565808f684SSatish Balay 2575808f684SSatish Balaybuild_src.run = build_sources 2585808f684SSatish Balay 2595808f684SSatish Balaydef run_testsuite(cmd): 2605808f684SSatish Balay from distutils.errors import DistutilsError 2615808f684SSatish Balay sys.path.insert(0, 'test') 2625808f684SSatish Balay try: 2635808f684SSatish Balay from runtests import main 2645808f684SSatish Balay finally: 2655808f684SSatish Balay del sys.path[0] 2665808f684SSatish Balay if cmd.dry_run: 2675808f684SSatish Balay return 2685808f684SSatish Balay args = cmd.args[:] or [] 2695808f684SSatish Balay if cmd.verbose < 1: 2705808f684SSatish Balay args.insert(0,'-q') 2715808f684SSatish Balay if cmd.verbose > 1: 2725808f684SSatish Balay args.insert(0,'-v') 2735808f684SSatish Balay err = main(args) 2745808f684SSatish Balay if err: 2755808f684SSatish Balay raise DistutilsError("test") 2765808f684SSatish Balay 2775808f684SSatish Balaytest.run = run_testsuite 2785808f684SSatish Balay 2795808f684SSatish Balay# -------------------------------------------------------------------- 2805808f684SSatish Balay 2815808f684SSatish Balaydef main(): 2825808f684SSatish Balay run_setup() 2835808f684SSatish Balay 2845808f684SSatish Balayif __name__ == '__main__': 2855808f684SSatish Balay main() 2865808f684SSatish Balay 2875808f684SSatish Balay# -------------------------------------------------------------------- 288