15808f684SSatish Balay#!/usr/bin/env python 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): 191e83877aSSatish Balay raise RuntimeError("Python version 2.6, 2.7 or >= 3.2 required") 201e83877aSSatish Balayif pyver == (2, 6) or pyver == (3, 2): 211e83877aSSatish Balay sys.stderr.write( 221e83877aSSatish Balay "WARNING: Python %d.%d is not supported.\n" % pyver) 231e83877aSSatish Balay 24f46a955bSLisandro DalcinPNAME = 'PETSc' 25f46a955bSLisandro DalcinEMAIL = 'petsc-maint@mcs.anl.gov' 26f46a955bSLisandro DalcinPLIST = [PNAME] 27fb83dddaSLisandro Dalcin 285808f684SSatish Balay# -------------------------------------------------------------------- 295808f684SSatish Balay# Metadata 305808f684SSatish Balay# -------------------------------------------------------------------- 315808f684SSatish Balay 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 39f46a955bSLisandro Dalcindef get_name(): 40f46a955bSLisandro Dalcin return F('{pyname}') 415808f684SSatish Balay 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 545808f684SSatish Balaydef description(): 55f46a955bSLisandro Dalcin return F('{Name} for Python') 56fb83dddaSLisandro Dalcin 57fb83dddaSLisandro Dalcindef long_description(): 585808f684SSatish Balay with open(os.path.join(topdir, 'DESCRIPTION.rst')) as f: 595808f684SSatish Balay return f.read() 605808f684SSatish Balay 61f46a955bSLisandro Dalcinurl = F('https://gitlab.com/{name}/{name}') 62f46a955bSLisandro Dalcinpypiroot = F('https://pypi.io/packages/source') 63f46a955bSLisandro Dalcinpypislug = F('{pyname}')[0] + F('/{pyname}') 64f46a955bSLisandro Dalcintarball = F('{pyname}-%s.tar.gz' % get_version()) 65f46a955bSLisandro Dalcindownload = '/'.join([pypiroot, pypislug, tarball]) 665808f684SSatish Balay 67fb83dddaSLisandro Dalcinclassifiers = """ 68fb83dddaSLisandro DalcinLicense :: OSI Approved :: BSD License 69fb83dddaSLisandro DalcinOperating System :: POSIX 70fb83dddaSLisandro DalcinIntended Audience :: Developers 71fb83dddaSLisandro DalcinIntended Audience :: Science/Research 72fb83dddaSLisandro DalcinProgramming Language :: C 73fb83dddaSLisandro DalcinProgramming Language :: C++ 74fb83dddaSLisandro DalcinProgramming Language :: Cython 75fb83dddaSLisandro DalcinProgramming Language :: Python 76fb83dddaSLisandro DalcinProgramming Language :: Python :: 2 77fb83dddaSLisandro DalcinProgramming Language :: Python :: 3 78fb83dddaSLisandro DalcinProgramming Language :: Python :: Implementation :: CPython 79fb83dddaSLisandro DalcinTopic :: Scientific/Engineering 80fb83dddaSLisandro DalcinTopic :: Software Development :: Libraries :: Python Modules 81fb83dddaSLisandro DalcinDevelopment Status :: 5 - Production/Stable 82f46a955bSLisandro Dalcin""".strip().split('\n') 835808f684SSatish Balay 84fb83dddaSLisandro Dalcinkeywords = """ 85fb83dddaSLisandro Dalcinscientific computing 86fb83dddaSLisandro Dalcinparallel computing 87fb83dddaSLisandro DalcinMPI 88f46a955bSLisandro Dalcin""".strip().split('\n') 895808f684SSatish Balay 90fb83dddaSLisandro Dalcinplatforms = """ 91fb83dddaSLisandro DalcinPOSIX 92fb83dddaSLisandro DalcinLinux 93fb83dddaSLisandro DalcinmacOS 94fb83dddaSLisandro DalcinFreeBSD 95f46a955bSLisandro Dalcin""".strip().split('\n') 96fb83dddaSLisandro Dalcin 97fb83dddaSLisandro Dalcinmetadata = { 98f46a955bSLisandro Dalcin 'name' : get_name(), 99f46a955bSLisandro Dalcin 'version' : get_version(), 100fb83dddaSLisandro Dalcin 'description' : description(), 101fb83dddaSLisandro Dalcin 'long_description' : long_description(), 102fb83dddaSLisandro Dalcin 'url' : url, 103fb83dddaSLisandro Dalcin 'download_url' : download, 104f46a955bSLisandro Dalcin 'classifiers' : classifiers, 105f46a955bSLisandro Dalcin 'keywords' : keywords + PLIST, 106fb83dddaSLisandro Dalcin 'license' : 'BSD-2-Clause', 107f46a955bSLisandro Dalcin 'platforms' : platforms, 108fb83dddaSLisandro Dalcin 'author' : 'Lisandro Dalcin', 109fb83dddaSLisandro Dalcin 'author_email' : 'dalcinl@gmail.com', 110f46a955bSLisandro Dalcin 'maintainer' : F('{Name} Team'), 111f46a955bSLisandro Dalcin 'maintainer_email' : EMAIL, 112fb83dddaSLisandro Dalcin} 113fb83dddaSLisandro Dalcinmetadata.update({ 114fb83dddaSLisandro Dalcin 'requires': ['numpy'], 115fb83dddaSLisandro Dalcin}) 116fb83dddaSLisandro Dalcin 117fb83dddaSLisandro Dalcinmetadata_extra = { 118833126bdSLisandro Dalcin 'long_description_content_type': 'text/x-rst', 119fb83dddaSLisandro Dalcin} 1205808f684SSatish Balay 1215808f684SSatish Balay# -------------------------------------------------------------------- 1225808f684SSatish Balay# Extension modules 1235808f684SSatish Balay# -------------------------------------------------------------------- 1245808f684SSatish Balay 125f46a955bSLisandro Dalcindef sources(): 126f46a955bSLisandro Dalcin src = dict( 127f46a955bSLisandro Dalcin source=F('{pyname}/{Name}.pyx'), 128f46a955bSLisandro Dalcin depends=[ 129f46a955bSLisandro Dalcin F('{pyname}/*.pyx'), 130f46a955bSLisandro Dalcin F('{pyname}/*.pxd'), 131f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pyx'), 132f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pxd'), 133f46a955bSLisandro Dalcin F('{pyname}/{Name}/*.pxi'), 134f46a955bSLisandro Dalcin ], 135f46a955bSLisandro Dalcin workdir='src', 136f46a955bSLisandro Dalcin ) 137f46a955bSLisandro Dalcin return [src] 138f46a955bSLisandro Dalcin 139fb83dddaSLisandro Dalcindef extensions(): 1408885bf16SLisandro Dalcin from os import walk 1415808f684SSatish Balay from glob import glob 1428885bf16SLisandro Dalcin from os.path import join 143f46a955bSLisandro Dalcin # 1445808f684SSatish Balay depends = [] 145f46a955bSLisandro Dalcin glob_join = lambda *args: glob(join(*args)) 1465808f684SSatish Balay for pth, dirs, files in walk('src'): 1478885bf16SLisandro Dalcin depends += glob_join(pth, '*.h') 1488885bf16SLisandro Dalcin depends += glob_join(pth, '*.c') 149f46a955bSLisandro Dalcin for pkg in map(str.lower, reversed(PLIST)): 150f46a955bSLisandro Dalcin if (pkg.upper()+'_DIR') in os.environ: 151f46a955bSLisandro Dalcin pd = os.environ[pkg.upper()+'_DIR'] 1528885bf16SLisandro Dalcin pa = os.environ.get('PETSC_ARCH', '') 1538885bf16SLisandro Dalcin depends += glob_join(pd, 'include', '*.h') 154f46a955bSLisandro Dalcin depends += glob_join(pd, 'include', pkg, 'private', '*.h') 155f46a955bSLisandro Dalcin depends += glob_join(pd, pa, 'include', '%sconf.h' % pkg) 156f46a955bSLisandro Dalcin # 157f46a955bSLisandro Dalcin include_dirs = [] 1580f51ee0fSAlexei Colin numpy_include = os.environ.get('NUMPY_INCLUDE') 1590f51ee0fSAlexei Colin if numpy_include is not None: 1600f51ee0fSAlexei Colin numpy_includes = [numpy_include] 1610f51ee0fSAlexei Colin else: 1625808f684SSatish Balay try: 1635808f684SSatish Balay import numpy 1645808f684SSatish Balay numpy_includes = [numpy.get_include()] 1655808f684SSatish Balay except ImportError: 1665808f684SSatish Balay numpy_includes = [] 167f46a955bSLisandro Dalcin include_dirs.extend(numpy_includes) 168f46a955bSLisandro Dalcin if F('{pyname}') != 'petsc4py': 169f46a955bSLisandro Dalcin try: 170f46a955bSLisandro Dalcin import petsc4py 171f46a955bSLisandro Dalcin petsc4py_includes = [petsc4py.get_include()] 172f46a955bSLisandro Dalcin except ImportError: 173f46a955bSLisandro Dalcin petsc4py_includes = [] 174f46a955bSLisandro Dalcin include_dirs.extend(petsc4py_includes) 175f46a955bSLisandro Dalcin # 176f46a955bSLisandro Dalcin ext = dict( 177f46a955bSLisandro Dalcin name=F('{pyname}.lib.{Name}'), 178f46a955bSLisandro Dalcin sources=[F('src/{pyname}/{Name}.c')], 179fb83dddaSLisandro Dalcin depends=depends, 180fb83dddaSLisandro Dalcin include_dirs=[ 181f46a955bSLisandro Dalcin 'src', 182f46a955bSLisandro Dalcin F('src/{pyname}/include'), 183f46a955bSLisandro Dalcin ] + include_dirs, 184fb83dddaSLisandro Dalcin define_macros=[ 185fb83dddaSLisandro Dalcin ('MPICH_SKIP_MPICXX', 1), 186fb83dddaSLisandro Dalcin ('OMPI_SKIP_MPICXX', 1), 187f46a955bSLisandro Dalcin ('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION'), 188fb83dddaSLisandro Dalcin ], 189fb83dddaSLisandro Dalcin ) 190f46a955bSLisandro Dalcin return [ext] 1915808f684SSatish Balay 1925808f684SSatish Balay# -------------------------------------------------------------------- 1935808f684SSatish Balay# Setup 1945808f684SSatish Balay# -------------------------------------------------------------------- 1955808f684SSatish Balay 196f8c80548SLisandro Dalcindef get_release(): 197f46a955bSLisandro Dalcin suffix = os.path.join('src', 'binding', F('{pyname}')) 198f46a955bSLisandro Dalcin if not topdir.endswith(os.path.join(os.path.sep, suffix)): 199*f09792b6SLisandro Dalcin return True 200f8c80548SLisandro Dalcin release = 1 201f8c80548SLisandro Dalcin rootdir = os.path.abspath(os.path.join(topdir, *[os.path.pardir]*3)) 202f46a955bSLisandro Dalcin version_h = os.path.join(rootdir, 'include', F('{name}version.h')) 203f46a955bSLisandro Dalcin release_macro = '%s_VERSION_RELEASE' % F('{name}').upper() 204f8c80548SLisandro Dalcin version_re = re.compile(r"#define\s+%s\s+([-]*\d+)" % release_macro) 205f8c80548SLisandro Dalcin if os.path.exists(version_h) and os.path.isfile(version_h): 206f8c80548SLisandro Dalcin with open(version_h, 'r') as f: 207f8c80548SLisandro Dalcin release = int(version_re.search(f.read()).groups()[0]) 208f8c80548SLisandro Dalcin return bool(release) 209f8c80548SLisandro Dalcin 210f8c80548SLisandro Dalcindef requires(pkgname, major, minor, release=True): 211f8c80548SLisandro Dalcin minor = minor + int(not release) 212f8c80548SLisandro Dalcin devel = '' if release else '.dev0' 213f8c80548SLisandro Dalcin vmin = "%s.%s%s" % (major, minor, devel) 214f8c80548SLisandro Dalcin vmax = "%s.%s" % (major, minor + 1) 215f8c80548SLisandro Dalcin return "%s>=%s,<%s" % (pkgname, vmin, vmax) 216f8c80548SLisandro Dalcin 2175808f684SSatish Balaydef run_setup(): 2185808f684SSatish Balay setup_args = metadata.copy() 219f8c80548SLisandro Dalcin vstr = setup_args['version'].split('.')[:2] 220f8c80548SLisandro Dalcin x, y = tuple(map(int, vstr)) 221f8c80548SLisandro Dalcin release = get_release() 222f8c80548SLisandro Dalcin if not release: 223f8c80548SLisandro Dalcin setup_args['version'] = "%d.%d.0.dev0" %(x, y+1) 2245808f684SSatish Balay if setuptools: 2255808f684SSatish Balay setup_args['zip_safe'] = False 2265808f684SSatish Balay setup_args['install_requires'] = ['numpy'] 227f46a955bSLisandro Dalcin for pkg in map(str.lower, PLIST): 228f46a955bSLisandro Dalcin PKG_DIR = os.environ.get(pkg.upper() + '_DIR') 229f46a955bSLisandro Dalcin if not (PKG_DIR and os.path.isdir(PKG_DIR)): 230f46a955bSLisandro Dalcin package = requires(pkg, x, y, release) 231f46a955bSLisandro Dalcin setup_args['install_requires'] += [package] 232f46a955bSLisandro Dalcin if F('{pyname}') != 'petsc4py': 233f46a955bSLisandro Dalcin package = requires('petsc4py', x, y, release) 234f46a955bSLisandro Dalcin setup_args['install_requires'] += [package] 235fb83dddaSLisandro Dalcin setup_args.update(metadata_extra) 2365808f684SSatish Balay # 237f46a955bSLisandro Dalcin conf = __import__(F('conf{name}')) 238f46a955bSLisandro Dalcin conf.setup( 239fb83dddaSLisandro Dalcin packages=[ 240f46a955bSLisandro Dalcin F('{pyname}'), 241f46a955bSLisandro Dalcin F('{pyname}.lib'), 242fb83dddaSLisandro Dalcin ], 243f46a955bSLisandro Dalcin package_dir={'' : 'src'}, 244fb83dddaSLisandro Dalcin package_data={ 245f46a955bSLisandro Dalcin F('{pyname}'): [ 246f46a955bSLisandro Dalcin F('{Name}.pxd'), 247f46a955bSLisandro Dalcin F('{Name}*.h'), 248f46a955bSLisandro Dalcin F('include/{pyname}/*.h'), 249f46a955bSLisandro Dalcin F('include/{pyname}/*.i'), 250fb83dddaSLisandro Dalcin ], 251f46a955bSLisandro Dalcin F('{pyname}.lib'): [ 252f46a955bSLisandro Dalcin F('{name}.cfg'), 253fb83dddaSLisandro Dalcin ], 254fb83dddaSLisandro Dalcin }, 255f46a955bSLisandro Dalcin cython_sources=[ 256f46a955bSLisandro Dalcin src for src in sources() 257f46a955bSLisandro Dalcin ], 258f46a955bSLisandro Dalcin ext_modules=[ 259f46a955bSLisandro Dalcin conf.Extension(**ext) for ext in extensions() 260f46a955bSLisandro Dalcin ], 261f46a955bSLisandro Dalcin **setup_args 262fb83dddaSLisandro Dalcin ) 2635808f684SSatish Balay 264fb83dddaSLisandro Dalcin# -------------------------------------------------------------------- 265fb83dddaSLisandro Dalcin 2665808f684SSatish Balaydef main(): 2675808f684SSatish Balay run_setup() 2685808f684SSatish Balay 2695808f684SSatish Balayif __name__ == '__main__': 2705808f684SSatish Balay main() 2715808f684SSatish Balay 2725808f684SSatish Balay# -------------------------------------------------------------------- 273