xref: /petsc/src/binding/petsc4py/setup.py (revision 8885bf165885162927f0f181feffa6a63f5c86e9)
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