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] 18*aab42556SSatish Balayif pyver < (3, 6): 19*aab42556SSatish Balay raise RuntimeError('Python version 3.6 or higher is required') 201e83877aSSatish Balay 21f46a955bSLisandro DalcinPNAME = 'PETSc' 22f46a955bSLisandro DalcinEMAIL = 'petsc-maint@mcs.anl.gov' 23f46a955bSLisandro DalcinPLIST = [PNAME] 24fb83dddaSLisandro Dalcin 255808f684SSatish Balay# -------------------------------------------------------------------- 265808f684SSatish Balay# Metadata 275808f684SSatish Balay# -------------------------------------------------------------------- 285808f684SSatish Balay 296f336411SStefano Zampini 30f46a955bSLisandro Dalcindef F(string): 31f46a955bSLisandro Dalcin return string.format( 32f46a955bSLisandro Dalcin Name=PNAME, 33f46a955bSLisandro Dalcin name=PNAME.lower(), 34f46a955bSLisandro Dalcin pyname=PNAME.lower() + '4py', 35f46a955bSLisandro Dalcin ) 365808f684SSatish Balay 376f336411SStefano Zampini 38f46a955bSLisandro Dalcindef get_name(): 39f46a955bSLisandro Dalcin return F('{pyname}') 405808f684SSatish Balay 416f336411SStefano Zampini 42f46a955bSLisandro Dalcindef get_version(): 43f46a955bSLisandro Dalcin try: 44f46a955bSLisandro Dalcin return get_version.result 45f46a955bSLisandro Dalcin except AttributeError: 46f46a955bSLisandro Dalcin pass 47f46a955bSLisandro Dalcin pkg_init_py = os.path.join(F('{pyname}'), '__init__.py') 48f46a955bSLisandro Dalcin with open(os.path.join(topdir, 'src', pkg_init_py)) as f: 495808f684SSatish Balay m = re.search(r"__version__\s*=\s*'(.*)'", f.read()) 50f46a955bSLisandro Dalcin version = m.groups()[0] 51f46a955bSLisandro Dalcin get_version.result = version 52f46a955bSLisandro Dalcin return version 535808f684SSatish Balay 546f336411SStefano Zampini 555808f684SSatish Balaydef description(): 56f46a955bSLisandro Dalcin return F('{Name} for Python') 57fb83dddaSLisandro Dalcin 586f336411SStefano Zampini 59fb83dddaSLisandro Dalcindef long_description(): 605808f684SSatish Balay with open(os.path.join(topdir, 'DESCRIPTION.rst')) as f: 615808f684SSatish Balay return f.read() 625808f684SSatish Balay 636f336411SStefano Zampini 64f46a955bSLisandro Dalcinurl = F('https://gitlab.com/{name}/{name}') 65f46a955bSLisandro Dalcinpypiroot = F('https://pypi.io/packages/source') 66f46a955bSLisandro Dalcinpypislug = F('{pyname}')[0] + F('/{pyname}') 67f46a955bSLisandro Dalcintarball = F('{pyname}-%s.tar.gz' % get_version()) 68f46a955bSLisandro Dalcindownload = '/'.join([pypiroot, pypislug, tarball]) 695808f684SSatish Balay 70fb83dddaSLisandro Dalcinclassifiers = """ 71fb83dddaSLisandro DalcinOperating System :: POSIX 72fb83dddaSLisandro DalcinIntended Audience :: Developers 73fb83dddaSLisandro DalcinIntended Audience :: Science/Research 74fb83dddaSLisandro DalcinProgramming Language :: C 75fb83dddaSLisandro DalcinProgramming Language :: C++ 76fb83dddaSLisandro DalcinProgramming Language :: Cython 77fb83dddaSLisandro DalcinProgramming Language :: Python 78fb83dddaSLisandro DalcinProgramming Language :: Python :: 3 79fb83dddaSLisandro DalcinProgramming Language :: Python :: Implementation :: CPython 80fb83dddaSLisandro DalcinTopic :: Scientific/Engineering 81fb83dddaSLisandro DalcinTopic :: Software Development :: Libraries :: Python Modules 82fb83dddaSLisandro DalcinDevelopment Status :: 5 - Production/Stable 83f46a955bSLisandro Dalcin""".strip().split('\n') 845808f684SSatish Balay 85fb83dddaSLisandro Dalcinkeywords = """ 86fb83dddaSLisandro Dalcinscientific computing 87fb83dddaSLisandro Dalcinparallel computing 88fb83dddaSLisandro DalcinMPI 89f46a955bSLisandro Dalcin""".strip().split('\n') 905808f684SSatish Balay 91fb83dddaSLisandro Dalcinplatforms = """ 92fb83dddaSLisandro DalcinPOSIX 93fb83dddaSLisandro DalcinLinux 94fb83dddaSLisandro DalcinmacOS 95fb83dddaSLisandro DalcinFreeBSD 96f46a955bSLisandro Dalcin""".strip().split('\n') 97fb83dddaSLisandro Dalcin 98fb83dddaSLisandro Dalcinmetadata = { 99f46a955bSLisandro Dalcin 'name': get_name(), 100f46a955bSLisandro Dalcin 'version': get_version(), 101fb83dddaSLisandro Dalcin 'description': description(), 102fb83dddaSLisandro Dalcin 'long_description': long_description(), 103fb83dddaSLisandro Dalcin 'url': url, 104fb83dddaSLisandro Dalcin 'download_url': download, 105f46a955bSLisandro Dalcin 'classifiers': classifiers, 106f46a955bSLisandro Dalcin 'keywords': keywords + PLIST, 107fb83dddaSLisandro Dalcin 'license': 'BSD-2-Clause', 108f46a955bSLisandro Dalcin 'platforms': platforms, 109fb83dddaSLisandro Dalcin 'author': 'Lisandro Dalcin', 110fb83dddaSLisandro Dalcin 'author_email': 'dalcinl@gmail.com', 111f46a955bSLisandro Dalcin 'maintainer': F('{Name} Team'), 112f46a955bSLisandro Dalcin 'maintainer_email': EMAIL, 113fb83dddaSLisandro Dalcin} 1146f336411SStefano Zampinimetadata.update( 1156f336411SStefano Zampini { 116fb83dddaSLisandro Dalcin 'requires': ['numpy'], 1176f336411SStefano Zampini } 1186f336411SStefano Zampini) 119fb83dddaSLisandro Dalcin 120fb83dddaSLisandro Dalcinmetadata_extra = { 121833126bdSLisandro Dalcin 'long_description_content_type': 'text/x-rst', 122fb83dddaSLisandro Dalcin} 1235808f684SSatish Balay 1245808f684SSatish Balay# -------------------------------------------------------------------- 1255808f684SSatish Balay# Extension modules 1265808f684SSatish Balay# -------------------------------------------------------------------- 1275808f684SSatish Balay 1286f336411SStefano Zampini 129f46a955bSLisandro Dalcindef sources(): 1306f336411SStefano Zampini src = { 1316f336411SStefano Zampini 'source': F('{pyname}/{Name}.pyx'), 1326f336411SStefano Zampini 'depends': [ 133f46a955bSLisandro Dalcin F('{pyname}/*.pyx'), 134f46a955bSLisandro Dalcin F('{pyname}/*.pxd'), 135f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pyx'), 136f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pxd'), 137f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pxi'), 138f46a955bSLisandro Dalcin ], 1396f336411SStefano Zampini 'workdir': 'src', 1406f336411SStefano Zampini } 141f46a955bSLisandro Dalcin return [src] 142f46a955bSLisandro Dalcin 1436f336411SStefano Zampini 144fb83dddaSLisandro Dalcindef extensions(): 1458885bf16SLisandro Dalcin from os import walk 1465808f684SSatish Balay from glob import glob 1478885bf16SLisandro Dalcin from os.path import join 1486f336411SStefano Zampini 149f46a955bSLisandro Dalcin # 1505808f684SSatish Balay depends = [] 151f46a955bSLisandro Dalcin glob_join = lambda *args: glob(join(*args)) 1526f336411SStefano Zampini for pth, _, _ in walk('src'): 1538885bf16SLisandro Dalcin depends += glob_join(pth, '*.h') 1548885bf16SLisandro Dalcin depends += glob_join(pth, '*.c') 155f46a955bSLisandro Dalcin for pkg in map(str.lower, reversed(PLIST)): 156f46a955bSLisandro Dalcin if (pkg.upper() + '_DIR') in os.environ: 157f46a955bSLisandro Dalcin pd = os.environ[pkg.upper() + '_DIR'] 1588885bf16SLisandro Dalcin pa = os.environ.get('PETSC_ARCH', '') 1598885bf16SLisandro Dalcin depends += glob_join(pd, 'include', '*.h') 160f46a955bSLisandro Dalcin depends += glob_join(pd, 'include', pkg, 'private', '*.h') 161f46a955bSLisandro Dalcin depends += glob_join(pd, pa, 'include', '%sconf.h' % pkg) 162f46a955bSLisandro Dalcin # 163f46a955bSLisandro Dalcin include_dirs = [] 1640f51ee0fSAlexei Colin numpy_include = os.environ.get('NUMPY_INCLUDE') 1650f51ee0fSAlexei Colin if numpy_include is not None: 1660f51ee0fSAlexei Colin numpy_includes = [numpy_include] 1670f51ee0fSAlexei Colin else: 1685808f684SSatish Balay try: 1695808f684SSatish Balay import numpy 1706f336411SStefano Zampini 1715808f684SSatish Balay numpy_includes = [numpy.get_include()] 1725808f684SSatish Balay except ImportError: 1735808f684SSatish Balay numpy_includes = [] 174f46a955bSLisandro Dalcin include_dirs.extend(numpy_includes) 175f46a955bSLisandro Dalcin if F('{pyname}') != 'petsc4py': 176f46a955bSLisandro Dalcin try: 177f46a955bSLisandro Dalcin import petsc4py 1786f336411SStefano Zampini 179f46a955bSLisandro Dalcin petsc4py_includes = [petsc4py.get_include()] 180f46a955bSLisandro Dalcin except ImportError: 181f46a955bSLisandro Dalcin petsc4py_includes = [] 182f46a955bSLisandro Dalcin include_dirs.extend(petsc4py_includes) 183f46a955bSLisandro Dalcin # 1846f336411SStefano Zampini ext = { 1856f336411SStefano Zampini 'name': F('{pyname}.lib.{Name}'), 1866f336411SStefano Zampini 'sources': [F('src/{pyname}/{Name}.c')], 1876f336411SStefano Zampini 'depends': depends, 1886f336411SStefano Zampini 'include_dirs': [ 189f46a955bSLisandro Dalcin 'src', 190f46a955bSLisandro Dalcin F('src/{pyname}/include'), 1916f336411SStefano Zampini ] 1926f336411SStefano Zampini + include_dirs, 1936f336411SStefano Zampini 'define_macros': [ 194fb83dddaSLisandro Dalcin ('MPICH_SKIP_MPICXX', 1), 195fb83dddaSLisandro Dalcin ('OMPI_SKIP_MPICXX', 1), 196f46a955bSLisandro Dalcin ('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION'), 197fb83dddaSLisandro Dalcin ], 1986f336411SStefano Zampini } 199f46a955bSLisandro Dalcin return [ext] 2005808f684SSatish Balay 2016f336411SStefano Zampini 2025808f684SSatish Balay# -------------------------------------------------------------------- 2035808f684SSatish Balay# Setup 2045808f684SSatish Balay# -------------------------------------------------------------------- 2055808f684SSatish Balay 2066f336411SStefano Zampini 207f8c80548SLisandro Dalcindef get_release(): 208f46a955bSLisandro Dalcin suffix = os.path.join('src', 'binding', F('{pyname}')) 209f46a955bSLisandro Dalcin if not topdir.endswith(os.path.join(os.path.sep, suffix)): 210f09792b6SLisandro Dalcin return True 211f8c80548SLisandro Dalcin release = 1 212f8c80548SLisandro Dalcin rootdir = os.path.abspath(os.path.join(topdir, *[os.path.pardir] * 3)) 213f46a955bSLisandro Dalcin version_h = os.path.join(rootdir, 'include', F('{name}version.h')) 214f46a955bSLisandro Dalcin release_macro = '%s_VERSION_RELEASE' % F('{name}').upper() 2156f336411SStefano Zampini version_re = re.compile(r'#define\s+%s\s+([-]*\d+)' % release_macro) 216f8c80548SLisandro Dalcin if os.path.exists(version_h) and os.path.isfile(version_h): 217f8c80548SLisandro Dalcin with open(version_h, 'r') as f: 218f8c80548SLisandro Dalcin release = int(version_re.search(f.read()).groups()[0]) 219f8c80548SLisandro Dalcin return bool(release) 220f8c80548SLisandro Dalcin 2216f336411SStefano Zampini 222f8c80548SLisandro Dalcindef requires(pkgname, major, minor, release=True): 223f8c80548SLisandro Dalcin minor = minor + int(not release) 224f8c80548SLisandro Dalcin devel = '' if release else '.dev0' 2256f336411SStefano Zampini vmin = f'{major}.{minor}{devel}' 2266f336411SStefano Zampini vmax = f'{major}.{minor+1}' 2276f336411SStefano Zampini return f'{pkgname}>={vmin},<{vmax}' 2286f336411SStefano Zampini 229f8c80548SLisandro Dalcin 2305808f684SSatish Balaydef run_setup(): 2312149b0eaSStefano Zampini is_sdist = 'sdist' in sys.argv 2325808f684SSatish Balay setup_args = metadata.copy() 233f8c80548SLisandro Dalcin vstr = setup_args['version'].split('.')[:2] 234f8c80548SLisandro Dalcin x, y = tuple(map(int, vstr)) 235f8c80548SLisandro Dalcin release = get_release() 236f8c80548SLisandro Dalcin if not release: 2376f336411SStefano Zampini setup_args['version'] = '%d.%d.0.dev0' % (x, y + 1) 2385808f684SSatish Balay if setuptools: 2395808f684SSatish Balay setup_args['zip_safe'] = False 2402149b0eaSStefano Zampini numpy_pin = 'numpy' 2412149b0eaSStefano Zampini if not is_sdist: 24230eefebbSLisandro Dalcin try: 24330eefebbSLisandro Dalcin import numpy 2446f336411SStefano Zampini 24530eefebbSLisandro Dalcin major = int(numpy.__version__.partition('.')[0]) 246f566d949SLisandro Dalcin numpy_pin = 'numpy>=1.19' if major >= 2 else 'numpy<2' 24730eefebbSLisandro Dalcin except ImportError: 2482149b0eaSStefano Zampini pass 249693647e8SLisandro Dalcin setup_args['setup_requires'] = ['numpy'] 25030eefebbSLisandro Dalcin setup_args['install_requires'] = [numpy_pin] 251f46a955bSLisandro Dalcin for pkg in map(str.lower, PLIST): 252f46a955bSLisandro Dalcin PKG_DIR = os.environ.get(pkg.upper() + '_DIR') 253f46a955bSLisandro Dalcin if not (PKG_DIR and os.path.isdir(PKG_DIR)): 254f46a955bSLisandro Dalcin package = requires(pkg, x, y, release) 255693647e8SLisandro Dalcin setup_args['setup_requires'] += [package] 256f46a955bSLisandro Dalcin setup_args['install_requires'] += [package] 257f46a955bSLisandro Dalcin if F('{pyname}') != 'petsc4py': 258f46a955bSLisandro Dalcin package = requires('petsc4py', x, y, release) 259693647e8SLisandro Dalcin setup_args['setup_requires'] += [package] 260f46a955bSLisandro Dalcin setup_args['install_requires'] += [package] 261fb83dddaSLisandro Dalcin setup_args.update(metadata_extra) 2625808f684SSatish Balay # 263f46a955bSLisandro Dalcin conf = __import__(F('conf{name}')) 264f46a955bSLisandro Dalcin conf.setup( 265fb83dddaSLisandro Dalcin packages=[ 266f46a955bSLisandro Dalcin F('{pyname}'), 267f46a955bSLisandro Dalcin F('{pyname}.lib'), 26822d6dc08SStefano Zampini F('{pyname}.lib._pytypes'), 26922d6dc08SStefano Zampini F('{pyname}.lib._pytypes.viewer'), 270fb83dddaSLisandro Dalcin ], 271f46a955bSLisandro Dalcin package_dir={'': 'src'}, 272fb83dddaSLisandro Dalcin package_data={ 273f46a955bSLisandro Dalcin F('{pyname}'): [ 274f46a955bSLisandro Dalcin F('{Name}.pxd'), 275f46a955bSLisandro Dalcin F('{Name}*.h'), 276f46a955bSLisandro Dalcin F('include/{pyname}/*.h'), 277f46a955bSLisandro Dalcin F('include/{pyname}/*.i'), 27855a74a43SLisandro Dalcin 'py.typed', 27955a74a43SLisandro Dalcin '*.pyi', 28055a74a43SLisandro Dalcin '*/*.pyi', 281fb83dddaSLisandro Dalcin ], 282f46a955bSLisandro Dalcin F('{pyname}.lib'): [ 283f46a955bSLisandro Dalcin F('{name}.cfg'), 284fb83dddaSLisandro Dalcin ], 285fb83dddaSLisandro Dalcin }, 2866f336411SStefano Zampini cython_sources=[src for src in sources()], # noqa: C416 2876f336411SStefano Zampini ext_modules=[conf.Extension(**ext) for ext in extensions()], 2886f336411SStefano Zampini **setup_args, 289fb83dddaSLisandro Dalcin ) 2905808f684SSatish Balay 2916f336411SStefano Zampini 292fb83dddaSLisandro Dalcin# -------------------------------------------------------------------- 293fb83dddaSLisandro Dalcin 2946f336411SStefano Zampini 2955808f684SSatish Balaydef main(): 2965808f684SSatish Balay run_setup() 2975808f684SSatish Balay 2986f336411SStefano Zampini 2995808f684SSatish Balayif __name__ == '__main__': 3005808f684SSatish Balay main() 3015808f684SSatish Balay 3025808f684SSatish Balay# -------------------------------------------------------------------- 303