xref: /petsc/setup.py (revision 7d562c6ec7361ff613392673c05ff6f628f5bcb3)
1e68ebbecSBarry Smith#!/usr/bin/env python
2e68ebbecSBarry Smith
3e68ebbecSBarry Smith"""
465a891e7SLisandro DalcinPETSc: Portable, Extensible Toolkit for Scientific Computation
565a891e7SLisandro Dalcin==============================================================
665a891e7SLisandro Dalcin
765a891e7SLisandro DalcinThe Portable, Extensible Toolkit for Scientific Computation (PETSc),
865a891e7SLisandro Dalcinis a suite of data structures and routines for the scalable (parallel)
965a891e7SLisandro Dalcinsolution of scientific applications modeled by partial differential
1065a891e7SLisandro Dalcinequations. It employs the Message Passing Interface (MPI) standard for
1165a891e7SLisandro Dalcinall message-passing communication.
12922ada92SLisandro Dalcin
13922ada92SLisandro Dalcin.. tip::
14922ada92SLisandro Dalcin
15922ada92SLisandro Dalcin  You can also install `petsc-dev`_ with::
16922ada92SLisandro Dalcin
17922ada92SLisandro Dalcin    $ pip install petsc==dev
18922ada92SLisandro Dalcin
19922ada92SLisandro Dalcin  .. _petsc-dev: http://petsc.cs.iit.edu/petsc/
20922ada92SLisandro Dalcin                 petsc-dev/archive/tip.tar.gz#egg=petsc-dev
21e68ebbecSBarry Smith"""
22e68ebbecSBarry Smith
2365a891e7SLisandro Dalcinimport sys, os
2465a891e7SLisandro Dalcinfrom distutils.core import setup
25cb58ab5bSLisandro Dalcinfrom distutils.util import get_platform, split_quoted
26b88f8b63SLisandro Dalcinfrom distutils.spawn import find_executable
2765a891e7SLisandro Dalcinfrom distutils.command.build import build as _build
2865a891e7SLisandro Dalcinif 'setuptools' in sys.modules:
2965a891e7SLisandro Dalcin    from setuptools.command.install import install as _install
3065a891e7SLisandro Dalcinelse:
3165a891e7SLisandro Dalcin    from distutils.command.install import install as _install
32a32381aeSLisandro Dalcinfrom distutils.command.sdist import sdist as _sdist
3365a891e7SLisandro Dalcinfrom distutils import log
3412c1d45bSMatthew G Knepley
3565a891e7SLisandro Dalcininit_py = """\
36a32381aeSLisandro Dalcin# Author:  PETSc Team
37a597b971SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov
3865a891e7SLisandro Dalcin
3965a891e7SLisandro Dalcindef get_petsc_dir():
4065a891e7SLisandro Dalcin    import os
4165a891e7SLisandro Dalcin    return os.path.dirname(__file__)
4265a891e7SLisandro Dalcin
43a32381aeSLisandro Dalcindef get_config():
44a32381aeSLisandro Dalcin    conf = {}
459fb7a39fSLisandro Dalcin    conf['PETSC_DIR'] = get_petsc_dir()
46a32381aeSLisandro Dalcin    return conf
4765a891e7SLisandro Dalcin"""
4865a891e7SLisandro Dalcin
4959e0f383SLisandro Dalcinmetadata = {
5059e0f383SLisandro Dalcin    'provides' : ['petsc'],
5159e0f383SLisandro Dalcin    'requires' : [],
5259e0f383SLisandro Dalcin}
5359e0f383SLisandro Dalcin
5465a891e7SLisandro Dalcindef bootstrap():
55cb58ab5bSLisandro Dalcin    # Set PETSC_DIR and PETSC_ARCH
5665a891e7SLisandro Dalcin    PETSC_DIR  = os.path.abspath(os.getcwd())
5765a891e7SLisandro Dalcin    PETSC_ARCH = get_platform() + '-python'
5865a891e7SLisandro Dalcin    os.environ['PETSC_DIR']  = PETSC_DIR
5965a891e7SLisandro Dalcin    os.environ['PETSC_ARCH'] = PETSC_ARCH
6065a891e7SLisandro Dalcin    sys.path.insert(0, os.path.join(PETSC_DIR, 'config'))
6159e0f383SLisandro Dalcin    # Generate package __init__.py file
629fb7a39fSLisandro Dalcin    from distutils.dir_util import mkpath
639fb7a39fSLisandro Dalcin    pkgdir = os.path.join('config', 'pypi')
640ddf2052SLisandro Dalcin    if not os.path.exists(pkgdir): mkpath(pkgdir)
659fb7a39fSLisandro Dalcin    pkgfile = os.path.join(pkgdir, '__init__.py')
66922ada92SLisandro Dalcin    fh = open(pkgfile, 'wt')
67922ada92SLisandro Dalcin    fh.write(init_py)
68922ada92SLisandro Dalcin    fh.close()
6959e0f383SLisandro Dalcin    # Simple-minded lookup for MPI and mpi4py
7059e0f383SLisandro Dalcin    mpi4py = mpicc = None
7159e0f383SLisandro Dalcin    try:
7259e0f383SLisandro Dalcin        import mpi4py
7359e0f383SLisandro Dalcin        conf = mpi4py.get_config()
7459e0f383SLisandro Dalcin        mpicc = conf.get('mpicc')
7559e0f383SLisandro Dalcin    except ImportError: # mpi4py is not installed
76922ada92SLisandro Dalcin        mpi4py = None
7759e0f383SLisandro Dalcin        mpicc = os.environ.get('MPICC') or find_executable('mpicc')
781b095333SLisandro Dalcin    except AttributeError: # mpi4py is too old
7959e0f383SLisandro Dalcin        pass
80922ada92SLisandro Dalcin    if ('setuptools' in sys.modules):
81be96eb59SLisandro Dalcin        metadata['zip_safe'] = False
82922ada92SLisandro Dalcin        if not mpi4py and mpicc:
83922ada92SLisandro Dalcin            metadata['install_requires']= ['mpi4py>=1.2.2']
8465a891e7SLisandro Dalcin
8565a891e7SLisandro Dalcindef config(dry_run=False):
8665a891e7SLisandro Dalcin    log.info('PETSc: configure')
8765a891e7SLisandro Dalcin    options = [
8865a891e7SLisandro Dalcin        'PETSC_ARCH='+os.environ['PETSC_ARCH'],
89cb58ab5bSLisandro Dalcin        '--with-shared-libraries=1',
9011035aebSLisandro Dalcin        '--with-debugging=0',
91922ada92SLisandro Dalcin        '--with-c2html=0', # not needed
92922ada92SLisandro Dalcin        #'--with-sowing=0',
93922ada92SLisandro Dalcin        #'--with-cmake=0',
9465a891e7SLisandro Dalcin        ]
9559e0f383SLisandro Dalcin    # MPI
9659e0f383SLisandro Dalcin    try:
9759e0f383SLisandro Dalcin        import mpi4py
9859e0f383SLisandro Dalcin        conf = mpi4py.get_config()
9959e0f383SLisandro Dalcin        mpicc  = conf.get('mpicc')
100cb58ab5bSLisandro Dalcin        mpicxx = conf.get('mpicxx')
101cb58ab5bSLisandro Dalcin        mpif90 = conf.get('mpif90')
10259e0f383SLisandro Dalcin    except (ImportError, AttributeError):
10359e0f383SLisandro Dalcin        mpicc  = os.environ.get('MPICC')  or find_executable('mpicc')
104cb58ab5bSLisandro Dalcin        mpicxx = os.environ.get('MPICXX') or find_executable('mpicxx')
105cb58ab5bSLisandro Dalcin        mpif90 = os.environ.get('MPIF90') or find_executable('mpif90')
10659e0f383SLisandro Dalcin    if mpicc:
10759e0f383SLisandro Dalcin        options.append('--with-cc='+mpicc)
108cb58ab5bSLisandro Dalcin        if mpicxx:
109cb58ab5bSLisandro Dalcin            options.append('--with-cxx='+mpicxx)
110cb58ab5bSLisandro Dalcin        if mpif90:
111cb58ab5bSLisandro Dalcin            options.append('--with-fc='+mpif90)
11259e0f383SLisandro Dalcin    else:
11359e0f383SLisandro Dalcin        options.append('--with-mpi=0')
114cb58ab5bSLisandro Dalcin    # Extra configure options
115cb58ab5bSLisandro Dalcin    config_opts = os.environ.get('PETSC_CONFIGURE_OPTIONS', '')
116cb58ab5bSLisandro Dalcin    config_opts = split_quoted(config_opts)
117cb58ab5bSLisandro Dalcin    options.extend(config_opts)
118cb58ab5bSLisandro Dalcin    log.info('configure options:')
119cb58ab5bSLisandro Dalcin    for opt in options:
120cb58ab5bSLisandro Dalcin        log.info(' '*4 + opt)
12159e0f383SLisandro Dalcin    # Run PETSc configure
122cb58ab5bSLisandro Dalcin    if dry_run: return
123e68ebbecSBarry Smith    import configure
12465a891e7SLisandro Dalcin    configure.petsc_configure(options)
125e68ebbecSBarry Smith    import logger
126e68ebbecSBarry Smith    logger.Logger.defaultLog = None
12712c1d45bSMatthew G Knepley
12865a891e7SLisandro Dalcindef build(dry_run=False):
12965a891e7SLisandro Dalcin    log.info('PETSc: build')
13059e0f383SLisandro Dalcin    # Run PETSc builder
131cb58ab5bSLisandro Dalcin    if dry_run: return
132e68ebbecSBarry Smith    import builder
133e68ebbecSBarry Smith    builder.PETScMaker().run()
134105e34d4SBarry Smith    import logger
135105e34d4SBarry Smith    logger.Logger.defaultLog = None
136e68ebbecSBarry Smith
13765a891e7SLisandro Dalcindef install(dest_dir, prefix=None, dry_run=False):
13865a891e7SLisandro Dalcin    log.info('PETSc: install')
13965a891e7SLisandro Dalcin    if prefix is None:
14065a891e7SLisandro Dalcin        prefix = dest_dir
14165a891e7SLisandro Dalcin    options = [
14265a891e7SLisandro Dalcin        '--destDir=' + dest_dir,
1434dee622bSLisandro Dalcin        '--prefix='  + prefix,
14465a891e7SLisandro Dalcin        ]
145cb58ab5bSLisandro Dalcin    log.info('install options:')
146cb58ab5bSLisandro Dalcin    for opt in options:
147cb58ab5bSLisandro Dalcin        log.info(' '*4 + opt)
14859e0f383SLisandro Dalcin    # Run PETSc installer
149cb58ab5bSLisandro Dalcin    if dry_run: return
150105e34d4SBarry Smith    import install
15165a891e7SLisandro Dalcin    install.Installer(options).run()
15265a891e7SLisandro Dalcin    import logger
15365a891e7SLisandro Dalcin    logger.Logger.defaultLog = None
15499468c80SLisandro Dalcin
15599468c80SLisandro Dalcinclass context:
15699468c80SLisandro Dalcin    def __init__(self):
15799468c80SLisandro Dalcin        self.sys_argv = sys.argv[:]
15899468c80SLisandro Dalcin        self.wdir = os.getcwd()
15999468c80SLisandro Dalcin    def enter(self):
16099468c80SLisandro Dalcin        del sys.argv[1:]
16199468c80SLisandro Dalcin        pdir = os.environ['PETSC_DIR']
16299468c80SLisandro Dalcin        os.chdir(pdir)
16399468c80SLisandro Dalcin        return self
16499468c80SLisandro Dalcin    def exit(self):
16599468c80SLisandro Dalcin        sys.argv[:] = self.sys_argv
16699468c80SLisandro Dalcin        os.chdir(self.wdir)
167105e34d4SBarry Smith
16865a891e7SLisandro Dalcinclass cmd_build(_build):
16965a891e7SLisandro Dalcin
170a597b971SLisandro Dalcin    def initialize_options(self):
171a597b971SLisandro Dalcin        _build.initialize_options(self)
172a597b971SLisandro Dalcin        PETSC_ARCH = os.environ.get('PETSC_ARCH', '')
173a597b971SLisandro Dalcin        self.build_base = os.path.join(PETSC_ARCH, 'build-python')
174a597b971SLisandro Dalcin
17565a891e7SLisandro Dalcin    def run(self):
17665a891e7SLisandro Dalcin        _build.run(self)
17799468c80SLisandro Dalcin        ctx = context().enter()
17865a891e7SLisandro Dalcin        try:
17965a891e7SLisandro Dalcin            config(self.dry_run)
18065a891e7SLisandro Dalcin            build(self.dry_run)
18165a891e7SLisandro Dalcin        finally:
18299468c80SLisandro Dalcin            ctx.exit()
18365a891e7SLisandro Dalcin
18465a891e7SLisandro Dalcinclass cmd_install(_install):
18565a891e7SLisandro Dalcin
18641716173SLisandro Dalcin    def initialize_options(self):
18741716173SLisandro Dalcin        _install.initialize_options(self)
18841716173SLisandro Dalcin        self.optimize = 1
18941716173SLisandro Dalcin
19065a891e7SLisandro Dalcin    def run(self):
19165a891e7SLisandro Dalcin        root_dir = self.install_platlib
19265a891e7SLisandro Dalcin        dest_dir = os.path.join(root_dir, 'petsc')
19365a891e7SLisandro Dalcin        bdist_base = self.get_finalized_command('bdist').bdist_base
19465a891e7SLisandro Dalcin        if dest_dir.startswith(bdist_base):
19565a891e7SLisandro Dalcin            prefix = dest_dir[len(bdist_base)+1:]
19665a891e7SLisandro Dalcin            prefix = prefix[prefix.index(os.path.sep):]
19765a891e7SLisandro Dalcin        else:
19865a891e7SLisandro Dalcin            prefix = dest_dir
19965a891e7SLisandro Dalcin        dest_dir = os.path.abspath(dest_dir)
20065a891e7SLisandro Dalcin        prefix   = os.path.abspath(prefix)
20199468c80SLisandro Dalcin        #
20299468c80SLisandro Dalcin        _install.run(self)
20399468c80SLisandro Dalcin        ctx = context().enter()
20465a891e7SLisandro Dalcin        try:
20565a891e7SLisandro Dalcin            install(dest_dir, prefix, self.dry_run)
20665a891e7SLisandro Dalcin        finally:
20799468c80SLisandro Dalcin            ctx.exit()
20865a891e7SLisandro Dalcin
209a32381aeSLisandro Dalcinclass cmd_sdist(_sdist):
210a32381aeSLisandro Dalcin
211a32381aeSLisandro Dalcin    def initialize_options(self):
212a32381aeSLisandro Dalcin        _sdist.initialize_options(self)
213a32381aeSLisandro Dalcin        self.force_manifest = 1
21499468c80SLisandro Dalcin        self.template = os.path.join('config', 'manifest.in')
215a32381aeSLisandro Dalcin
21665a891e7SLisandro Dalcindef version():
2177d04d9c9SLisandro Dalcin    import re
2187d04d9c9SLisandro Dalcin    version_re = {
2197d04d9c9SLisandro Dalcin        'major'  : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"),
2207d04d9c9SLisandro Dalcin        'minor'  : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"),
2217d04d9c9SLisandro Dalcin        'micro'  : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"),
2227d04d9c9SLisandro Dalcin        'patch'  : re.compile(r"#define\s+PETSC_VERSION_PATCH\s+(\d+)"),
2237d04d9c9SLisandro Dalcin        'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+(\d+)"),
2247d04d9c9SLisandro Dalcin        }
2257d04d9c9SLisandro Dalcin    petscversion_h = os.path.join('include','petscversion.h')
2267d04d9c9SLisandro Dalcin    data = open(petscversion_h, 'rt').read()
2277d04d9c9SLisandro Dalcin    major = int(version_re['major'].search(data).groups()[0])
2287d04d9c9SLisandro Dalcin    minor = int(version_re['minor'].search(data).groups()[0])
2297d04d9c9SLisandro Dalcin    micro = int(version_re['micro'].search(data).groups()[0])
2307d04d9c9SLisandro Dalcin    patch = int(version_re['patch'].search(data).groups()[0])
2317d04d9c9SLisandro Dalcin    release = int(version_re['release'].search(data).groups()[0])
2327d04d9c9SLisandro Dalcin    if release:
2337d04d9c9SLisandro Dalcin        v = "%d.%d" % (major, minor)
2347d04d9c9SLisandro Dalcin        if micro > 0:
2357d04d9c9SLisandro Dalcin            v += ".%d" % micro
2367d04d9c9SLisandro Dalcin        if patch > 0:
237bd6472b3SLisandro Dalcin            v += ".%d" % patch
2387d04d9c9SLisandro Dalcin    else:
23961a717f9SLisandro Dalcin        v = "%d.%d.dev%d" % (major, minor+1, 0)
2407d04d9c9SLisandro Dalcin    return v
24159e0f383SLisandro Dalcin
24265a891e7SLisandro Dalcindef tarball():
24350f36069SLisandro Dalcin    VERSION = version()
24450f36069SLisandro Dalcin    if '.dev' in VERSION:
245a32381aeSLisandro Dalcin        return None
246*7d562c6eSLisandro Dalcin    bits = VERSION.split('.')
247*7d562c6eSLisandro Dalcin    if len(bits) == 2: bits.append('0')
248*7d562c6eSLisandro Dalcin    VERSION = '.'.join(bits[:-1]) + '-p' + bits[-1]
24950f36069SLisandro Dalcin    return ('http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/'
25050f36069SLisandro Dalcin            'petsc-lite-%s.tar.gz' % VERSION)
25165a891e7SLisandro Dalcin
25265a891e7SLisandro Dalcindescription = __doc__.split('\n')[1:-1]; del description[1:3]
25365a891e7SLisandro Dalcinclassifiers = """
25465a891e7SLisandro DalcinLicense :: Public Domain
25565a891e7SLisandro DalcinOperating System :: POSIX
25665a891e7SLisandro DalcinIntended Audience :: Developers
25765a891e7SLisandro DalcinIntended Audience :: Science/Research
25865a891e7SLisandro DalcinProgramming Language :: C
25965a891e7SLisandro DalcinProgramming Language :: C++
26065a891e7SLisandro DalcinProgramming Language :: Fortran
26165a891e7SLisandro DalcinProgramming Language :: Python
26265a891e7SLisandro DalcinTopic :: Scientific/Engineering
26365a891e7SLisandro DalcinTopic :: Software Development :: Libraries
26465a891e7SLisandro Dalcin"""
26565a891e7SLisandro Dalcin
26665a891e7SLisandro Dalcinbootstrap()
26765a891e7SLisandro Dalcinsetup(name='petsc',
26865a891e7SLisandro Dalcin      version=version(),
26965a891e7SLisandro Dalcin      description=description.pop(0),
27065a891e7SLisandro Dalcin      long_description='\n'.join(description),
27165a891e7SLisandro Dalcin      classifiers= classifiers.split('\n')[1:-1],
27265a891e7SLisandro Dalcin      keywords = ['PETSc', 'MPI'],
27365a891e7SLisandro Dalcin      platforms=['POSIX'],
27465a891e7SLisandro Dalcin      license='PETSc',
27565a891e7SLisandro Dalcin
27665a891e7SLisandro Dalcin      url='http://www.mcs.anl.gov/petsc/',
27765a891e7SLisandro Dalcin      download_url=tarball(),
27865a891e7SLisandro Dalcin
27965a891e7SLisandro Dalcin      author='PETSc Team',
28099468c80SLisandro Dalcin      author_email='petsc-maint@mcs.anl.gov',
28165a891e7SLisandro Dalcin      maintainer='Lisandro Dalcin',
28265a891e7SLisandro Dalcin      maintainer_email='dalcinl@gmail.com',
28365a891e7SLisandro Dalcin
28465a891e7SLisandro Dalcin      packages = ['petsc'],
2859fb7a39fSLisandro Dalcin      package_dir = {'petsc': 'config/pypi'},
28665a891e7SLisandro Dalcin      cmdclass={
28765a891e7SLisandro Dalcin        'build': cmd_build,
28865a891e7SLisandro Dalcin        'install': cmd_install,
289a32381aeSLisandro Dalcin        'sdist': cmd_sdist,
29065a891e7SLisandro Dalcin        },
29159e0f383SLisandro Dalcin      **metadata)
292