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): 738885bf16SLisandro Dalcin from os import walk 745808f684SSatish Balay from glob import glob 758885bf16SLisandro Dalcin from os.path import join 768885bf16SLisandro Dalcin glob_join = lambda *args: glob(join(*args)) 775808f684SSatish Balay depends = [] 785808f684SSatish Balay for pth, dirs, files in walk('src'): 798885bf16SLisandro Dalcin depends += glob_join(pth, '*.h') 808885bf16SLisandro Dalcin depends += glob_join(pth, '*.c') 818885bf16SLisandro Dalcin if 'PETSC_DIR' in os.environ: 828885bf16SLisandro Dalcin pd = os.environ['PETSC_DIR'] 838885bf16SLisandro Dalcin pa = os.environ.get('PETSC_ARCH', '') 848885bf16SLisandro Dalcin depends += glob_join(pd, 'include', '*.h') 858885bf16SLisandro Dalcin depends += glob_join(pd, 'include', 'petsc', 'private', '*.h') 868885bf16SLisandro Dalcin depends += glob_join(pd, pa, 'include', 'petscconf.h') 870f51ee0fSAlexei Colin numpy_include = os.environ.get('NUMPY_INCLUDE') 880f51ee0fSAlexei Colin if numpy_include is not None: 890f51ee0fSAlexei Colin numpy_includes = [numpy_include] 900f51ee0fSAlexei Colin else: 915808f684SSatish Balay try: 925808f684SSatish Balay import numpy 935808f684SSatish Balay numpy_includes = [numpy.get_include()] 945808f684SSatish Balay except ImportError: 955808f684SSatish Balay numpy_includes = [] 965808f684SSatish Balay return [Extension('petsc4py.lib.PETSc', 975808f684SSatish Balay sources=['src/PETSc.c', 985808f684SSatish Balay 'src/libpetsc4py.c', 995808f684SSatish Balay ], 1005808f684SSatish Balay include_dirs=['src/include', 1015808f684SSatish Balay ] + numpy_includes, 1025808f684SSatish Balay depends=depends)] 1035808f684SSatish Balay 1045808f684SSatish Balay# -------------------------------------------------------------------- 1055808f684SSatish Balay# Setup 1065808f684SSatish Balay# -------------------------------------------------------------------- 1075808f684SSatish Balay 1085808f684SSatish Balayfrom conf.petscconf import setup, Extension 1095808f684SSatish Balayfrom conf.petscconf import config, build, build_src, build_ext, install 1105808f684SSatish Balayfrom conf.petscconf import clean, test, sdist 1115808f684SSatish Balay 112a9c71d45SLisandro DalcinCYTHON = '0.24' 1135808f684SSatish Balay 114*f8c80548SLisandro Dalcindef get_release(): 115*f8c80548SLisandro Dalcin release = 1 116*f8c80548SLisandro Dalcin if topdir.endswith(os.path.join(os.path.sep, 'src', 'binding', name)): 117*f8c80548SLisandro Dalcin topname = name.replace('4py', '') 118*f8c80548SLisandro Dalcin rootdir = os.path.abspath(os.path.join(topdir, *[os.path.pardir]*3)) 119*f8c80548SLisandro Dalcin version_h = os.path.join(rootdir, 'include', '%sversion.h' % topname) 120*f8c80548SLisandro Dalcin release_macro = '%s_VERSION_RELEASE' % topname.upper() 121*f8c80548SLisandro Dalcin version_re = re.compile(r"#define\s+%s\s+([-]*\d+)" % release_macro) 122*f8c80548SLisandro Dalcin if os.path.exists(version_h) and os.path.isfile(version_h): 123*f8c80548SLisandro Dalcin with open(version_h, 'r') as f: 124*f8c80548SLisandro Dalcin release = int(version_re.search(f.read()).groups()[0]) 125*f8c80548SLisandro Dalcin return bool(release) 126*f8c80548SLisandro Dalcin 127*f8c80548SLisandro Dalcindef requires(pkgname, major, minor, release=True): 128*f8c80548SLisandro Dalcin minor = minor + int(not release) 129*f8c80548SLisandro Dalcin devel = '' if release else '.dev0' 130*f8c80548SLisandro Dalcin vmin = "%s.%s%s" % (major, minor, devel) 131*f8c80548SLisandro Dalcin vmax = "%s.%s" % (major, minor + 1) 132*f8c80548SLisandro Dalcin return "%s>=%s,<%s" % (pkgname, vmin, vmax) 133*f8c80548SLisandro Dalcin 1345808f684SSatish Balaydef run_setup(): 1355808f684SSatish Balay setup_args = metadata.copy() 136*f8c80548SLisandro Dalcin vstr = setup_args['version'].split('.')[:2] 137*f8c80548SLisandro Dalcin x, y = tuple(map(int, vstr)) 138*f8c80548SLisandro Dalcin release = get_release() 139*f8c80548SLisandro Dalcin if not release: 140*f8c80548SLisandro Dalcin setup_args['version'] = "%d.%d.0.dev0" %(x, y+1) 1415808f684SSatish Balay if setuptools: 1425808f684SSatish Balay setup_args['zip_safe'] = False 1435808f684SSatish Balay setup_args['install_requires'] = ['numpy'] 1445808f684SSatish Balay PETSC_DIR = os.environ.get('PETSC_DIR') 1455808f684SSatish Balay if not (PETSC_DIR and os.path.isdir(PETSC_DIR)): 146*f8c80548SLisandro Dalcin petsc = requires('petsc', x, y, release) 147*f8c80548SLisandro Dalcin setup_args['install_requires'] += [petsc] 1485808f684SSatish Balay if setuptools: 1495808f684SSatish Balay src = os.path.join('src', 'petsc4py.PETSc.c') 1505808f684SSatish Balay has_src = os.path.exists(os.path.join(topdir, src)) 1515808f684SSatish Balay has_git = os.path.isdir(os.path.join(topdir, '.git')) 1525808f684SSatish Balay has_hg = os.path.isdir(os.path.join(topdir, '.hg')) 1533594a89dSLisandro Dalcin suffix = os.path.join('src', 'binding', 'petsc4py') 1543594a89dSLisandro Dalcin in_petsc = topdir.endswith(os.path.sep + suffix) 1553594a89dSLisandro Dalcin if not has_src or has_git or has_hg or in_petsc: 1565808f684SSatish Balay setup_args['setup_requires'] = ['Cython>='+CYTHON] 1575808f684SSatish Balay # 1585808f684SSatish Balay setup(packages = ['petsc4py', 1595808f684SSatish Balay 'petsc4py.lib',], 1605808f684SSatish Balay package_dir = {'petsc4py' : 'src', 1615808f684SSatish Balay 'petsc4py.lib' : 'src/lib'}, 1625808f684SSatish Balay package_data = {'petsc4py' : ['include/petsc4py/*.h', 1635808f684SSatish Balay 'include/petsc4py/*.i', 1645808f684SSatish Balay 'include/petsc4py/*.pxd', 1655808f684SSatish Balay 'include/petsc4py/*.pxi', 1665808f684SSatish Balay 'include/petsc4py/*.pyx', 1675808f684SSatish Balay 'PETSc.pxd',], 1685808f684SSatish Balay 'petsc4py.lib' : ['petsc.cfg'],}, 1695808f684SSatish Balay ext_modules = get_ext_modules(Extension), 1705808f684SSatish Balay cmdclass = {'config' : config, 1715808f684SSatish Balay 'build' : build, 1725808f684SSatish Balay 'build_src' : build_src, 1735808f684SSatish Balay 'build_ext' : build_ext, 1745808f684SSatish Balay 'install' : install, 1755808f684SSatish Balay 'clean' : clean, 1765808f684SSatish Balay 'test' : test, 1775808f684SSatish Balay 'sdist' : sdist, 1785808f684SSatish Balay }, 1795808f684SSatish Balay **setup_args) 1805808f684SSatish Balay 1815808f684SSatish Balaydef chk_cython(VERSION): 1825808f684SSatish Balay from distutils import log 1835808f684SSatish Balay from distutils.version import LooseVersion 1845808f684SSatish Balay from distutils.version import StrictVersion 1855808f684SSatish Balay warn = lambda msg='': sys.stderr.write(msg+'\n') 1865808f684SSatish Balay # 1875808f684SSatish Balay try: 1885808f684SSatish Balay import Cython 1895808f684SSatish Balay except ImportError: 1905808f684SSatish Balay warn("*"*80) 1915808f684SSatish Balay warn() 1925808f684SSatish Balay warn(" You need to generate C source files with Cython!!") 1935808f684SSatish Balay warn(" Download and install Cython <http://www.cython.org>") 1945808f684SSatish Balay warn() 1955808f684SSatish Balay warn("*"*80) 1965808f684SSatish Balay return False 1975808f684SSatish Balay # 1985808f684SSatish Balay try: 1995808f684SSatish Balay CYTHON_VERSION = Cython.__version__ 2005808f684SSatish Balay except AttributeError: 2015808f684SSatish Balay from Cython.Compiler.Version import version as CYTHON_VERSION 2025808f684SSatish Balay REQUIRED = VERSION 2035808f684SSatish Balay m = re.match(r"(\d+\.\d+(?:\.\d+)?).*", CYTHON_VERSION) 2045808f684SSatish Balay if m: 2055808f684SSatish Balay Version = StrictVersion 2065808f684SSatish Balay AVAILABLE = m.groups()[0] 2075808f684SSatish Balay else: 2085808f684SSatish Balay Version = LooseVersion 2095808f684SSatish Balay AVAILABLE = CYTHON_VERSION 2105808f684SSatish Balay if (REQUIRED is not None and 2115808f684SSatish Balay Version(AVAILABLE) < Version(REQUIRED)): 2125808f684SSatish Balay warn("*"*80) 2135808f684SSatish Balay warn() 2145808f684SSatish Balay warn(" You need to install Cython %s (you have version %s)" 2155808f684SSatish Balay % (REQUIRED, CYTHON_VERSION)) 2165808f684SSatish Balay warn(" Download and install Cython <http://www.cython.org>") 2175808f684SSatish Balay warn() 2185808f684SSatish Balay warn("*"*80) 2195808f684SSatish Balay return False 2205808f684SSatish Balay # 2215808f684SSatish Balay return True 2225808f684SSatish Balay 223a9c71d45SLisandro Dalcindef run_cython(source, target=None, 224a9c71d45SLisandro Dalcin depends=(), includes=(), 2255808f684SSatish Balay destdir_c=None, destdir_h=None, 2265808f684SSatish Balay wdir=None, force=False, VERSION=None): 2275808f684SSatish Balay from glob import glob 2285808f684SSatish Balay from distutils import log 2295808f684SSatish Balay from distutils import dep_util 2305808f684SSatish Balay from distutils.errors import DistutilsError 231a9c71d45SLisandro Dalcin if target is None: 2325808f684SSatish Balay target = os.path.splitext(source)[0]+'.c' 2335808f684SSatish Balay cwd = os.getcwd() 2345808f684SSatish Balay try: 2355808f684SSatish Balay if wdir: os.chdir(wdir) 2365808f684SSatish Balay alldeps = [source] 2375808f684SSatish Balay for dep in depends: 2385808f684SSatish Balay alldeps += glob(dep) 2395808f684SSatish Balay if not (force or dep_util.newer_group(alldeps, target)): 2405808f684SSatish Balay log.debug("skipping '%s' -> '%s' (up-to-date)", 2415808f684SSatish Balay source, target) 2425808f684SSatish Balay return 2435808f684SSatish Balay finally: 2445808f684SSatish Balay os.chdir(cwd) 2455808f684SSatish Balay if not chk_cython(VERSION): 2465808f684SSatish Balay raise DistutilsError("requires Cython>=%s" % VERSION) 2475808f684SSatish Balay log.info("cythonizing '%s' -> '%s'", source, target) 2485808f684SSatish Balay from conf.cythonize import cythonize 249a9c71d45SLisandro Dalcin err = cythonize(source, target, 2505808f684SSatish Balay includes=includes, 2515808f684SSatish Balay destdir_c=destdir_c, 2525808f684SSatish Balay destdir_h=destdir_h, 2535808f684SSatish Balay wdir=wdir) 2545808f684SSatish Balay if err: 2555808f684SSatish Balay raise DistutilsError( 2565808f684SSatish Balay "Cython failure: '%s' -> '%s'" % (source, target)) 2575808f684SSatish Balay 2585808f684SSatish Balaydef build_sources(cmd): 2595808f684SSatish Balay from os.path import exists, isdir, join 260ccd2fb5eSBarry Smith 2615808f684SSatish Balay # petsc4py.PETSc 2625808f684SSatish Balay source = 'petsc4py.PETSc.pyx' 263a9c71d45SLisandro Dalcin target = 'petsc4py.PETSc.c' 264ccd2fb5eSBarry Smith depends = ['include/*/*.pxd', 2655808f684SSatish Balay 'PETSc/*.pyx', 266ccd2fb5eSBarry Smith 'PETSc/*.pxi'] 2675808f684SSatish Balay includes = ['include'] 2685808f684SSatish Balay destdir_h = os.path.join('include', 'petsc4py') 269a9c71d45SLisandro Dalcin run_cython(source, target, 270a9c71d45SLisandro Dalcin depends=depends, includes=includes, 2715808f684SSatish Balay destdir_c=None, destdir_h=destdir_h, wdir='src', 2725808f684SSatish Balay force=cmd.force, VERSION=CYTHON) 2735808f684SSatish Balay # libpetsc4py 2745808f684SSatish Balay source = os.path.join('libpetsc4py', 'libpetsc4py.pyx') 2755808f684SSatish Balay depends = ['include/petsc4py/*.pxd', 2765808f684SSatish Balay 'libpetsc4py/*.pyx', 2775808f684SSatish Balay 'libpetsc4py/*.pxi'] 2785808f684SSatish Balay includes = ['include'] 279a9c71d45SLisandro Dalcin run_cython(source, 280a9c71d45SLisandro Dalcin depends=depends, includes=includes, 2815808f684SSatish Balay destdir_c=None, destdir_h=None, wdir='src', 2825808f684SSatish Balay force=cmd.force, VERSION=CYTHON) 2835808f684SSatish Balay 2845808f684SSatish Balaybuild_src.run = build_sources 2855808f684SSatish Balay 2865808f684SSatish Balaydef run_testsuite(cmd): 2875808f684SSatish Balay from distutils.errors import DistutilsError 2885808f684SSatish Balay sys.path.insert(0, 'test') 2895808f684SSatish Balay try: 2905808f684SSatish Balay from runtests import main 2915808f684SSatish Balay finally: 2925808f684SSatish Balay del sys.path[0] 2935808f684SSatish Balay if cmd.dry_run: 2945808f684SSatish Balay return 2955808f684SSatish Balay args = cmd.args[:] or [] 2965808f684SSatish Balay if cmd.verbose < 1: 2975808f684SSatish Balay args.insert(0,'-q') 2985808f684SSatish Balay if cmd.verbose > 1: 2995808f684SSatish Balay args.insert(0,'-v') 3005808f684SSatish Balay err = main(args) 3015808f684SSatish Balay if err: 3025808f684SSatish Balay raise DistutilsError("test") 3035808f684SSatish Balay 3045808f684SSatish Balaytest.run = run_testsuite 3055808f684SSatish Balay 3065808f684SSatish Balay# -------------------------------------------------------------------- 3075808f684SSatish Balay 3085808f684SSatish Balaydef main(): 3095808f684SSatish Balay run_setup() 3105808f684SSatish Balay 3115808f684SSatish Balayif __name__ == '__main__': 3125808f684SSatish Balay main() 3135808f684SSatish Balay 3145808f684SSatish Balay# -------------------------------------------------------------------- 315