1#!/usr/bin/env python 2 3""" 4TAO: Toolkit for Advanced Optimization 5====================================== 6 7The Toolkit for Advanced Optimization (TAO) is aimed at the solution 8of large-scale optimization problems on high-performance 9architectures. Its main goals are portability, performance, scalable 10parallelism, and an interface independent of the architecture. TAO is 11suitable for both single-processor and massively-parallel 12architectures. 13 14.. tip:: 15 16 You can also install `tao-dev`_ with:: 17 18 $ pip install petsc==dev tao==dev 19 20 .. _tao-dev: http://bitbucket.org/sarich/tao-devel/ 21 get/tip.tar.gz#egg=tao-dev 22""" 23 24import sys, os 25from distutils.core import setup 26from distutils.util import get_platform 27from distutils.spawn import find_executable 28from distutils.command.build import build as _build 29if 'setuptools' in sys.modules: 30 from setuptools.command.install import install as _install 31else: 32 from distutils.command.install import install as _install 33from distutils.command.sdist import sdist as _sdist 34from distutils import log 35 36init_py = """\ 37# Author: TAO Team 38# Contact: tao-comments@mcs.anl.gov 39 40def get_tao_dir(): 41 import os 42 return os.path.dirname(__file__) 43 44def get_config(): 45 conf = {} 46 conf['TAO_DIR'] = get_tao_dir() 47 return conf 48""" 49 50metadata = { 51 'provides' : ['tao'], 52 'requires' : [], 53} 54 55def bootstrap(): 56 from os.path import join, isdir, abspath 57 # Set TAO_DIR 58 TAO_DIR = abspath(os.getcwd()) 59 os.environ['TAO_DIR'] = TAO_DIR 60 # Check PETSC_DIR/PETSC_ARCH 61 PETSC_DIR = os.environ.get('PETSC_DIR', "") 62 PETSC_ARCH = os.environ.get('PETSC_ARCH', "") 63 if not (PETSC_DIR and isdir(PETSC_DIR)): 64 PETSC_DIR = None 65 try: del os.environ['PETSC_DIR'] 66 except KeyError: pass 67 PETSC_ARCH = None 68 try: del os.environ['PETSC_ARCH'] 69 except KeyError: pass 70 elif not isdir(join(PETSC_DIR, PETSC_ARCH)): 71 PETSC_ARCH = None 72 try: del os.environ['PETSC_ARCH'] 73 except KeyError: pass 74 # Generate package __init__.py file 75 from distutils.dir_util import mkpath 76 pkgdir = os.path.join(TAO_DIR, 'pypi') 77 pkgfile = os.path.join(pkgdir, '__init__.py') 78 if not os.path.exists(pkgdir): mkpath(pkgdir) 79 fh = open(pkgfile, 'wt') 80 fh.write(init_py) 81 fh.close() 82 if ('setuptools' in sys.modules): 83 metadata['zip_safe'] = False 84 if not PETSC_DIR: 85 metadata['install_requires']= ['petsc>=3.3,<3.4'] 86 87def get_petsc_dir(): 88 PETSC_DIR = os.environ.get('PETSC_DIR') 89 if PETSC_DIR: return PETSC_DIR 90 try: 91 import petsc 92 PETSC_DIR = petsc.get_petsc_dir() 93 except ImportError: 94 log.warn("PETSC_DIR not specified") 95 PETSC_DIR = os.path.join(os.path.sep, 'usr', 'local', 'petsc') 96 return PETSC_DIR 97 98def get_petsc_arch(): 99 PETSC_ARCH = os.environ.get('PETSC_ARCH') or '' 100 return PETSC_ARCH 101 102def config(dry_run=False): 103 log.info('TAO: configure') 104 if dry_run: return 105 # Run TAO configure 106 os.environ['PETSC_DIR'] = get_petsc_dir() 107 status = 0#os.system("./configure") 108 if status != 0: raise RuntimeError(status) 109 110def build(dry_run=False): 111 log.info('TAO: build') 112 if dry_run: return 113 # Run TAO build 114 status = os.system(" ".join(( 115 find_executable('make'), 116 'PETSC_DIR='+get_petsc_dir(), 117 'PETSC_ARCH='+get_petsc_arch(), 118 'all', 119 ))) 120 if status != 0: raise RuntimeError 121 122def install(dest_dir, prefix=None, dry_run=False): 123 log.info('TAO: install') 124 if dry_run: return 125 TAO_DIR = os.environ['TAO_DIR'] 126 PETSC_ARCH = get_petsc_arch() 127 # Run TAO install (python) 128 from distutils.file_util import copy_file 129 from distutils.dir_util import copy_tree 130 copy_tree(os.path.join(TAO_DIR, 'include'), 131 os.path.join(dest_dir, 'include')) 132 copy_tree(os.path.join(TAO_DIR, 'conf'), 133 os.path.join(dest_dir, 'conf')) 134 copy_tree(os.path.join(TAO_DIR, PETSC_ARCH, 'lib'), 135 os.path.join(dest_dir, 'lib')) 136 # remove bad files 137 badfiles = [os.path.join(dest_dir, 'conf', 'install.py')] 138 for dirname, _, filenames in os.walk( 139 os.path.join(dest_dir, 'include')): 140 badfiles += [os.path.join(dirname, f) 141 for f in filenames 142 if f.endswith('.html')] 143 for filename in badfiles: 144 fullpath = os.path.join(dirname, filename) 145 try: 146 os.remove(fullpath) 147 log.info("removing %s", fullpath) 148 except: 149 pass 150 151class context: 152 def __init__(self): 153 self.sys_argv = sys.argv[:] 154 self.wdir = os.getcwd() 155 def enter(self): 156 del sys.argv[1:] 157 pdir = os.environ['TAO_DIR'] 158 os.chdir(pdir) 159 return self 160 def exit(self): 161 sys.argv[:] = self.sys_argv 162 os.chdir(self.wdir) 163 164class cmd_build(_build): 165 166 def initialize_options(self): 167 _build.initialize_options(self) 168 PETSC_ARCH = get_petsc_arch() 169 self.build_base = os.path.join(PETSC_ARCH, 'build-python') 170 171 def run(self): 172 _build.run(self) 173 ctx = context().enter() 174 try: 175 config(self.dry_run) 176 build(self.dry_run) 177 finally: 178 ctx.exit() 179 180class cmd_install(_install): 181 182 def initialize_options(self): 183 _install.initialize_options(self) 184 self.optimize = 1 185 186 def run(self): 187 root_dir = self.install_platlib 188 dest_dir = os.path.join(root_dir, 'tao') 189 bdist_base = self.get_finalized_command('bdist').bdist_base 190 if dest_dir.startswith(bdist_base): 191 prefix = dest_dir[len(bdist_base)+1:] 192 prefix = prefix[prefix.index(os.path.sep):] 193 else: 194 prefix = dest_dir 195 dest_dir = os.path.abspath(dest_dir) 196 prefix = os.path.abspath(prefix) 197 # 198 _install.run(self) 199 ctx = context().enter() 200 try: 201 install(dest_dir, prefix, self.dry_run) 202 finally: 203 ctx.exit() 204 205manifest_in = """\ 206include makefile LICENSE 207 208recursive-include include * 209recursive-include src * 210recursive-include conf * 211 212recursive-exclude include *.html 213recursive-exclude src *.html 214recursive-exclude src/*/examples/* *.* 215recursive-exclude pypi *.* 216""" 217 218class cmd_sdist(_sdist): 219 220 def initialize_options(self): 221 _sdist.initialize_options(self) 222 self.force_manifest = 1 223 self.template = os.path.join('pypi', 'manifest.in') 224 # Generate manifest.in file 225 from distutils.dir_util import mkpath 226 TAO_DIR = os.environ['TAO_DIR'] 227 pkgdir = os.path.join(TAO_DIR, 'pypi') 228 if not os.path.exists(pkgdir): mkpath(pkgdir) 229 template = self.template 230 fh = open(template, 'wt') 231 fh.write(manifest_in) 232 fh.close() 233 234def version(): 235 import re 236 version_re = { 237 'major' : re.compile(r"#define\s+TAO_VERSION_MAJOR\s+(\d+)"), 238 'minor' : re.compile(r"#define\s+TAO_VERSION_MINOR\s+(\d+)"), 239 'micro' : re.compile(r"#define\s+TAO_VERSION_SUBMINOR\s+(\d+)"), 240 'patch' : re.compile(r"#define\s+TAO_VERSION_PATCH\s+(\d+)"), 241 'release': re.compile(r"#define\s+TAO_VERSION_RELEASE\s+(\d+)"), 242 } 243 taoversion_h = os.path.join('include','tao_version.h') 244 data = open(taoversion_h, 'rt').read() 245 major = int(version_re['major'].search(data).groups()[0]) 246 minor = int(version_re['minor'].search(data).groups()[0]) 247 micro = int(version_re['micro'].search(data).groups()[0]) 248 patch = int(version_re['patch'].search(data).groups()[0]) 249 release = int(version_re['release'].search(data).groups()[0]) 250 if release: 251 v = "%d.%d" % (major, minor) 252 if micro > 0: 253 v += ".%d" % micro 254 if patch > 0: 255 v += ".%d" % patch 256 else: 257 v = "%d.%d.dev%d" % (major, minor+1, 0) 258 return v 259 260def tarball(): 261 VERSION = version() 262 if '.dev' in VERSION: 263 return None 264 bits = VERSION.split('.') 265 if len(bits) == 2: bits.append('0') 266 TAO_VERSION = '.'.join(bits[:-1]) + '-p' + bits[-1] 267 return ('http://www.mcs.anl.gov/research/projects/tao/download/' 268 'tao-%s.tar.gz#egg=tao-%s' % (TAO_VERSION, VERSION)) 269 270description = __doc__.split('\n')[1:-1]; del description[1:3] 271classifiers = """ 272License :: OSI Approved 273Operating System :: POSIX 274Intended Audience :: Developers 275Intended Audience :: Science/Research 276Programming Language :: C 277Programming Language :: C++ 278Programming Language :: Fortran 279Programming Language :: Python 280Topic :: Scientific/Engineering 281Topic :: Software Development :: Libraries 282""" 283 284bootstrap() 285print tarball() 286setup(name='tao', 287 version=version(), 288 description=description.pop(0), 289 long_description='\n'.join(description), 290 classifiers= classifiers.split('\n')[1:-1], 291 keywords = ['TAO', 'PETSc', 'MPI'], 292 platforms=['POSIX'], 293 license='TAO', 294 295 url='http://www.mcs.anl.gov/tao/', 296 download_url=tarball(), 297 298 author='TAO Team', 299 author_email='tao-comments@mcs.anl.gov', 300 maintainer='Lisandro Dalcin', 301 maintainer_email='dalcinl@gmail.com', 302 303 packages = ['tao'], 304 package_dir = {'tao': 'pypi'}, 305 cmdclass={ 306 'build': cmd_build, 307 'install': cmd_install, 308 'sdist': cmd_sdist, 309 }, 310 **metadata) 311