xref: /petsc/setup.py (revision 7dd4b89e7493a54ce263f1cc517556d756b198c8)
1#!/usr/bin/env python
2
3"""
4PETSc for Python
5================
6
7Python bindings for PETSc libraries.
8"""
9
10
11## try:
12##     import setuptools
13## except ImportError:
14##     pass
15
16import sys
17sys.dont_write_bytecode = True
18
19# --------------------------------------------------------------------
20# Metadata
21# --------------------------------------------------------------------
22
23from conf.metadata import metadata
24
25def version():
26    import os, re
27    fh = open(os.path.join('src', '__init__.py'))
28    try: data = fh.read()
29    finally: fh.close()
30    m = re.search(r"__version__\s*=\s*'(.*)'", data)
31    return m.groups()[0]
32
33name     = 'petsc4py'
34version  = version()
35
36url      = 'http://%(name)s.googlecode.com/' % vars()
37download = url + 'files/%(name)s-%(version)s.tar.gz' % vars()
38
39descr    = __doc__.strip().split('\n'); del descr[1:3]
40devstat  = ['Development Status :: 3 - Alpha']
41keywords = ['PETSc', 'MPI']
42
43metadata['name'] = name
44metadata['version'] = version
45metadata['description'] = descr.pop(0)
46metadata['long_description'] = '\n'.join(descr)
47metadata['keywords'] += keywords
48metadata['classifiers'] += devstat
49metadata['url'] = url
50metadata['download_url'] = download
51
52metadata['provides'] = ['petsc4py']
53metadata['requires'] = ['numpy']
54
55# --------------------------------------------------------------------
56# Extension modules
57# --------------------------------------------------------------------
58
59def get_ext_modules(Extension):
60    from os   import walk, path
61    from glob import glob
62    depends = []
63    for pth, dirs, files in walk('src'):
64        depends += glob(path.join(pth, '*.h'))
65    for pth, dirs, files in walk(path.join('src', 'source')):
66        depends += glob(path.join(pth, '*.h'))
67        depends += glob(path.join(pth, '*.c'))
68    try:
69        import numpy
70        numpy_includes = [numpy.get_include()]
71    except ImportError:
72        numpy_includes = []
73    return [Extension('petsc4py.lib.PETSc',
74                      sources=['src/PETSc.c',
75                               'src/source/libpetsc4py.c',
76                               ],
77                      include_dirs=['src/include',
78                                    'src/source',
79                                    ] + numpy_includes,
80                      depends=depends)]
81
82# --------------------------------------------------------------------
83# Setup
84# --------------------------------------------------------------------
85
86from conf.petscconf import setup, Extension
87from conf.petscconf import config, build, sdist
88from conf.petscconf import build_src, build_ext
89
90def run_setup():
91    import sys, os
92    if (('distribute' in sys.modules) or
93        ('setuptools' in sys.modules)):
94        metadata['install_requires'] = ['numpy']
95        if not os.environ.get('PETSC_DIR'):
96            metadata['install_requires'].append('petsc')
97    if 'setuptools' in sys.modules:
98        metadata['zip_safe'] = False
99    setup(packages     = ['petsc4py',
100                          'petsc4py.lib',],
101          package_dir  = {'petsc4py'     : 'src',
102                          'petsc4py.lib' : 'src/lib'},
103          package_data = {'petsc4py'     : ['include/petsc4py/*.h',
104                                            'include/petsc4py/*.i',
105                                            'include/petsc4py/*.pxd',
106                                            'include/petsc4py/*.pxi',
107                                            'include/petsc4py/*.pyx',],
108                          'petsc4py.lib' : ['petsc.cfg'],},
109          ext_modules  = get_ext_modules(Extension),
110          cmdclass     = {'config'     : config,
111                          'build'      : build,
112                          'build_src'  : build_src,
113                          'build_ext'  : build_ext,
114                          'sdist'      : sdist,
115                          },
116          **metadata)
117
118def chk_cython(CYTHON_VERSION_REQUIRED):
119    import sys, os
120    from distutils.version import StrictVersion as Version
121    warn = lambda msg='': sys.stderr.write(msg+'\n')
122    #
123    try:
124        import Cython
125    except ImportError:
126        warn("*"*80)
127        warn()
128        warn(" You need to generate C source files with Cython!!")
129        warn(" Download and install Cython <http://www.cython.org>")
130        warn()
131        warn("*"*80)
132        return False
133    #
134    try:
135        CYTHON_VERSION = Cython.__version__
136    except AttributeError:
137        from Cython.Compiler.Version import version as CYTHON_VERSION
138    CYTHON_VERSION = CYTHON_VERSION.split('+', 1)[0]
139    for s in ('.alpha', 'alpha'):
140        CYTHON_VERSION = CYTHON_VERSION.replace(s, 'a')
141    for s in ('.beta',  'beta', '.rc', 'rc', '.c', 'c'):
142        CYTHON_VERSION = CYTHON_VERSION.replace(s, 'b')
143    if Version(CYTHON_VERSION) < Version(CYTHON_VERSION_REQUIRED):
144        warn("*"*80)
145        warn()
146        warn(" You need to install Cython %s (you have version %s)"
147             % (CYTHON_VERSION_REQUIRED, CYTHON_VERSION))
148        warn(" Download and install Cython <http://www.cython.org>")
149        warn()
150        warn("*"*80)
151        return False
152    #
153    return True
154
155def run_cython(source, target, includes=(),
156               depends=(), force=False,
157               CYTHON_VERSION_REQUIRED=None):
158    from distutils import log
159    from distutils import dep_util
160    from distutils.errors import DistutilsError
161    depends = [source] + list(depends)
162    if not (force or dep_util.newer_group(depends, target)):
163        log.debug("skipping '%s' -> '%s' (up-to-date)",
164                  source, target)
165        return
166    if (CYTHON_VERSION_REQUIRED and not
167        chk_cython(CYTHON_VERSION_REQUIRED)):
168        raise DistutilsError('requires Cython>=%s'
169                             % CYTHON_VERSION_REQUIRED)
170    log.info("cythonizing '%s' -> '%s'", source, target)
171    from conf.cythonize import run as cythonize
172    cythonize(source, includes=includes)
173
174def build_sources(cmd):
175    CYTHON_VERSION_REQUIRED = '0.13'
176    import os, glob
177    if not (os.path.isdir('.hg')  or
178            os.path.isdir('.git') or
179            cmd.force): return
180    source = os.path.join('src', 'petsc4py.PETSc.pyx')
181    target = os.path.splitext(source)[0]+".c"
182    depends = (glob.glob("src/include/*/*.pxd") +
183               glob.glob("src/*/*.pyx") +
184               glob.glob("src/*/*.pxi"))
185    includes =  []
186    run_cython(source, target, includes,
187               depends, cmd.force,
188               CYTHON_VERSION_REQUIRED)
189
190build_src.run = build_sources
191
192# --------------------------------------------------------------------
193
194def main():
195    run_setup()
196
197if __name__ == '__main__':
198    main()
199
200# --------------------------------------------------------------------
201