xref: /petsc/src/binding/petsc4py/setup.py (revision eaf87d4b69e480df6b4f698fb66af3a5b42719d8)
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__))
305808f684SSatish Balay
315808f684SSatish Balayfrom conf.metadata import metadata
325808f684SSatish Balay
335808f684SSatish Balaydef name():
345808f684SSatish Balay    return 'petsc4py'
355808f684SSatish Balay
365808f684SSatish Balaydef version():
375808f684SSatish Balay    with open(os.path.join(topdir, 'src', '__init__.py')) as f:
385808f684SSatish Balay        m = re.search(r"__version__\s*=\s*'(.*)'", f.read())
395808f684SSatish Balay        return m.groups()[0]
405808f684SSatish Balay
415808f684SSatish Balaydef description():
425808f684SSatish Balay    with open(os.path.join(topdir, 'DESCRIPTION.rst')) as f:
435808f684SSatish Balay        return f.read()
445808f684SSatish Balay
455808f684SSatish Balayname     = name()
465808f684SSatish Balayversion  = version()
475808f684SSatish Balay
48*eaf87d4bSBarry Smithurl      = 'https://gitlab.com/petsc/petsc'
495808f684SSatish Balaypypiroot = 'https://pypi.io/packages/source/%s/%s/' % (name[0], name)
505808f684SSatish Balaydownload = pypiroot + '%(name)s-%(version)s.tar.gz' % vars()
515808f684SSatish Balay
525808f684SSatish Balaydevstat  = ['Development Status :: 5 - Production/Stable']
535808f684SSatish Balaykeywords = ['PETSc', 'MPI']
545808f684SSatish Balay
555808f684SSatish Balaymetadata['name'] = name
565808f684SSatish Balaymetadata['version'] = version
575808f684SSatish Balaymetadata['description'] = __doc__.strip()
585808f684SSatish Balaymetadata['long_description'] = description()
595808f684SSatish Balaymetadata['keywords'] += keywords
605808f684SSatish Balaymetadata['classifiers'] += devstat
615808f684SSatish Balaymetadata['url'] = url
625808f684SSatish Balaymetadata['download_url'] = download
635808f684SSatish Balay
645808f684SSatish Balaymetadata['provides'] = ['petsc4py']
655808f684SSatish Balaymetadata['requires'] = ['numpy']
665808f684SSatish Balay
675808f684SSatish Balay# --------------------------------------------------------------------
685808f684SSatish Balay# Extension modules
695808f684SSatish Balay# --------------------------------------------------------------------
705808f684SSatish Balay
715808f684SSatish Balaydef get_ext_modules(Extension):
725808f684SSatish Balay    from os   import walk, path
735808f684SSatish Balay    from glob import glob
745808f684SSatish Balay    depends = []
755808f684SSatish Balay    for pth, dirs, files in walk('src'):
765808f684SSatish Balay        depends += glob(path.join(pth, '*.h'))
775808f684SSatish Balay        depends += glob(path.join(pth, '*.c'))
785808f684SSatish Balay    try:
795808f684SSatish Balay        import numpy
805808f684SSatish Balay        numpy_includes = [numpy.get_include()]
815808f684SSatish Balay    except ImportError:
825808f684SSatish Balay        numpy_includes = []
835808f684SSatish Balay    return [Extension('petsc4py.lib.PETSc',
845808f684SSatish Balay                      sources=['src/PETSc.c',
855808f684SSatish Balay                               'src/libpetsc4py.c',
865808f684SSatish Balay                               ],
875808f684SSatish Balay                      include_dirs=['src/include',
885808f684SSatish Balay                                    ] + numpy_includes,
895808f684SSatish Balay                      depends=depends)]
905808f684SSatish Balay
915808f684SSatish Balay# --------------------------------------------------------------------
925808f684SSatish Balay# Setup
935808f684SSatish Balay# --------------------------------------------------------------------
945808f684SSatish Balay
955808f684SSatish Balayfrom conf.petscconf import setup, Extension
965808f684SSatish Balayfrom conf.petscconf import config, build, build_src, build_ext, install
975808f684SSatish Balayfrom conf.petscconf import clean, test, sdist
985808f684SSatish Balay
995808f684SSatish BalayCYTHON = '0.22'
1005808f684SSatish Balay
1015808f684SSatish Balaydef run_setup():
1025808f684SSatish Balay    setup_args = metadata.copy()
1035808f684SSatish Balay    if setuptools:
1045808f684SSatish Balay        setup_args['zip_safe'] = False
1055808f684SSatish Balay        setup_args['install_requires'] = ['numpy']
1065808f684SSatish Balay        PETSC_DIR = os.environ.get('PETSC_DIR')
1075808f684SSatish Balay        if not (PETSC_DIR and os.path.isdir(PETSC_DIR)):
1085808f684SSatish Balay            vstr = setup_args['version'].split('.')[:2]
1095808f684SSatish Balay            x, y = int(vstr[0]), int(vstr[1])
1105808f684SSatish Balay            PETSC = ">=%s.%s,<%s.%s" % (x, y, x, y+1)
1115808f684SSatish Balay            setup_args['install_requires'] += ['petsc'+PETSC]
1125808f684SSatish Balay    if setuptools:
1135808f684SSatish Balay        src = os.path.join('src', 'petsc4py.PETSc.c')
1145808f684SSatish Balay        has_src = os.path.exists(os.path.join(topdir, src))
1155808f684SSatish Balay        has_git = os.path.isdir(os.path.join(topdir, '.git'))
1165808f684SSatish Balay        has_hg  = os.path.isdir(os.path.join(topdir, '.hg'))
1175808f684SSatish Balay        if not has_src or has_git or has_hg:
1185808f684SSatish Balay            setup_args['setup_requires'] = ['Cython>='+CYTHON]
1195808f684SSatish Balay    #
1205808f684SSatish Balay    setup(packages     = ['petsc4py',
1215808f684SSatish Balay                          'petsc4py.lib',],
1225808f684SSatish Balay          package_dir  = {'petsc4py'     : 'src',
1235808f684SSatish Balay                          'petsc4py.lib' : 'src/lib'},
1245808f684SSatish Balay          package_data = {'petsc4py'     : ['include/petsc4py/*.h',
1255808f684SSatish Balay                                            'include/petsc4py/*.i',
1265808f684SSatish Balay                                            'include/petsc4py/*.pxd',
1275808f684SSatish Balay                                            'include/petsc4py/*.pxi',
1285808f684SSatish Balay                                            'include/petsc4py/*.pyx',
1295808f684SSatish Balay                                            'PETSc.pxd',],
1305808f684SSatish Balay                          'petsc4py.lib' : ['petsc.cfg'],},
1315808f684SSatish Balay          ext_modules  = get_ext_modules(Extension),
1325808f684SSatish Balay          cmdclass     = {'config'     : config,
1335808f684SSatish Balay                          'build'      : build,
1345808f684SSatish Balay                          'build_src'  : build_src,
1355808f684SSatish Balay                          'build_ext'  : build_ext,
1365808f684SSatish Balay                          'install'    : install,
1375808f684SSatish Balay                          'clean'      : clean,
1385808f684SSatish Balay                          'test'       : test,
1395808f684SSatish Balay                          'sdist'      : sdist,
1405808f684SSatish Balay                          },
1415808f684SSatish Balay          **setup_args)
1425808f684SSatish Balay
1435808f684SSatish Balaydef chk_cython(VERSION):
1445808f684SSatish Balay    from distutils import log
1455808f684SSatish Balay    from distutils.version import LooseVersion
1465808f684SSatish Balay    from distutils.version import StrictVersion
1475808f684SSatish Balay    warn = lambda msg='': sys.stderr.write(msg+'\n')
1485808f684SSatish Balay    #
1495808f684SSatish Balay    try:
1505808f684SSatish Balay        import Cython
1515808f684SSatish Balay    except ImportError:
1525808f684SSatish Balay        warn("*"*80)
1535808f684SSatish Balay        warn()
1545808f684SSatish Balay        warn(" You need to generate C source files with Cython!!")
1555808f684SSatish Balay        warn(" Download and install Cython <http://www.cython.org>")
1565808f684SSatish Balay        warn()
1575808f684SSatish Balay        warn("*"*80)
1585808f684SSatish Balay        return False
1595808f684SSatish Balay    #
1605808f684SSatish Balay    try:
1615808f684SSatish Balay        CYTHON_VERSION = Cython.__version__
1625808f684SSatish Balay    except AttributeError:
1635808f684SSatish Balay        from Cython.Compiler.Version import version as CYTHON_VERSION
1645808f684SSatish Balay    REQUIRED = VERSION
1655808f684SSatish Balay    m = re.match(r"(\d+\.\d+(?:\.\d+)?).*", CYTHON_VERSION)
1665808f684SSatish Balay    if m:
1675808f684SSatish Balay        Version = StrictVersion
1685808f684SSatish Balay        AVAILABLE = m.groups()[0]
1695808f684SSatish Balay    else:
1705808f684SSatish Balay        Version = LooseVersion
1715808f684SSatish Balay        AVAILABLE = CYTHON_VERSION
1725808f684SSatish Balay    if (REQUIRED is not None and
1735808f684SSatish Balay        Version(AVAILABLE) < Version(REQUIRED)):
1745808f684SSatish Balay        warn("*"*80)
1755808f684SSatish Balay        warn()
1765808f684SSatish Balay        warn(" You need to install Cython %s (you have version %s)"
1775808f684SSatish Balay             % (REQUIRED, CYTHON_VERSION))
1785808f684SSatish Balay        warn(" Download and install Cython <http://www.cython.org>")
1795808f684SSatish Balay        warn()
1805808f684SSatish Balay        warn("*"*80)
1815808f684SSatish Balay        return False
1825808f684SSatish Balay    #
1835808f684SSatish Balay    return True
1845808f684SSatish Balay
1855808f684SSatish Balaydef run_cython(source, depends=(), includes=(),
1865808f684SSatish Balay               destdir_c=None, destdir_h=None,
1875808f684SSatish Balay               wdir=None, force=False, VERSION=None):
1885808f684SSatish Balay    from glob import glob
1895808f684SSatish Balay    from distutils import log
1905808f684SSatish Balay    from distutils import dep_util
1915808f684SSatish Balay    from distutils.errors import DistutilsError
1925808f684SSatish Balay    target = os.path.splitext(source)[0]+'.c'
1935808f684SSatish Balay    cwd = os.getcwd()
1945808f684SSatish Balay    try:
1955808f684SSatish Balay        if wdir: os.chdir(wdir)
1965808f684SSatish Balay        alldeps = [source]
1975808f684SSatish Balay        for dep in depends:
1985808f684SSatish Balay            alldeps += glob(dep)
1995808f684SSatish Balay        if not (force or dep_util.newer_group(alldeps, target)):
2005808f684SSatish Balay            log.debug("skipping '%s' -> '%s' (up-to-date)",
2015808f684SSatish Balay                      source, target)
2025808f684SSatish Balay            return
2035808f684SSatish Balay    finally:
2045808f684SSatish Balay        os.chdir(cwd)
2055808f684SSatish Balay    if not chk_cython(VERSION):
2065808f684SSatish Balay        raise DistutilsError("requires Cython>=%s" % VERSION)
2075808f684SSatish Balay    log.info("cythonizing '%s' -> '%s'", source, target)
2085808f684SSatish Balay    from conf.cythonize import cythonize
2095808f684SSatish Balay    err = cythonize(source,
2105808f684SSatish Balay                    includes=includes,
2115808f684SSatish Balay                    destdir_c=destdir_c,
2125808f684SSatish Balay                    destdir_h=destdir_h,
2135808f684SSatish Balay                    wdir=wdir)
2145808f684SSatish Balay    if err:
2155808f684SSatish Balay        raise DistutilsError(
2165808f684SSatish Balay            "Cython failure: '%s' -> '%s'" % (source, target))
2175808f684SSatish Balay
2185808f684SSatish Balaydef build_sources(cmd):
2195808f684SSatish Balay    from os.path import exists, isdir, join
2205808f684SSatish Balay    if (exists(join('src', 'petsc4py.PETSc.c')) and
2215808f684SSatish Balay        not (isdir('.hg') or isdir('.git')) and
2225808f684SSatish Balay        not cmd.force): return
2235808f684SSatish Balay    # petsc4py.PETSc
2245808f684SSatish Balay    source = 'petsc4py.PETSc.pyx'
2255808f684SSatish Balay    depends = ('include/*/*.pxd',
2265808f684SSatish Balay               'PETSc/*.pyx',
2275808f684SSatish Balay               'PETSc/*.pxi',)
2285808f684SSatish Balay    includes = ['include']
2295808f684SSatish Balay    destdir_h = os.path.join('include', 'petsc4py')
2305808f684SSatish Balay    run_cython(source, depends, includes,
2315808f684SSatish Balay               destdir_c=None, destdir_h=destdir_h, wdir='src',
2325808f684SSatish Balay               force=cmd.force, VERSION=CYTHON)
2335808f684SSatish Balay    # libpetsc4py
2345808f684SSatish Balay    source = os.path.join('libpetsc4py', 'libpetsc4py.pyx')
2355808f684SSatish Balay    depends = ['include/petsc4py/*.pxd',
2365808f684SSatish Balay               'libpetsc4py/*.pyx',
2375808f684SSatish Balay               'libpetsc4py/*.pxi']
2385808f684SSatish Balay    includes = ['include']
2395808f684SSatish Balay    run_cython(source, depends, includes,
2405808f684SSatish Balay               destdir_c=None, destdir_h=None, wdir='src',
2415808f684SSatish Balay               force=cmd.force, VERSION=CYTHON)
2425808f684SSatish Balay
2435808f684SSatish Balaybuild_src.run = build_sources
2445808f684SSatish Balay
2455808f684SSatish Balaydef run_testsuite(cmd):
2465808f684SSatish Balay    from distutils.errors import DistutilsError
2475808f684SSatish Balay    sys.path.insert(0, 'test')
2485808f684SSatish Balay    try:
2495808f684SSatish Balay        from runtests import main
2505808f684SSatish Balay    finally:
2515808f684SSatish Balay        del sys.path[0]
2525808f684SSatish Balay    if cmd.dry_run:
2535808f684SSatish Balay        return
2545808f684SSatish Balay    args = cmd.args[:] or []
2555808f684SSatish Balay    if cmd.verbose < 1:
2565808f684SSatish Balay        args.insert(0,'-q')
2575808f684SSatish Balay    if cmd.verbose > 1:
2585808f684SSatish Balay        args.insert(0,'-v')
2595808f684SSatish Balay    err = main(args)
2605808f684SSatish Balay    if err:
2615808f684SSatish Balay        raise DistutilsError("test")
2625808f684SSatish Balay
2635808f684SSatish Balaytest.run = run_testsuite
2645808f684SSatish Balay
2655808f684SSatish Balay# --------------------------------------------------------------------
2665808f684SSatish Balay
2675808f684SSatish Balaydef main():
2685808f684SSatish Balay    run_setup()
2695808f684SSatish Balay
2705808f684SSatish Balayif __name__ == '__main__':
2715808f684SSatish Balay    main()
2725808f684SSatish Balay
2735808f684SSatish Balay# --------------------------------------------------------------------
274