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 8*9fb6d20cSLisandro Dalcinimport warnings 95808f684SSatish Balay 105808f684SSatish Balaytry: 115808f684SSatish Balay import setuptools 125808f684SSatish Balayexcept ImportError: 135808f684SSatish Balay setuptools = None 145808f684SSatish Balay 15f46a955bSLisandro Dalcintopdir = os.path.abspath(os.path.dirname(__file__)) 16f46a955bSLisandro Dalcinsys.path.insert(0, os.path.join(topdir, 'conf')) 17f46a955bSLisandro Dalcin 185808f684SSatish Balaypyver = sys.version_info[:2] 19aab42556SSatish Balayif pyver < (3, 6): 20aab42556SSatish Balay raise RuntimeError('Python version 3.6 or higher is required') 211e83877aSSatish Balay 22f46a955bSLisandro DalcinPNAME = 'PETSc' 23f46a955bSLisandro DalcinEMAIL = 'petsc-maint@mcs.anl.gov' 24f46a955bSLisandro DalcinPLIST = [PNAME] 25fb83dddaSLisandro Dalcin 265808f684SSatish Balay# -------------------------------------------------------------------- 275808f684SSatish Balay# Metadata 285808f684SSatish Balay# -------------------------------------------------------------------- 295808f684SSatish Balay 306f336411SStefano Zampini 31f46a955bSLisandro Dalcindef F(string): 32f46a955bSLisandro Dalcin return string.format( 33f46a955bSLisandro Dalcin Name=PNAME, 34f46a955bSLisandro Dalcin name=PNAME.lower(), 35f46a955bSLisandro Dalcin pyname=PNAME.lower() + '4py', 36f46a955bSLisandro Dalcin ) 375808f684SSatish Balay 386f336411SStefano Zampini 39f46a955bSLisandro Dalcindef get_name(): 40f46a955bSLisandro Dalcin return F('{pyname}') 415808f684SSatish Balay 426f336411SStefano Zampini 43f46a955bSLisandro Dalcindef get_version(): 44f46a955bSLisandro Dalcin try: 45f46a955bSLisandro Dalcin return get_version.result 46f46a955bSLisandro Dalcin except AttributeError: 47f46a955bSLisandro Dalcin pass 48f46a955bSLisandro Dalcin pkg_init_py = os.path.join(F('{pyname}'), '__init__.py') 49f46a955bSLisandro Dalcin with open(os.path.join(topdir, 'src', pkg_init_py)) as f: 505808f684SSatish Balay m = re.search(r"__version__\s*=\s*'(.*)'", f.read()) 51f46a955bSLisandro Dalcin version = m.groups()[0] 52f46a955bSLisandro Dalcin get_version.result = version 53f46a955bSLisandro Dalcin return version 545808f684SSatish Balay 556f336411SStefano Zampini 565808f684SSatish Balaydef description(): 57f46a955bSLisandro Dalcin return F('{Name} for Python') 58fb83dddaSLisandro Dalcin 596f336411SStefano Zampini 60fb83dddaSLisandro Dalcindef long_description(): 615808f684SSatish Balay with open(os.path.join(topdir, 'DESCRIPTION.rst')) as f: 625808f684SSatish Balay return f.read() 635808f684SSatish Balay 646f336411SStefano Zampini 65f46a955bSLisandro Dalcinurl = F('https://gitlab.com/{name}/{name}') 66f46a955bSLisandro Dalcinpypiroot = F('https://pypi.io/packages/source') 67f46a955bSLisandro Dalcinpypislug = F('{pyname}')[0] + F('/{pyname}') 68f46a955bSLisandro Dalcintarball = F('{pyname}-%s.tar.gz' % get_version()) 69f46a955bSLisandro Dalcindownload = '/'.join([pypiroot, pypislug, tarball]) 705808f684SSatish Balay 71fb83dddaSLisandro Dalcinclassifiers = """ 72fb83dddaSLisandro DalcinOperating System :: POSIX 73fb83dddaSLisandro DalcinIntended Audience :: Developers 74fb83dddaSLisandro DalcinIntended Audience :: Science/Research 75fb83dddaSLisandro DalcinProgramming Language :: C 76fb83dddaSLisandro DalcinProgramming Language :: C++ 77fb83dddaSLisandro DalcinProgramming Language :: Cython 78fb83dddaSLisandro DalcinProgramming Language :: Python 79fb83dddaSLisandro DalcinProgramming Language :: Python :: 3 80fb83dddaSLisandro DalcinProgramming Language :: Python :: Implementation :: CPython 81fb83dddaSLisandro DalcinTopic :: Scientific/Engineering 82fb83dddaSLisandro DalcinTopic :: Software Development :: Libraries :: Python Modules 83fb83dddaSLisandro DalcinDevelopment Status :: 5 - Production/Stable 84f46a955bSLisandro Dalcin""".strip().split('\n') 855808f684SSatish Balay 86fb83dddaSLisandro Dalcinkeywords = """ 87fb83dddaSLisandro Dalcinscientific computing 88fb83dddaSLisandro Dalcinparallel computing 89fb83dddaSLisandro DalcinMPI 90f46a955bSLisandro Dalcin""".strip().split('\n') 915808f684SSatish Balay 92fb83dddaSLisandro Dalcinplatforms = """ 93fb83dddaSLisandro DalcinPOSIX 94fb83dddaSLisandro DalcinLinux 95fb83dddaSLisandro DalcinmacOS 96fb83dddaSLisandro DalcinFreeBSD 97f46a955bSLisandro Dalcin""".strip().split('\n') 98fb83dddaSLisandro Dalcin 99fb83dddaSLisandro Dalcinmetadata = { 100f46a955bSLisandro Dalcin 'name': get_name(), 101f46a955bSLisandro Dalcin 'version': get_version(), 102fb83dddaSLisandro Dalcin 'description': description(), 103fb83dddaSLisandro Dalcin 'long_description': long_description(), 104fb83dddaSLisandro Dalcin 'url': url, 105fb83dddaSLisandro Dalcin 'download_url': download, 106f46a955bSLisandro Dalcin 'classifiers': classifiers, 107f46a955bSLisandro Dalcin 'keywords': keywords + PLIST, 108fb83dddaSLisandro Dalcin 'license': 'BSD-2-Clause', 109f46a955bSLisandro Dalcin 'platforms': platforms, 110fb83dddaSLisandro Dalcin 'author': 'Lisandro Dalcin', 111fb83dddaSLisandro Dalcin 'author_email': 'dalcinl@gmail.com', 112f46a955bSLisandro Dalcin 'maintainer': F('{Name} Team'), 113f46a955bSLisandro Dalcin 'maintainer_email': EMAIL, 114fb83dddaSLisandro Dalcin} 1156f336411SStefano Zampinimetadata.update( 1166f336411SStefano Zampini { 117fb83dddaSLisandro Dalcin 'requires': ['numpy'], 1186f336411SStefano Zampini } 1196f336411SStefano Zampini) 120fb83dddaSLisandro Dalcin 121fb83dddaSLisandro Dalcinmetadata_extra = { 122833126bdSLisandro Dalcin 'long_description_content_type': 'text/x-rst', 123fb83dddaSLisandro Dalcin} 1245808f684SSatish Balay 1255808f684SSatish Balay# -------------------------------------------------------------------- 1265808f684SSatish Balay# Extension modules 1275808f684SSatish Balay# -------------------------------------------------------------------- 1285808f684SSatish Balay 1296f336411SStefano Zampini 130f46a955bSLisandro Dalcindef sources(): 1316f336411SStefano Zampini src = { 1326f336411SStefano Zampini 'source': F('{pyname}/{Name}.pyx'), 1336f336411SStefano Zampini 'depends': [ 134f46a955bSLisandro Dalcin F('{pyname}/*.pyx'), 135f46a955bSLisandro Dalcin F('{pyname}/*.pxd'), 136f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pyx'), 137f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pxd'), 138f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pxi'), 139f46a955bSLisandro Dalcin ], 1406f336411SStefano Zampini 'workdir': 'src', 1416f336411SStefano Zampini } 142f46a955bSLisandro Dalcin return [src] 143f46a955bSLisandro Dalcin 1446f336411SStefano Zampini 145fb83dddaSLisandro Dalcindef extensions(): 1468885bf16SLisandro Dalcin from os import walk 1475808f684SSatish Balay from glob import glob 1488885bf16SLisandro Dalcin from os.path import join 1496f336411SStefano Zampini 150f46a955bSLisandro Dalcin # 1515808f684SSatish Balay depends = [] 152f46a955bSLisandro Dalcin glob_join = lambda *args: glob(join(*args)) 1536f336411SStefano Zampini for pth, _, _ in walk('src'): 1548885bf16SLisandro Dalcin depends += glob_join(pth, '*.h') 1558885bf16SLisandro Dalcin depends += glob_join(pth, '*.c') 156f46a955bSLisandro Dalcin for pkg in map(str.lower, reversed(PLIST)): 157f46a955bSLisandro Dalcin if (pkg.upper() + '_DIR') in os.environ: 158f46a955bSLisandro Dalcin pd = os.environ[pkg.upper() + '_DIR'] 1598885bf16SLisandro Dalcin pa = os.environ.get('PETSC_ARCH', '') 1608885bf16SLisandro Dalcin depends += glob_join(pd, 'include', '*.h') 161f46a955bSLisandro Dalcin depends += glob_join(pd, 'include', pkg, 'private', '*.h') 162f46a955bSLisandro Dalcin depends += glob_join(pd, pa, 'include', '%sconf.h' % pkg) 163f46a955bSLisandro Dalcin # 164f46a955bSLisandro Dalcin include_dirs = [] 1650f51ee0fSAlexei Colin numpy_include = os.environ.get('NUMPY_INCLUDE') 1660f51ee0fSAlexei Colin if numpy_include is not None: 1670f51ee0fSAlexei Colin numpy_includes = [numpy_include] 1680f51ee0fSAlexei Colin else: 1695808f684SSatish Balay try: 1705808f684SSatish Balay import numpy 1716f336411SStefano Zampini 1725808f684SSatish Balay numpy_includes = [numpy.get_include()] 1735808f684SSatish Balay except ImportError: 1745808f684SSatish Balay numpy_includes = [] 175f46a955bSLisandro Dalcin include_dirs.extend(numpy_includes) 176f46a955bSLisandro Dalcin if F('{pyname}') != 'petsc4py': 177f46a955bSLisandro Dalcin try: 178f46a955bSLisandro Dalcin import petsc4py 1796f336411SStefano Zampini 180f46a955bSLisandro Dalcin petsc4py_includes = [petsc4py.get_include()] 181f46a955bSLisandro Dalcin except ImportError: 182f46a955bSLisandro Dalcin petsc4py_includes = [] 183f46a955bSLisandro Dalcin include_dirs.extend(petsc4py_includes) 184f46a955bSLisandro Dalcin # 1856f336411SStefano Zampini ext = { 1866f336411SStefano Zampini 'name': F('{pyname}.lib.{Name}'), 1876f336411SStefano Zampini 'sources': [F('src/{pyname}/{Name}.c')], 1886f336411SStefano Zampini 'depends': depends, 1896f336411SStefano Zampini 'include_dirs': [ 190f46a955bSLisandro Dalcin 'src', 191f46a955bSLisandro Dalcin F('src/{pyname}/include'), 1926f336411SStefano Zampini ] 1936f336411SStefano Zampini + include_dirs, 1946f336411SStefano Zampini 'define_macros': [ 195fb83dddaSLisandro Dalcin ('MPICH_SKIP_MPICXX', 1), 196fb83dddaSLisandro Dalcin ('OMPI_SKIP_MPICXX', 1), 197f46a955bSLisandro Dalcin ('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION'), 198fb83dddaSLisandro Dalcin ], 1996f336411SStefano Zampini } 200f46a955bSLisandro Dalcin return [ext] 2015808f684SSatish Balay 2026f336411SStefano Zampini 2035808f684SSatish Balay# -------------------------------------------------------------------- 2045808f684SSatish Balay# Setup 2055808f684SSatish Balay# -------------------------------------------------------------------- 2065808f684SSatish Balay 2076f336411SStefano Zampini 208f8c80548SLisandro Dalcindef get_release(): 209f46a955bSLisandro Dalcin suffix = os.path.join('src', 'binding', F('{pyname}')) 210f46a955bSLisandro Dalcin if not topdir.endswith(os.path.join(os.path.sep, suffix)): 211f09792b6SLisandro Dalcin return True 212f8c80548SLisandro Dalcin release = 1 213f8c80548SLisandro Dalcin rootdir = os.path.abspath(os.path.join(topdir, *[os.path.pardir] * 3)) 214f46a955bSLisandro Dalcin version_h = os.path.join(rootdir, 'include', F('{name}version.h')) 215f46a955bSLisandro Dalcin release_macro = '%s_VERSION_RELEASE' % F('{name}').upper() 2166f336411SStefano Zampini version_re = re.compile(r'#define\s+%s\s+([-]*\d+)' % release_macro) 217f8c80548SLisandro Dalcin if os.path.exists(version_h) and os.path.isfile(version_h): 218f8c80548SLisandro Dalcin with open(version_h, 'r') as f: 219f8c80548SLisandro Dalcin release = int(version_re.search(f.read()).groups()[0]) 220f8c80548SLisandro Dalcin return bool(release) 221f8c80548SLisandro Dalcin 2226f336411SStefano Zampini 223f8c80548SLisandro Dalcindef requires(pkgname, major, minor, release=True): 224f8c80548SLisandro Dalcin minor = minor + int(not release) 225f8c80548SLisandro Dalcin devel = '' if release else '.dev0' 2266f336411SStefano Zampini vmin = f'{major}.{minor}{devel}' 2276f336411SStefano Zampini vmax = f'{major}.{minor+1}' 2286f336411SStefano Zampini return f'{pkgname}>={vmin},<{vmax}' 2296f336411SStefano Zampini 230f8c80548SLisandro Dalcin 2315808f684SSatish Balaydef run_setup(): 2322149b0eaSStefano Zampini is_sdist = 'sdist' in sys.argv 2335808f684SSatish Balay setup_args = metadata.copy() 234f8c80548SLisandro Dalcin vstr = setup_args['version'].split('.')[:2] 235f8c80548SLisandro Dalcin x, y = tuple(map(int, vstr)) 236f8c80548SLisandro Dalcin release = get_release() 237f8c80548SLisandro Dalcin if not release: 2386f336411SStefano Zampini setup_args['version'] = '%d.%d.0.dev0' % (x, y + 1) 2395808f684SSatish Balay if setuptools: 240*9fb6d20cSLisandro Dalcin warnings.filterwarnings( 241*9fb6d20cSLisandro Dalcin 'ignore', message=r'.*fetch_build_eggs', module='setuptools' 242*9fb6d20cSLisandro Dalcin ) 2435808f684SSatish Balay setup_args['zip_safe'] = False 2442149b0eaSStefano Zampini numpy_pin = 'numpy' 2452149b0eaSStefano 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: 2522149b0eaSStefano 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'), 27222d6dc08SStefano Zampini F('{pyname}.lib._pytypes'), 27322d6dc08SStefano Zampini F('{pyname}.lib._pytypes.viewer'), 274fb83dddaSLisandro Dalcin ], 275f46a955bSLisandro Dalcin package_dir={'': 'src'}, 276fb83dddaSLisandro Dalcin package_data={ 277f46a955bSLisandro Dalcin F('{pyname}'): [ 278f46a955bSLisandro Dalcin F('{Name}.pxd'), 279f46a955bSLisandro Dalcin F('{Name}*.h'), 280f46a955bSLisandro Dalcin F('include/{pyname}/*.h'), 281f46a955bSLisandro Dalcin F('include/{pyname}/*.i'), 28255a74a43SLisandro Dalcin 'py.typed', 28355a74a43SLisandro Dalcin '*.pyi', 28455a74a43SLisandro Dalcin '*/*.pyi', 285fb83dddaSLisandro Dalcin ], 286f46a955bSLisandro Dalcin F('{pyname}.lib'): [ 287f46a955bSLisandro Dalcin F('{name}.cfg'), 288fb83dddaSLisandro Dalcin ], 289fb83dddaSLisandro Dalcin }, 2906f336411SStefano Zampini cython_sources=[src for src in sources()], # noqa: C416 2916f336411SStefano Zampini ext_modules=[conf.Extension(**ext) for ext in extensions()], 2926f336411SStefano Zampini **setup_args, 293fb83dddaSLisandro Dalcin ) 2945808f684SSatish Balay 2956f336411SStefano Zampini 296fb83dddaSLisandro Dalcin# -------------------------------------------------------------------- 297fb83dddaSLisandro Dalcin 2986f336411SStefano Zampini 2995808f684SSatish Balaydef main(): 3005808f684SSatish Balay run_setup() 3015808f684SSatish Balay 3026f336411SStefano Zampini 3035808f684SSatish Balayif __name__ == '__main__': 3045808f684SSatish Balay main() 3055808f684SSatish Balay 3065808f684SSatish Balay# -------------------------------------------------------------------- 307