xref: /petsc/setup.py (revision 1eeab4b41f87ea67e89b6cda108ada6a0f25ab99)
11b37a2a7SPierre Jolivet#!/usr/bin/env python3
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
1393b33a5aSLisandro Dalcin.. note::
1493b33a5aSLisandro Dalcin
155ee53db2SLisandro Dalcin   To install the ``PETSc`` and ``petsc4py`` packages
165ee53db2SLisandro Dalcin   (``mpi4py`` is optional but highly recommended) use::
1793b33a5aSLisandro Dalcin
185ee53db2SLisandro Dalcin     $ python -m pip install numpy mpi4py
195ee53db2SLisandro Dalcin     $ python -m pip install petsc petsc4py
2093b33a5aSLisandro Dalcin
21922ada92SLisandro Dalcin.. tip::
22922ada92SLisandro Dalcin
2393b33a5aSLisandro Dalcin  You can also install the in-development versions with::
24922ada92SLisandro Dalcin
25eaf87d4bSBarry Smith    $ python -m pip install Cython numpy mpi4py
269dddd249SSatish Balay    $ python -m pip install --no-deps https://gitlab.com/petsc/petsc/-/archive/main/petsc-main.tar.gz
27ca62002aSBarry Smith
28007ce00dSBarry Smith  Provide any ``PETSc`` ./configure options using the environmental variable ``PETSC_CONFIGURE_OPTIONS``.
29007ce00dSBarry Smith
30007ce00dSBarry Smith  Do not use the ``PETSc`` ``./configure`` options ``--with-cc``, ``--with-cxx``, ``--with-fc``, or ``--with-mpi-dir``.
315ee53db2SLisandro Dalcin  To set the MPI compilers use the environmental variables ``MPICC``, ``MPICXX``, ``MPIFORT``.
325ee53db2SLisandro Dalcin  If ``mpi4py`` is installed the compilers will be obtained from that installation and ``MPICC``, ``MPICXX``, ``MPIFORT`` will be ignored.
33007ce00dSBarry Smith
34e68ebbecSBarry Smith"""
35e68ebbecSBarry Smith
365ee53db2SLisandro Dalcinimport re
375ee53db2SLisandro Dalcinimport os
385ee53db2SLisandro Dalcinimport sys
395ee53db2SLisandro Dalcinimport shlex
405ee53db2SLisandro Dalcinimport shutil
4196fd8cd7SLisandro Dalcinfrom setuptools import setup
425ee53db2SLisandro Dalcinfrom wheel.bdist_wheel import bdist_wheel as _bdist_wheel
4396fd8cd7SLisandro Dalcinfrom setuptools.command.install import install as _install
4465a891e7SLisandro Dalcinfrom distutils import log
4512c1d45bSMatthew G Knepley
4665a891e7SLisandro Dalcininit_py = """\
47a32381aeSLisandro Dalcin# Author:  PETSc Team
48a597b971SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov
4965a891e7SLisandro Dalcin
5065a891e7SLisandro Dalcindef get_petsc_dir():
5165a891e7SLisandro Dalcin    import os
5265a891e7SLisandro Dalcin    return os.path.dirname(__file__)
5365a891e7SLisandro Dalcin
545ee53db2SLisandro Dalcin
55a32381aeSLisandro Dalcindef get_config():
56a32381aeSLisandro Dalcin    conf = {}
579fb7a39fSLisandro Dalcin    conf['PETSC_DIR'] = get_petsc_dir()
58a32381aeSLisandro Dalcin    return conf
5965a891e7SLisandro Dalcin"""
6065a891e7SLisandro Dalcin
615ee53db2SLisandro Dalcinmain_py = """\
625ee53db2SLisandro Dalcin# Author:  PETSc Team
635ee53db2SLisandro Dalcin# Contact: petsc-maint@mcs.anl.gov
645ee53db2SLisandro Dalcin
655ee53db2SLisandro Dalcinif __name__ == "__main__":
665ee53db2SLisandro Dalcin    import sys
675ee53db2SLisandro Dalcin    if "--prefix" in sys.argv:
685ee53db2SLisandro Dalcin        from . import get_petsc_dir
695ee53db2SLisandro Dalcin        print(get_petsc_dir())
705ee53db2SLisandro Dalcin        del get_petsc_dir
715ee53db2SLisandro Dalcin    del sys
725ee53db2SLisandro Dalcin"""
735ee53db2SLisandro Dalcin
7459e0f383SLisandro Dalcinmetadata = {
7559e0f383SLisandro Dalcin    'provides' : ['petsc'],
7696fd8cd7SLisandro Dalcin    'zip_safe' : False,
7759e0f383SLisandro Dalcin}
7859e0f383SLisandro Dalcin
7915075023SLisandro DalcinCONFIGURE_OPTIONS = []
8015075023SLisandro Dalcin
815ee53db2SLisandro Dalcin
8265a891e7SLisandro Dalcindef bootstrap():
83cb58ab5bSLisandro Dalcin    # Set PETSC_DIR and PETSC_ARCH
8465a891e7SLisandro Dalcin    PETSC_DIR  = os.path.abspath(os.getcwd())
855ee53db2SLisandro Dalcin    PETSC_ARCH = 'arch-python'
8665a891e7SLisandro Dalcin    os.environ['PETSC_DIR']  = PETSC_DIR
8765a891e7SLisandro Dalcin    os.environ['PETSC_ARCH'] = PETSC_ARCH
8865a891e7SLisandro Dalcin    sys.path.insert(0, os.path.join(PETSC_DIR, 'config'))
89af0996ceSBarry Smith    sys.path.insert(0, os.path.join(PETSC_DIR, 'lib','petsc','conf'))
905ee53db2SLisandro Dalcin
915ee53db2SLisandro Dalcin    # Generate package __init__.py and __main__.py files
929fb7a39fSLisandro Dalcin    pkgdir = os.path.join('config', 'pypi')
935ee53db2SLisandro Dalcin    os.makedirs(pkgdir, exist_ok=True)
945ee53db2SLisandro Dalcin    for pyfile, contents in (
955ee53db2SLisandro Dalcin        ('__init__.py', init_py),
965ee53db2SLisandro Dalcin        ('__main__.py', main_py),
975ee53db2SLisandro Dalcin    ):
985ee53db2SLisandro Dalcin        with open(os.path.join(pkgdir, pyfile), 'w') as fh:
995ee53db2SLisandro Dalcin            fh.write(contents)
1005ee53db2SLisandro Dalcin
10115075023SLisandro Dalcin    # Configure options
10215075023SLisandro Dalcin    options = os.environ.get('PETSC_CONFIGURE_OPTIONS', '')
1035ee53db2SLisandro Dalcin    CONFIGURE_OPTIONS.extend(shlex.split(options))
104007ce00dSBarry Smith    for i in CONFIGURE_OPTIONS:
1055f9afd5aSLawrence Mitchell        if i.startswith('--with-mpi-dir='):
1065ee53db2SLisandro Dalcin            raise RuntimeError("Do not use --with-mpi-dir, use the environmental variables MPICC, MPICXX, MPIFORT")
1075f9afd5aSLawrence Mitchell        if i.startswith('--with-cc='):
108007ce00dSBarry Smith            raise RuntimeError("Do not use --with-cc, use the environmental variable MPICC")
1095f9afd5aSLawrence Mitchell        if i.startswith('--with-cxx=') and i != "--with-cxx=0":
110007ce00dSBarry Smith            raise RuntimeError("Do not use --with-cxx, use the environmental variable MPICXX")
1115f9afd5aSLawrence Mitchell        if i.startswith('--with-fc=') and i != "--with-fc=0":
1125ee53db2SLisandro Dalcin            raise RuntimeError("Do not use --with-fc, use the environmental variable MPIFORT")
113007ce00dSBarry Smith
11415075023SLisandro Dalcin    if '--with-mpi=0' not in CONFIGURE_OPTIONS:
11559e0f383SLisandro Dalcin        # Simple-minded lookup for MPI and mpi4py
11659e0f383SLisandro Dalcin        mpi4py = mpicc = None
11759e0f383SLisandro Dalcin        try:
11859e0f383SLisandro Dalcin            import mpi4py
11959e0f383SLisandro Dalcin            conf = mpi4py.get_config()
12059e0f383SLisandro Dalcin            mpicc = conf.get('mpicc')
12159e0f383SLisandro Dalcin        except ImportError: # mpi4py is not installed
122922ada92SLisandro Dalcin            mpi4py = None
12315075023SLisandro Dalcin            mpicc = (os.environ.get('MPICC') or
1245ee53db2SLisandro Dalcin                     shutil.which('mpicc'))
1251b095333SLisandro Dalcin        except AttributeError: # mpi4py is too old
12659e0f383SLisandro Dalcin            pass
127922ada92SLisandro Dalcin        if not mpi4py and mpicc:
128922ada92SLisandro Dalcin            metadata['install_requires'] = ['mpi4py>=1.2.2']
12965a891e7SLisandro Dalcin
1305ee53db2SLisandro Dalcin
13196fd8cd7SLisandro Dalcindef config(prefix, dry_run=False):
13265a891e7SLisandro Dalcin    log.info('PETSc: configure')
13365a891e7SLisandro Dalcin    options = [
13496fd8cd7SLisandro Dalcin        '--prefix=' + prefix,
13565a891e7SLisandro Dalcin        'PETSC_ARCH='+os.environ['PETSC_ARCH'],
136cb58ab5bSLisandro Dalcin        '--with-shared-libraries=1',
13711035aebSLisandro Dalcin        '--with-debugging=0',
138922ada92SLisandro Dalcin        '--with-c2html=0', # not needed
13965a891e7SLisandro Dalcin        ]
14015075023SLisandro Dalcin    if '--with-fc=0' in CONFIGURE_OPTIONS:
14115075023SLisandro Dalcin        options.append('--with-sowing=0')
14215075023SLisandro Dalcin    if '--with-mpi=0' not in CONFIGURE_OPTIONS:
14359e0f383SLisandro Dalcin        try:
14459e0f383SLisandro Dalcin            import mpi4py
14559e0f383SLisandro Dalcin            conf = mpi4py.get_config()
14659e0f383SLisandro Dalcin            mpicc  = conf.get('mpicc')
147cb58ab5bSLisandro Dalcin            mpicxx = conf.get('mpicxx')
1485ee53db2SLisandro Dalcin            mpifort = conf.get('mpifort') or conf.get('mpif90')
14959e0f383SLisandro Dalcin        except (ImportError, AttributeError):
1505ee53db2SLisandro Dalcin            mpicc  = os.environ.get('MPICC') or shutil.which('mpicc')
1515ee53db2SLisandro Dalcin            mpicxx = os.environ.get('MPICXX') or shutil.which('mpicxx')
1525ee53db2SLisandro Dalcin            mpifort = os.environ.get('MPIFORT') or os.environ.get('MPIF90')
1535ee53db2SLisandro Dalcin            mpifort = mpifort or shutil.which('mpifort')
1545ee53db2SLisandro Dalcin            mpifort = mpifort or shutil.which('mpif90')
15559e0f383SLisandro Dalcin        if mpicc:
15659e0f383SLisandro Dalcin            options.append('--with-cc='+mpicc)
15715075023SLisandro Dalcin            if '--with-cxx=0' not in CONFIGURE_OPTIONS:
158cb58ab5bSLisandro Dalcin                if mpicxx:
159cb58ab5bSLisandro Dalcin                    options.append('--with-cxx='+mpicxx)
16093b33a5aSLisandro Dalcin                else:
16193b33a5aSLisandro Dalcin                    options.append('--with-cxx=0')
16215075023SLisandro Dalcin            if '--with-fc=0' not in CONFIGURE_OPTIONS:
1635ee53db2SLisandro Dalcin                if mpifort:
1645ee53db2SLisandro Dalcin                    options.append('--with-fc='+mpifort)
16559e0f383SLisandro Dalcin                else:
16693b33a5aSLisandro Dalcin                    options.append('--with-fc=0')
16793b33a5aSLisandro Dalcin                    options.append('--with-sowing=0')
16893b33a5aSLisandro Dalcin        else:
16959e0f383SLisandro Dalcin            options.append('--with-mpi=0')
17015075023SLisandro Dalcin    options.extend(CONFIGURE_OPTIONS)
17115075023SLisandro Dalcin    #
172cb58ab5bSLisandro Dalcin    log.info('configure options:')
173cb58ab5bSLisandro Dalcin    for opt in options:
174cb58ab5bSLisandro Dalcin        log.info(' '*4 + opt)
17559e0f383SLisandro Dalcin    # Run PETSc configure
1765ee53db2SLisandro Dalcin    if dry_run:
1775ee53db2SLisandro Dalcin        return
1780a0dac6aSLisandro Dalcin    use_config_py = False
17996fd8cd7SLisandro Dalcin    if use_config_py:
180e68ebbecSBarry Smith        import configure
18165a891e7SLisandro Dalcin        configure.petsc_configure(options)
182e68ebbecSBarry Smith        import logger
183e68ebbecSBarry Smith        logger.Logger.defaultLog = None
18496fd8cd7SLisandro Dalcin    else:
18584a6b807SJose E. Roman        python = sys.executable
1860a0dac6aSLisandro Dalcin        command = [python, './configure'] + options
18796fd8cd7SLisandro Dalcin        status = os.system(" ".join(command))
1885ee53db2SLisandro Dalcin        if status != 0:
1895ee53db2SLisandro Dalcin            raise RuntimeError(status)
1905ee53db2SLisandro Dalcin    # Fix PETSc configuration
191*1eeab4b4SLisandro Dalcin    using_build_backend = any(
192*1eeab4b4SLisandro Dalcin        os.environ.get(prefix + '_BUILD_BACKEND')
193*1eeab4b4SLisandro Dalcin        for prefix in ('_PYPROJECT_HOOKS', 'PEP517')
194*1eeab4b4SLisandro Dalcin    )
195*1eeab4b4SLisandro Dalcin    if using_build_backend:
1965ee53db2SLisandro Dalcin        pdir = os.environ['PETSC_DIR']
1975ee53db2SLisandro Dalcin        parch = os.environ['PETSC_ARCH']
1985ee53db2SLisandro Dalcin        include = os.path.join(pdir, parch, 'include')
1995ee53db2SLisandro Dalcin        for filename in (
2005ee53db2SLisandro Dalcin            'petscconf.h',
2015ee53db2SLisandro Dalcin            'petscconfiginfo.h',
2025ee53db2SLisandro Dalcin            'petscmachineinfo.h',
2035ee53db2SLisandro Dalcin        ):
2045ee53db2SLisandro Dalcin            filename = os.path.join(include, filename)
2055ee53db2SLisandro Dalcin            with open(filename, 'r') as old_fh:
2065ee53db2SLisandro Dalcin                contents = old_fh.read()
2075ee53db2SLisandro Dalcin            contents = contents.replace(prefix, '${PETSC_DIR}')
2085ee53db2SLisandro Dalcin            contents = re.sub(
2095ee53db2SLisandro Dalcin                r'^(#define PETSC_PYTHON_EXE) "(.*)"$',
2105ee53db2SLisandro Dalcin                r'\1 "python%d"' % sys.version_info[0],
2115ee53db2SLisandro Dalcin                contents, flags=re.MULTILINE,
2125ee53db2SLisandro Dalcin            )
2135ee53db2SLisandro Dalcin            with open(filename, 'w') as new_fh:
2145ee53db2SLisandro Dalcin                new_fh.write(contents)
2155ee53db2SLisandro Dalcin
21612c1d45bSMatthew G Knepley
21765a891e7SLisandro Dalcindef build(dry_run=False):
21865a891e7SLisandro Dalcin    log.info('PETSc: build')
219367c215cSLisandro Dalcin    # Run PETSc build
2205ee53db2SLisandro Dalcin    if dry_run:
2215ee53db2SLisandro Dalcin        return
222367c215cSLisandro Dalcin    use_builder_py = False
223367c215cSLisandro Dalcin    if use_builder_py:
224e68ebbecSBarry Smith        import builder
225e68ebbecSBarry Smith        builder.PETScMaker().run()
226105e34d4SBarry Smith        import logger
227105e34d4SBarry Smith        logger.Logger.defaultLog = None
228367c215cSLisandro Dalcin    else:
2295ee53db2SLisandro Dalcin        make = shutil.which('make')
23096fd8cd7SLisandro Dalcin        command = [make, 'all']
23196fd8cd7SLisandro Dalcin        status = os.system(" ".join(command))
2325ee53db2SLisandro Dalcin        if status != 0:
2335ee53db2SLisandro Dalcin            raise RuntimeError(status)
2345ee53db2SLisandro Dalcin
235e68ebbecSBarry Smith
2368c408988SSatish Balaydef install(dry_run=False):
23765a891e7SLisandro Dalcin    log.info('PETSc: install')
23859e0f383SLisandro Dalcin    # Run PETSc installer
2395ee53db2SLisandro Dalcin    if dry_run:
2405ee53db2SLisandro Dalcin        return
2410a0dac6aSLisandro Dalcin    use_install_py = False
242367c215cSLisandro Dalcin    if use_install_py:
243105e34d4SBarry Smith        import install
2448c408988SSatish Balay        install.Installer().run()
24565a891e7SLisandro Dalcin        import logger
24665a891e7SLisandro Dalcin        logger.Logger.defaultLog = None
247367c215cSLisandro Dalcin    else:
2485ee53db2SLisandro Dalcin        make = shutil.which('make')
2498c408988SSatish Balay        command = [make, 'install']
25096fd8cd7SLisandro Dalcin        status = os.system(" ".join(command))
2515ee53db2SLisandro Dalcin        if status != 0:
2525ee53db2SLisandro Dalcin            raise RuntimeError(status)
2535ee53db2SLisandro Dalcin
25499468c80SLisandro Dalcin
25596fd8cd7SLisandro Dalcinclass context(object):
25699468c80SLisandro Dalcin    def __init__(self):
25799468c80SLisandro Dalcin        self.sys_argv = sys.argv[:]
25899468c80SLisandro Dalcin        self.wdir = os.getcwd()
25999468c80SLisandro Dalcin    def enter(self):
26099468c80SLisandro Dalcin        del sys.argv[1:]
26199468c80SLisandro Dalcin        pdir = os.environ['PETSC_DIR']
26299468c80SLisandro Dalcin        os.chdir(pdir)
26399468c80SLisandro Dalcin        return self
26499468c80SLisandro Dalcin    def exit(self):
26599468c80SLisandro Dalcin        sys.argv[:] = self.sys_argv
26699468c80SLisandro Dalcin        os.chdir(self.wdir)
267105e34d4SBarry Smith
2685ee53db2SLisandro Dalcin
26965a891e7SLisandro Dalcinclass cmd_install(_install):
27065a891e7SLisandro Dalcin
27141716173SLisandro Dalcin    def initialize_options(self):
27241716173SLisandro Dalcin        _install.initialize_options(self)
27341716173SLisandro Dalcin
27489031a3cSLisandro Dalcin    def finalize_options(self):
27589031a3cSLisandro Dalcin        _install.finalize_options(self)
27689031a3cSLisandro Dalcin        self.install_lib = self.install_platlib
27789031a3cSLisandro Dalcin        self.install_libbase = self.install_lib
278f46a955bSLisandro Dalcin        self.old_and_unmanageable = True
27989031a3cSLisandro Dalcin
28065a891e7SLisandro Dalcin    def run(self):
28189031a3cSLisandro Dalcin        root_dir = os.path.abspath(self.install_lib)
2828c408988SSatish Balay        prefix = os.path.join(root_dir, 'petsc')
28399468c80SLisandro Dalcin        #
28499468c80SLisandro Dalcin        ctx = context().enter()
28565a891e7SLisandro Dalcin        try:
28696fd8cd7SLisandro Dalcin            config(prefix, self.dry_run)
28796fd8cd7SLisandro Dalcin            build(self.dry_run)
2888c408988SSatish Balay            install(self.dry_run)
28965a891e7SLisandro Dalcin        finally:
29099468c80SLisandro Dalcin            ctx.exit()
29196fd8cd7SLisandro Dalcin        #
29296fd8cd7SLisandro Dalcin        self.outputs = []
2938c408988SSatish Balay        for dirpath, _, filenames in os.walk(prefix):
29496fd8cd7SLisandro Dalcin            for fn in filenames:
29596fd8cd7SLisandro Dalcin                self.outputs.append(os.path.join(dirpath, fn))
29696fd8cd7SLisandro Dalcin        #
29796fd8cd7SLisandro Dalcin        _install.run(self)
29865a891e7SLisandro Dalcin
29996fd8cd7SLisandro Dalcin    def get_outputs(self):
30096fd8cd7SLisandro Dalcin        outputs = getattr(self, 'outputs', [])
30196fd8cd7SLisandro Dalcin        outputs += _install.get_outputs(self)
30296fd8cd7SLisandro Dalcin        return outputs
303a32381aeSLisandro Dalcin
3045ee53db2SLisandro Dalcin
3055ee53db2SLisandro Dalcinclass cmd_bdist_wheel(_bdist_wheel):
3065ee53db2SLisandro Dalcin
3075ee53db2SLisandro Dalcin    def finalize_options(self):
3085ee53db2SLisandro Dalcin        super().finalize_options()
3095ee53db2SLisandro Dalcin        self.root_is_pure = False
3105ee53db2SLisandro Dalcin        self.build_number = None
3115ee53db2SLisandro Dalcin
3125ee53db2SLisandro Dalcin    def get_tag(self):
3135ee53db2SLisandro Dalcin        plat_tag = super().get_tag()[-1]
3145ee53db2SLisandro Dalcin        return (self.python_tag, "none", plat_tag)
3155ee53db2SLisandro Dalcin
3165ee53db2SLisandro Dalcin
31765a891e7SLisandro Dalcindef version():
3187d04d9c9SLisandro Dalcin    version_re = {
3197d04d9c9SLisandro Dalcin        'major'  : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"),
3207d04d9c9SLisandro Dalcin        'minor'  : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"),
3217d04d9c9SLisandro Dalcin        'micro'  : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"),
32215261b6dSSatish Balay        'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+([-]*\d+)"),
3237d04d9c9SLisandro Dalcin        }
3247d04d9c9SLisandro Dalcin    petscversion_h = os.path.join('include','petscversion.h')
32596fd8cd7SLisandro Dalcin    data = open(petscversion_h, 'r').read()
3267d04d9c9SLisandro Dalcin    major = int(version_re['major'].search(data).groups()[0])
3277d04d9c9SLisandro Dalcin    minor = int(version_re['minor'].search(data).groups()[0])
3287d04d9c9SLisandro Dalcin    micro = int(version_re['micro'].search(data).groups()[0])
3297d04d9c9SLisandro Dalcin    release = int(version_re['release'].search(data).groups()[0])
330f46a955bSLisandro Dalcin    if release:
3310a0dac6aSLisandro Dalcin        v = "%d.%d.%d" % (major, minor, micro)
3327d04d9c9SLisandro Dalcin    else:
3330a0dac6aSLisandro Dalcin        v = "%d.%d.0.dev%d" % (major, minor+1, 0)
3347d04d9c9SLisandro Dalcin    return v
33559e0f383SLisandro Dalcin
3365ee53db2SLisandro Dalcin
33765a891e7SLisandro Dalcindef tarball():
33850f36069SLisandro Dalcin    VERSION = version()
3395ee53db2SLisandro Dalcin    if '.dev' in VERSION:
3405ee53db2SLisandro Dalcin        return None
341ca0d62ffSSatish Balay    return ('https://web.cels.anl.gov/projects/petsc/download/release-snapshots/'
342a8af48b3SSatish Balay            'petsc-%s.tar.gz#egg=petsc-%s' % (VERSION, VERSION))
34365a891e7SLisandro Dalcin
3445ee53db2SLisandro Dalcin
3455ee53db2SLisandro Dalcindescription = __doc__.split('\n')[1:-1]
3465ee53db2SLisandro Dalcindel description[1:3]
3475ee53db2SLisandro Dalcin
34865a891e7SLisandro Dalcinclassifiers = """
34996fd8cd7SLisandro DalcinDevelopment Status :: 5 - Production/Stable
35065a891e7SLisandro DalcinIntended Audience :: Developers
35165a891e7SLisandro DalcinIntended Audience :: Science/Research
35296fd8cd7SLisandro DalcinLicense :: OSI Approved :: BSD License
35396fd8cd7SLisandro DalcinOperating System :: POSIX
35465a891e7SLisandro DalcinProgramming Language :: C
35565a891e7SLisandro DalcinProgramming Language :: C++
35665a891e7SLisandro DalcinProgramming Language :: Fortran
35765a891e7SLisandro DalcinProgramming Language :: Python
35865a891e7SLisandro DalcinTopic :: Scientific/Engineering
35965a891e7SLisandro DalcinTopic :: Software Development :: Libraries
36065a891e7SLisandro Dalcin"""
36165a891e7SLisandro Dalcin
36265a891e7SLisandro Dalcinbootstrap()
3635ee53db2SLisandro Dalcinsetup(
3645ee53db2SLisandro Dalcin    name='petsc',
36565a891e7SLisandro Dalcin    version=version(),
36665a891e7SLisandro Dalcin    description=description.pop(0),
36765a891e7SLisandro Dalcin    long_description='\n'.join(description),
3685ee53db2SLisandro Dalcin    long_description_content_type='text/x-rst',
36965a891e7SLisandro Dalcin    classifiers=classifiers.split('\n')[1:-1],
37065a891e7SLisandro Dalcin    keywords = ['PETSc', 'MPI'],
37165a891e7SLisandro Dalcin    platforms=['POSIX'],
3725ee53db2SLisandro Dalcin    license='BSD-2-Clause',
37365a891e7SLisandro Dalcin
374a17b96a8SKyle Gerard Felker    url='https://petsc.org/',
37565a891e7SLisandro Dalcin    download_url=tarball(),
37665a891e7SLisandro Dalcin
37765a891e7SLisandro Dalcin    author='PETSc Team',
37899468c80SLisandro Dalcin    author_email='petsc-maint@mcs.anl.gov',
37965a891e7SLisandro Dalcin    maintainer='Lisandro Dalcin',
38065a891e7SLisandro Dalcin    maintainer_email='dalcinl@gmail.com',
38165a891e7SLisandro Dalcin
38265a891e7SLisandro Dalcin    packages=['petsc'],
3839fb7a39fSLisandro Dalcin    package_dir= {'petsc': 'config/pypi'},
3845ee53db2SLisandro Dalcin    cmdclass={
3855ee53db2SLisandro Dalcin        'install': cmd_install,
3865ee53db2SLisandro Dalcin        'bdist_wheel': cmd_bdist_wheel,
3875ee53db2SLisandro Dalcin    },
3885ee53db2SLisandro Dalcin    **metadata
3895ee53db2SLisandro Dalcin)
390