11b37a2a7SPierre Jolivet#!/usr/bin/env python3 25808f684SSatish Balay# Author: Lisandro Dalcin 35808f684SSatish Balay# Contact: dalcinl@gmail.com 45808f684SSatish Balay 55808f684SSatish Balayimport re 6fb83dddaSLisandro Dalcinimport os 7fb83dddaSLisandro Dalcinimport sys 85808f684SSatish Balay 95808f684SSatish Balaytry: 105808f684SSatish Balay import setuptools 115808f684SSatish Balayexcept ImportError: 125808f684SSatish Balay setuptools = None 135808f684SSatish Balay 14f46a955bSLisandro Dalcintopdir = os.path.abspath(os.path.dirname(__file__)) 15f46a955bSLisandro Dalcinsys.path.insert(0, os.path.join(topdir, 'conf')) 16f46a955bSLisandro Dalcin 175808f684SSatish Balaypyver = sys.version_info[:2] 181e83877aSSatish Balayif pyver < (2, 6) or (3, 0) <= pyver < (3, 2): 196f336411SStefano Zampini raise RuntimeError('Python version 2.6, 2.7 or >= 3.2 required') 201e83877aSSatish Balayif pyver == (2, 6) or pyver == (3, 2): 216f336411SStefano Zampini sys.stderr.write('WARNING: Python %d.%d is not supported.\n' % pyver) 221e83877aSSatish Balay 23f46a955bSLisandro DalcinPNAME = 'PETSc' 24f46a955bSLisandro DalcinEMAIL = 'petsc-maint@mcs.anl.gov' 25f46a955bSLisandro DalcinPLIST = [PNAME] 26fb83dddaSLisandro Dalcin 275808f684SSatish Balay# -------------------------------------------------------------------- 285808f684SSatish Balay# Metadata 295808f684SSatish Balay# -------------------------------------------------------------------- 305808f684SSatish Balay 316f336411SStefano Zampini 32f46a955bSLisandro Dalcindef F(string): 33f46a955bSLisandro Dalcin return string.format( 34f46a955bSLisandro Dalcin Name=PNAME, 35f46a955bSLisandro Dalcin name=PNAME.lower(), 36f46a955bSLisandro Dalcin pyname=PNAME.lower() + '4py', 37f46a955bSLisandro Dalcin ) 385808f684SSatish Balay 396f336411SStefano Zampini 40f46a955bSLisandro Dalcindef get_name(): 41f46a955bSLisandro Dalcin return F('{pyname}') 425808f684SSatish Balay 436f336411SStefano Zampini 44f46a955bSLisandro Dalcindef get_version(): 45f46a955bSLisandro Dalcin try: 46f46a955bSLisandro Dalcin return get_version.result 47f46a955bSLisandro Dalcin except AttributeError: 48f46a955bSLisandro Dalcin pass 49f46a955bSLisandro Dalcin pkg_init_py = os.path.join(F('{pyname}'), '__init__.py') 50f46a955bSLisandro Dalcin with open(os.path.join(topdir, 'src', pkg_init_py)) as f: 515808f684SSatish Balay m = re.search(r"__version__\s*=\s*'(.*)'", f.read()) 52f46a955bSLisandro Dalcin version = m.groups()[0] 53f46a955bSLisandro Dalcin get_version.result = version 54f46a955bSLisandro Dalcin return version 555808f684SSatish Balay 566f336411SStefano Zampini 575808f684SSatish Balaydef description(): 58f46a955bSLisandro Dalcin return F('{Name} for Python') 59fb83dddaSLisandro Dalcin 606f336411SStefano Zampini 61fb83dddaSLisandro Dalcindef long_description(): 625808f684SSatish Balay with open(os.path.join(topdir, 'DESCRIPTION.rst')) as f: 635808f684SSatish Balay return f.read() 645808f684SSatish Balay 656f336411SStefano Zampini 66f46a955bSLisandro Dalcinurl = F('https://gitlab.com/{name}/{name}') 67f46a955bSLisandro Dalcinpypiroot = F('https://pypi.io/packages/source') 68f46a955bSLisandro Dalcinpypislug = F('{pyname}')[0] + F('/{pyname}') 69f46a955bSLisandro Dalcintarball = F('{pyname}-%s.tar.gz' % get_version()) 70f46a955bSLisandro Dalcindownload = '/'.join([pypiroot, pypislug, tarball]) 715808f684SSatish Balay 72fb83dddaSLisandro Dalcinclassifiers = """ 73fb83dddaSLisandro DalcinLicense :: OSI Approved :: BSD License 74fb83dddaSLisandro DalcinOperating System :: POSIX 75fb83dddaSLisandro DalcinIntended Audience :: Developers 76fb83dddaSLisandro DalcinIntended Audience :: Science/Research 77fb83dddaSLisandro DalcinProgramming Language :: C 78fb83dddaSLisandro DalcinProgramming Language :: C++ 79fb83dddaSLisandro DalcinProgramming Language :: Cython 80fb83dddaSLisandro DalcinProgramming Language :: Python 81fb83dddaSLisandro DalcinProgramming Language :: Python :: 2 82fb83dddaSLisandro DalcinProgramming Language :: Python :: 3 83fb83dddaSLisandro DalcinProgramming Language :: Python :: Implementation :: CPython 84fb83dddaSLisandro DalcinTopic :: Scientific/Engineering 85fb83dddaSLisandro DalcinTopic :: Software Development :: Libraries :: Python Modules 86fb83dddaSLisandro DalcinDevelopment Status :: 5 - Production/Stable 87f46a955bSLisandro Dalcin""".strip().split('\n') 885808f684SSatish Balay 89fb83dddaSLisandro Dalcinkeywords = """ 90fb83dddaSLisandro Dalcinscientific computing 91fb83dddaSLisandro Dalcinparallel computing 92fb83dddaSLisandro DalcinMPI 93f46a955bSLisandro Dalcin""".strip().split('\n') 945808f684SSatish Balay 95fb83dddaSLisandro Dalcinplatforms = """ 96fb83dddaSLisandro DalcinPOSIX 97fb83dddaSLisandro DalcinLinux 98fb83dddaSLisandro DalcinmacOS 99fb83dddaSLisandro DalcinFreeBSD 100f46a955bSLisandro Dalcin""".strip().split('\n') 101fb83dddaSLisandro Dalcin 102fb83dddaSLisandro Dalcinmetadata = { 103f46a955bSLisandro Dalcin 'name': get_name(), 104f46a955bSLisandro Dalcin 'version': get_version(), 105fb83dddaSLisandro Dalcin 'description': description(), 106fb83dddaSLisandro Dalcin 'long_description': long_description(), 107fb83dddaSLisandro Dalcin 'url': url, 108fb83dddaSLisandro Dalcin 'download_url': download, 109f46a955bSLisandro Dalcin 'classifiers': classifiers, 110f46a955bSLisandro Dalcin 'keywords': keywords + PLIST, 111fb83dddaSLisandro Dalcin 'license': 'BSD-2-Clause', 112f46a955bSLisandro Dalcin 'platforms': platforms, 113fb83dddaSLisandro Dalcin 'author': 'Lisandro Dalcin', 114fb83dddaSLisandro Dalcin 'author_email': 'dalcinl@gmail.com', 115f46a955bSLisandro Dalcin 'maintainer': F('{Name} Team'), 116f46a955bSLisandro Dalcin 'maintainer_email': EMAIL, 117fb83dddaSLisandro Dalcin} 1186f336411SStefano Zampinimetadata.update( 1196f336411SStefano Zampini { 120fb83dddaSLisandro Dalcin 'requires': ['numpy'], 1216f336411SStefano Zampini } 1226f336411SStefano Zampini) 123fb83dddaSLisandro Dalcin 124fb83dddaSLisandro Dalcinmetadata_extra = { 125833126bdSLisandro Dalcin 'long_description_content_type': 'text/x-rst', 126fb83dddaSLisandro Dalcin} 1275808f684SSatish Balay 1285808f684SSatish Balay# -------------------------------------------------------------------- 1295808f684SSatish Balay# Extension modules 1305808f684SSatish Balay# -------------------------------------------------------------------- 1315808f684SSatish Balay 1326f336411SStefano Zampini 133f46a955bSLisandro Dalcindef sources(): 1346f336411SStefano Zampini src = { 1356f336411SStefano Zampini 'source': F('{pyname}/{Name}.pyx'), 1366f336411SStefano Zampini 'depends': [ 137f46a955bSLisandro Dalcin F('{pyname}/*.pyx'), 138f46a955bSLisandro Dalcin F('{pyname}/*.pxd'), 139f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pyx'), 140f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pxd'), 141f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pxi'), 142f46a955bSLisandro Dalcin ], 1436f336411SStefano Zampini 'workdir': 'src', 1446f336411SStefano Zampini } 145f46a955bSLisandro Dalcin return [src] 146f46a955bSLisandro Dalcin 1476f336411SStefano Zampini 148fb83dddaSLisandro Dalcindef extensions(): 1498885bf16SLisandro Dalcin from os import walk 1505808f684SSatish Balay from glob import glob 1518885bf16SLisandro Dalcin from os.path import join 1526f336411SStefano Zampini 153f46a955bSLisandro Dalcin # 1545808f684SSatish Balay depends = [] 155f46a955bSLisandro Dalcin glob_join = lambda *args: glob(join(*args)) 1566f336411SStefano Zampini for pth, _, _ in walk('src'): 1578885bf16SLisandro Dalcin depends += glob_join(pth, '*.h') 1588885bf16SLisandro Dalcin depends += glob_join(pth, '*.c') 159f46a955bSLisandro Dalcin for pkg in map(str.lower, reversed(PLIST)): 160f46a955bSLisandro Dalcin if (pkg.upper() + '_DIR') in os.environ: 161f46a955bSLisandro Dalcin pd = os.environ[pkg.upper() + '_DIR'] 1628885bf16SLisandro Dalcin pa = os.environ.get('PETSC_ARCH', '') 1638885bf16SLisandro Dalcin depends += glob_join(pd, 'include', '*.h') 164f46a955bSLisandro Dalcin depends += glob_join(pd, 'include', pkg, 'private', '*.h') 165f46a955bSLisandro Dalcin depends += glob_join(pd, pa, 'include', '%sconf.h' % pkg) 166f46a955bSLisandro Dalcin # 167f46a955bSLisandro Dalcin include_dirs = [] 1680f51ee0fSAlexei Colin numpy_include = os.environ.get('NUMPY_INCLUDE') 1690f51ee0fSAlexei Colin if numpy_include is not None: 1700f51ee0fSAlexei Colin numpy_includes = [numpy_include] 1710f51ee0fSAlexei Colin else: 1725808f684SSatish Balay try: 1735808f684SSatish Balay import numpy 1746f336411SStefano Zampini 1755808f684SSatish Balay numpy_includes = [numpy.get_include()] 1765808f684SSatish Balay except ImportError: 1775808f684SSatish Balay numpy_includes = [] 178f46a955bSLisandro Dalcin include_dirs.extend(numpy_includes) 179f46a955bSLisandro Dalcin if F('{pyname}') != 'petsc4py': 180f46a955bSLisandro Dalcin try: 181f46a955bSLisandro Dalcin import petsc4py 1826f336411SStefano Zampini 183f46a955bSLisandro Dalcin petsc4py_includes = [petsc4py.get_include()] 184f46a955bSLisandro Dalcin except ImportError: 185f46a955bSLisandro Dalcin petsc4py_includes = [] 186f46a955bSLisandro Dalcin include_dirs.extend(petsc4py_includes) 187f46a955bSLisandro Dalcin # 1886f336411SStefano Zampini ext = { 1896f336411SStefano Zampini 'name': F('{pyname}.lib.{Name}'), 1906f336411SStefano Zampini 'sources': [F('src/{pyname}/{Name}.c')], 1916f336411SStefano Zampini 'depends': depends, 1926f336411SStefano Zampini 'include_dirs': [ 193f46a955bSLisandro Dalcin 'src', 194f46a955bSLisandro Dalcin F('src/{pyname}/include'), 1956f336411SStefano Zampini ] 1966f336411SStefano Zampini + include_dirs, 1976f336411SStefano Zampini 'define_macros': [ 198fb83dddaSLisandro Dalcin ('MPICH_SKIP_MPICXX', 1), 199fb83dddaSLisandro Dalcin ('OMPI_SKIP_MPICXX', 1), 200f46a955bSLisandro Dalcin ('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION'), 201fb83dddaSLisandro Dalcin ], 2026f336411SStefano Zampini } 203f46a955bSLisandro Dalcin return [ext] 2045808f684SSatish Balay 2056f336411SStefano Zampini 2065808f684SSatish Balay# -------------------------------------------------------------------- 2075808f684SSatish Balay# Setup 2085808f684SSatish Balay# -------------------------------------------------------------------- 2095808f684SSatish Balay 2106f336411SStefano Zampini 211f8c80548SLisandro Dalcindef get_release(): 212f46a955bSLisandro Dalcin suffix = os.path.join('src', 'binding', F('{pyname}')) 213f46a955bSLisandro Dalcin if not topdir.endswith(os.path.join(os.path.sep, suffix)): 214f09792b6SLisandro Dalcin return True 215f8c80548SLisandro Dalcin release = 1 216f8c80548SLisandro Dalcin rootdir = os.path.abspath(os.path.join(topdir, *[os.path.pardir] * 3)) 217f46a955bSLisandro Dalcin version_h = os.path.join(rootdir, 'include', F('{name}version.h')) 218f46a955bSLisandro Dalcin release_macro = '%s_VERSION_RELEASE' % F('{name}').upper() 2196f336411SStefano Zampini version_re = re.compile(r'#define\s+%s\s+([-]*\d+)' % release_macro) 220f8c80548SLisandro Dalcin if os.path.exists(version_h) and os.path.isfile(version_h): 221f8c80548SLisandro Dalcin with open(version_h, 'r') as f: 222f8c80548SLisandro Dalcin release = int(version_re.search(f.read()).groups()[0]) 223f8c80548SLisandro Dalcin return bool(release) 224f8c80548SLisandro Dalcin 2256f336411SStefano Zampini 226f8c80548SLisandro Dalcindef requires(pkgname, major, minor, release=True): 227f8c80548SLisandro Dalcin minor = minor + int(not release) 228f8c80548SLisandro Dalcin devel = '' if release else '.dev0' 2296f336411SStefano Zampini vmin = f'{major}.{minor}{devel}' 2306f336411SStefano Zampini vmax = f'{major}.{minor+1}' 2316f336411SStefano Zampini return f'{pkgname}>={vmin},<{vmax}' 2326f336411SStefano Zampini 233f8c80548SLisandro Dalcin 2345808f684SSatish Balaydef run_setup(): 235*2149b0eaSStefano Zampini is_sdist = 'sdist' in sys.argv 2365808f684SSatish Balay setup_args = metadata.copy() 237f8c80548SLisandro Dalcin vstr = setup_args['version'].split('.')[:2] 238f8c80548SLisandro Dalcin x, y = tuple(map(int, vstr)) 239f8c80548SLisandro Dalcin release = get_release() 240f8c80548SLisandro Dalcin if not release: 2416f336411SStefano Zampini setup_args['version'] = '%d.%d.0.dev0' % (x, y + 1) 2425808f684SSatish Balay if setuptools: 2435808f684SSatish Balay setup_args['zip_safe'] = False 244*2149b0eaSStefano Zampini numpy_pin = 'numpy' 245*2149b0eaSStefano Zampini if not is_sdist: 24630eefebbSLisandro Dalcin try: 24730eefebbSLisandro Dalcin import numpy 2486f336411SStefano Zampini 24930eefebbSLisandro Dalcin major = int(numpy.__version__.partition('.')[0]) 250f566d949SLisandro Dalcin numpy_pin = 'numpy>=1.19' if major >= 2 else 'numpy<2' 25130eefebbSLisandro Dalcin except ImportError: 252*2149b0eaSStefano Zampini pass 253693647e8SLisandro Dalcin setup_args['setup_requires'] = ['numpy'] 25430eefebbSLisandro Dalcin setup_args['install_requires'] = [numpy_pin] 255f46a955bSLisandro Dalcin for pkg in map(str.lower, PLIST): 256f46a955bSLisandro Dalcin PKG_DIR = os.environ.get(pkg.upper() + '_DIR') 257f46a955bSLisandro Dalcin if not (PKG_DIR and os.path.isdir(PKG_DIR)): 258f46a955bSLisandro Dalcin package = requires(pkg, x, y, release) 259693647e8SLisandro Dalcin setup_args['setup_requires'] += [package] 260f46a955bSLisandro Dalcin setup_args['install_requires'] += [package] 261f46a955bSLisandro Dalcin if F('{pyname}') != 'petsc4py': 262f46a955bSLisandro Dalcin package = requires('petsc4py', x, y, release) 263693647e8SLisandro Dalcin setup_args['setup_requires'] += [package] 264f46a955bSLisandro Dalcin setup_args['install_requires'] += [package] 265fb83dddaSLisandro Dalcin setup_args.update(metadata_extra) 2665808f684SSatish Balay # 267f46a955bSLisandro Dalcin conf = __import__(F('conf{name}')) 268f46a955bSLisandro Dalcin conf.setup( 269fb83dddaSLisandro Dalcin packages=[ 270f46a955bSLisandro Dalcin F('{pyname}'), 271f46a955bSLisandro Dalcin F('{pyname}.lib'), 272fb83dddaSLisandro Dalcin ], 273f46a955bSLisandro Dalcin package_dir={'': 'src'}, 274fb83dddaSLisandro Dalcin package_data={ 275f46a955bSLisandro Dalcin F('{pyname}'): [ 276f46a955bSLisandro Dalcin F('{Name}.pxd'), 277f46a955bSLisandro Dalcin F('{Name}*.h'), 278f46a955bSLisandro Dalcin F('include/{pyname}/*.h'), 279f46a955bSLisandro Dalcin F('include/{pyname}/*.i'), 28055a74a43SLisandro Dalcin 'py.typed', 28155a74a43SLisandro Dalcin '*.pyi', 28255a74a43SLisandro Dalcin '*/*.pyi', 283fb83dddaSLisandro Dalcin ], 284f46a955bSLisandro Dalcin F('{pyname}.lib'): [ 285f46a955bSLisandro Dalcin F('{name}.cfg'), 286fb83dddaSLisandro Dalcin ], 287fb83dddaSLisandro Dalcin }, 2886f336411SStefano Zampini cython_sources=[src for src in sources()], # noqa: C416 2896f336411SStefano Zampini ext_modules=[conf.Extension(**ext) for ext in extensions()], 2906f336411SStefano Zampini **setup_args, 291fb83dddaSLisandro Dalcin ) 2925808f684SSatish Balay 2936f336411SStefano Zampini 294fb83dddaSLisandro Dalcin# -------------------------------------------------------------------- 295fb83dddaSLisandro Dalcin 2966f336411SStefano Zampini 2975808f684SSatish Balaydef main(): 2985808f684SSatish Balay run_setup() 2995808f684SSatish Balay 3006f336411SStefano Zampini 3015808f684SSatish Balayif __name__ == '__main__': 3025808f684SSatish Balay main() 3035808f684SSatish Balay 3045808f684SSatish Balay# -------------------------------------------------------------------- 305