xref: /petsc/setup.py (revision 41716173ee99fa02c13b817637c7f37a2e516e2b)
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.
12e68ebbecSBarry Smith"""
13e68ebbecSBarry Smith
1465a891e7SLisandro Dalcinimport sys, os
1565a891e7SLisandro Dalcinfrom distutils.core import setup
1665a891e7SLisandro Dalcinfrom distutils.util import get_platform
17b88f8b63SLisandro Dalcinfrom distutils.spawn import find_executable
1865a891e7SLisandro Dalcinfrom distutils.command.build import build as _build
1965a891e7SLisandro Dalcinif 'setuptools' in sys.modules:
2065a891e7SLisandro Dalcin    from setuptools.command.install import install as _install
2165a891e7SLisandro Dalcinelse:
2265a891e7SLisandro Dalcin    from distutils.command.install import install as _install
23a32381aeSLisandro Dalcinfrom distutils.command.sdist import sdist as _sdist
2465a891e7SLisandro Dalcinfrom distutils import log
2512c1d45bSMatthew G Knepley
2665a891e7SLisandro Dalcininit_py = """\
27a32381aeSLisandro Dalcin# Author:  PETSc Team
28a597b971SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov
2965a891e7SLisandro Dalcin
3065a891e7SLisandro Dalcindef get_petsc_dir():
3165a891e7SLisandro Dalcin    import os
3265a891e7SLisandro Dalcin    return os.path.dirname(__file__)
3365a891e7SLisandro Dalcin
34a32381aeSLisandro Dalcindef get_config():
35a32381aeSLisandro Dalcin    conf = {}
369fb7a39fSLisandro Dalcin    conf['PETSC_DIR'] = get_petsc_dir()
37a32381aeSLisandro Dalcin    return conf
3865a891e7SLisandro Dalcin"""
3965a891e7SLisandro Dalcin
4059e0f383SLisandro Dalcinmetadata = {
4159e0f383SLisandro Dalcin    'provides' : ['petsc'],
4259e0f383SLisandro Dalcin    'requires' : [],
4359e0f383SLisandro Dalcin}
4459e0f383SLisandro Dalcin
4565a891e7SLisandro Dalcindef bootstrap():
4659e0f383SLisandro Dalcin    # Set PETSC_DIR and PETSC_ARCH,
4765a891e7SLisandro Dalcin    PETSC_DIR  = os.path.abspath(os.getcwd())
4865a891e7SLisandro Dalcin    PETSC_ARCH = get_platform() + '-python'
4965a891e7SLisandro Dalcin    os.environ['PETSC_DIR']  = PETSC_DIR
5065a891e7SLisandro Dalcin    os.environ['PETSC_ARCH'] = PETSC_ARCH
5165a891e7SLisandro Dalcin    sys.path.insert(0, os.path.join(PETSC_DIR, 'config'))
5259e0f383SLisandro Dalcin    # Generate package __init__.py file
539fb7a39fSLisandro Dalcin    from distutils.dir_util import mkpath
549fb7a39fSLisandro Dalcin    pkgdir = os.path.join('config', 'pypi')
559fb7a39fSLisandro Dalcin    pkgfile = os.path.join(pkgdir, '__init__.py')
569fb7a39fSLisandro Dalcin    if not os.path.exists(pkgdir):
579fb7a39fSLisandro Dalcin        mkpath(pkgdir)
589fb7a39fSLisandro Dalcin    if not os.path.exists(pkgfile):
5965a891e7SLisandro Dalcin        open(pkgfile, 'wt').write(init_py)
6059e0f383SLisandro Dalcin    # Simple-minded lookup for MPI and mpi4py
6159e0f383SLisandro Dalcin    mpi4py = mpicc = None
6259e0f383SLisandro Dalcin    try:
6359e0f383SLisandro Dalcin        import mpi4py
6459e0f383SLisandro Dalcin        conf = mpi4py.get_config()
6559e0f383SLisandro Dalcin        mpicc = conf.get('mpicc')
6659e0f383SLisandro Dalcin    except ImportError: # mpi4py is not installed
6759e0f383SLisandro Dalcin        mpicc = os.environ.get('MPICC') or find_executable('mpicc')
681b095333SLisandro Dalcin    except AttributeError: # mpi4py is too old
6959e0f383SLisandro Dalcin        pass
7059e0f383SLisandro Dalcin    if not mpi4py and mpicc:
711b095333SLisandro Dalcin        if (('distribute' in sys.modules) or
721b095333SLisandro Dalcin            ('setuptools' in sys.modules)):
731b095333SLisandro Dalcin            metadata['install_requires']= ['mpi4py>=1.2.2']
74be96eb59SLisandro Dalcin    if 'setuptools' in sys.modules:
75be96eb59SLisandro Dalcin        metadata['zip_safe'] = False
7665a891e7SLisandro Dalcin
7765a891e7SLisandro Dalcindef config(dry_run=False):
7865a891e7SLisandro Dalcin    log.info('PETSc: configure')
7965a891e7SLisandro Dalcin    if dry_run: return
8065a891e7SLisandro Dalcin    options = [
8165a891e7SLisandro Dalcin        'PETSC_ARCH='+os.environ['PETSC_ARCH'],
8265a891e7SLisandro Dalcin        '--with-shared-libraries',
8359e0f383SLisandro Dalcin        '--with-cmake=0', # not needed
8465a891e7SLisandro Dalcin        ]
8559e0f383SLisandro Dalcin    # MPI
8659e0f383SLisandro Dalcin    try:
8759e0f383SLisandro Dalcin        import mpi4py
8859e0f383SLisandro Dalcin        conf = mpi4py.get_config()
8959e0f383SLisandro Dalcin        mpicc = conf.get('mpicc')
9059e0f383SLisandro Dalcin    except (ImportError, AttributeError):
9159e0f383SLisandro Dalcin        mpicc = os.environ.get('MPICC') or find_executable('mpicc')
9259e0f383SLisandro Dalcin    if mpicc:
9359e0f383SLisandro Dalcin        options.append('--with-cc='+mpicc)
9459e0f383SLisandro Dalcin    else:
9559e0f383SLisandro Dalcin        options.append('--with-mpi=0')
9699468c80SLisandro Dalcin    options.append('--with-cxx=0') # XXX mpicxx?
9799468c80SLisandro Dalcin    options.append('--with-fc=0')  # XXX mpif90?
9859e0f383SLisandro Dalcin    # Run PETSc configure
99e68ebbecSBarry Smith    import configure
10065a891e7SLisandro Dalcin    configure.petsc_configure(options)
101e68ebbecSBarry Smith    import logger
102e68ebbecSBarry Smith    logger.Logger.defaultLog = None
10312c1d45bSMatthew G Knepley
10465a891e7SLisandro Dalcindef build(dry_run=False):
10565a891e7SLisandro Dalcin    log.info('PETSc: build')
10665a891e7SLisandro Dalcin    if dry_run: return
10759e0f383SLisandro Dalcin    # Run PETSc builder
108e68ebbecSBarry Smith    import builder
109e68ebbecSBarry Smith    builder.PETScMaker().run()
110105e34d4SBarry Smith    import logger
111105e34d4SBarry Smith    logger.Logger.defaultLog = None
112e68ebbecSBarry Smith
11365a891e7SLisandro Dalcindef install(dest_dir, prefix=None, dry_run=False):
11465a891e7SLisandro Dalcin    log.info('PETSc: install')
11565a891e7SLisandro Dalcin    if dry_run: return
11665a891e7SLisandro Dalcin    if prefix is None:
11765a891e7SLisandro Dalcin        prefix = dest_dir
11865a891e7SLisandro Dalcin    options = [
11965a891e7SLisandro Dalcin        '--destDir=' + dest_dir,
1204dee622bSLisandro Dalcin        '--prefix='  + prefix,
12165a891e7SLisandro Dalcin        ]
12259e0f383SLisandro Dalcin    # Run PETSc installer
123105e34d4SBarry Smith    import install
12465a891e7SLisandro Dalcin    install.Installer(options).run()
12565a891e7SLisandro Dalcin    import logger
12665a891e7SLisandro Dalcin    logger.Logger.defaultLog = None
12799468c80SLisandro Dalcin
12899468c80SLisandro Dalcinclass context:
12999468c80SLisandro Dalcin    def __init__(self):
13099468c80SLisandro Dalcin        self.sys_argv = sys.argv[:]
13199468c80SLisandro Dalcin        self.wdir = os.getcwd()
13299468c80SLisandro Dalcin    def enter(self):
13399468c80SLisandro Dalcin        del sys.argv[1:]
13499468c80SLisandro Dalcin        pdir = os.environ['PETSC_DIR']
13599468c80SLisandro Dalcin        os.chdir(pdir)
13699468c80SLisandro Dalcin        return self
13799468c80SLisandro Dalcin    def exit(self):
13899468c80SLisandro Dalcin        sys.argv[:] = self.sys_argv
13999468c80SLisandro Dalcin        os.chdir(self.wdir)
140105e34d4SBarry Smith
14165a891e7SLisandro Dalcinclass cmd_build(_build):
14265a891e7SLisandro Dalcin
143a597b971SLisandro Dalcin    def initialize_options(self):
144a597b971SLisandro Dalcin        _build.initialize_options(self)
145a597b971SLisandro Dalcin        PETSC_ARCH = os.environ.get('PETSC_ARCH', '')
146a597b971SLisandro Dalcin        self.build_base = os.path.join(PETSC_ARCH, 'build-python')
147a597b971SLisandro Dalcin
14865a891e7SLisandro Dalcin    def run(self):
14965a891e7SLisandro Dalcin        _build.run(self)
15099468c80SLisandro Dalcin        ctx = context().enter()
15165a891e7SLisandro Dalcin        try:
15265a891e7SLisandro Dalcin            config(self.dry_run)
15365a891e7SLisandro Dalcin            build(self.dry_run)
15465a891e7SLisandro Dalcin        finally:
15599468c80SLisandro Dalcin            ctx.exit()
15665a891e7SLisandro Dalcin
15765a891e7SLisandro Dalcinclass cmd_install(_install):
15865a891e7SLisandro Dalcin
159*41716173SLisandro Dalcin    def initialize_options(self):
160*41716173SLisandro Dalcin        _install.initialize_options(self)
161*41716173SLisandro Dalcin        self.optimize = 1
162*41716173SLisandro Dalcin
16365a891e7SLisandro Dalcin    def run(self):
16465a891e7SLisandro Dalcin        root_dir = self.install_platlib
16565a891e7SLisandro Dalcin        dest_dir = os.path.join(root_dir, 'petsc')
16665a891e7SLisandro Dalcin        bdist_base = self.get_finalized_command('bdist').bdist_base
16765a891e7SLisandro Dalcin        if dest_dir.startswith(bdist_base):
16865a891e7SLisandro Dalcin            prefix = dest_dir[len(bdist_base)+1:]
16965a891e7SLisandro Dalcin            prefix = prefix[prefix.index(os.path.sep):]
17065a891e7SLisandro Dalcin        else:
17165a891e7SLisandro Dalcin            prefix = dest_dir
17265a891e7SLisandro Dalcin        dest_dir = os.path.abspath(dest_dir)
17365a891e7SLisandro Dalcin        prefix   = os.path.abspath(prefix)
17499468c80SLisandro Dalcin        #
17599468c80SLisandro Dalcin        _install.run(self)
17699468c80SLisandro Dalcin        ctx = context().enter()
17765a891e7SLisandro Dalcin        try:
17865a891e7SLisandro Dalcin            install(dest_dir, prefix, self.dry_run)
17965a891e7SLisandro Dalcin        finally:
18099468c80SLisandro Dalcin            ctx.exit()
18165a891e7SLisandro Dalcin
182a32381aeSLisandro Dalcinclass cmd_sdist(_sdist):
183a32381aeSLisandro Dalcin
184a32381aeSLisandro Dalcin    def initialize_options(self):
185a32381aeSLisandro Dalcin        _sdist.initialize_options(self)
186a32381aeSLisandro Dalcin        self.force_manifest = 1
18799468c80SLisandro Dalcin        self.template = os.path.join('config', 'manifest.in')
188a32381aeSLisandro Dalcin
18965a891e7SLisandro Dalcindef version():
1907d04d9c9SLisandro Dalcin    import re
1917d04d9c9SLisandro Dalcin    version_re = {
1927d04d9c9SLisandro Dalcin        'major'  : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"),
1937d04d9c9SLisandro Dalcin        'minor'  : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"),
1947d04d9c9SLisandro Dalcin        'micro'  : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"),
1957d04d9c9SLisandro Dalcin        'patch'  : re.compile(r"#define\s+PETSC_VERSION_PATCH\s+(\d+)"),
1967d04d9c9SLisandro Dalcin        'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+(\d+)"),
1977d04d9c9SLisandro Dalcin        }
1987d04d9c9SLisandro Dalcin    petscversion_h = os.path.join('include','petscversion.h')
1997d04d9c9SLisandro Dalcin    data = open(petscversion_h, 'rt').read()
2007d04d9c9SLisandro Dalcin    major = int(version_re['major'].search(data).groups()[0])
2017d04d9c9SLisandro Dalcin    minor = int(version_re['minor'].search(data).groups()[0])
2027d04d9c9SLisandro Dalcin    micro = int(version_re['micro'].search(data).groups()[0])
2037d04d9c9SLisandro Dalcin    patch = int(version_re['patch'].search(data).groups()[0])
2047d04d9c9SLisandro Dalcin    release = int(version_re['release'].search(data).groups()[0])
2057d04d9c9SLisandro Dalcin    if release:
2067d04d9c9SLisandro Dalcin        v = "%d.%d" % (major, minor)
2077d04d9c9SLisandro Dalcin        if micro > 0:
2087d04d9c9SLisandro Dalcin            v += ".%d" % micro
2097d04d9c9SLisandro Dalcin        if patch > 0:
21061a717f9SLisandro Dalcin            v += ".post%d" % patch
2117d04d9c9SLisandro Dalcin    else:
21261a717f9SLisandro Dalcin        v = "%d.%d.dev%d" % (major, minor+1, 0)
2137d04d9c9SLisandro Dalcin    return v
21459e0f383SLisandro Dalcin
21565a891e7SLisandro Dalcindef tarball():
21650f36069SLisandro Dalcin    VERSION = version()
21750f36069SLisandro Dalcin    if '.dev' in VERSION:
218a32381aeSLisandro Dalcin        return None
21950f36069SLisandro Dalcin    if '.post' not in VERSION:
22050f36069SLisandro Dalcin        VERSION = VERSION + '.post0'
22150f36069SLisandro Dalcin    VERSION = VERSION.replace('.post', '-p')
22250f36069SLisandro Dalcin    return ('http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/'
22350f36069SLisandro Dalcin            'petsc-lite-%s.tar.gz' % VERSION)
22465a891e7SLisandro Dalcin
22565a891e7SLisandro Dalcindescription = __doc__.split('\n')[1:-1]; del description[1:3]
22665a891e7SLisandro Dalcinclassifiers = """
22765a891e7SLisandro DalcinLicense :: Public Domain
22865a891e7SLisandro DalcinOperating System :: POSIX
22965a891e7SLisandro DalcinIntended Audience :: Developers
23065a891e7SLisandro DalcinIntended Audience :: Science/Research
23165a891e7SLisandro DalcinProgramming Language :: C
23265a891e7SLisandro DalcinProgramming Language :: C++
23365a891e7SLisandro DalcinProgramming Language :: Fortran
23465a891e7SLisandro DalcinProgramming Language :: Python
23565a891e7SLisandro DalcinTopic :: Scientific/Engineering
23665a891e7SLisandro DalcinTopic :: Software Development :: Libraries
23765a891e7SLisandro Dalcin"""
23865a891e7SLisandro Dalcin
23965a891e7SLisandro Dalcinbootstrap()
24065a891e7SLisandro Dalcinsetup(name='petsc',
24165a891e7SLisandro Dalcin      version=version(),
24265a891e7SLisandro Dalcin      description=description.pop(0),
24365a891e7SLisandro Dalcin      long_description='\n'.join(description),
24465a891e7SLisandro Dalcin      classifiers= classifiers.split('\n')[1:-1],
24565a891e7SLisandro Dalcin      keywords = ['PETSc', 'MPI'],
24665a891e7SLisandro Dalcin      platforms=['POSIX'],
24765a891e7SLisandro Dalcin      license='PETSc',
24865a891e7SLisandro Dalcin
24965a891e7SLisandro Dalcin      url='http://www.mcs.anl.gov/petsc/',
25065a891e7SLisandro Dalcin      download_url=tarball(),
25165a891e7SLisandro Dalcin
25265a891e7SLisandro Dalcin      author='PETSc Team',
25399468c80SLisandro Dalcin      author_email='petsc-maint@mcs.anl.gov',
25465a891e7SLisandro Dalcin      maintainer='Lisandro Dalcin',
25565a891e7SLisandro Dalcin      maintainer_email='dalcinl@gmail.com',
25665a891e7SLisandro Dalcin
25765a891e7SLisandro Dalcin      packages = ['petsc'],
2589fb7a39fSLisandro Dalcin      package_dir = {'petsc': 'config/pypi'},
25965a891e7SLisandro Dalcin      cmdclass={
26065a891e7SLisandro Dalcin        'build': cmd_build,
26165a891e7SLisandro Dalcin        'install': cmd_install,
262a32381aeSLisandro Dalcin        'sdist': cmd_sdist,
26365a891e7SLisandro Dalcin        },
26459e0f383SLisandro Dalcin      **metadata)
265