1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# ============================================================================== 4# COPYRIGHT (C) 1991 - 2003 EDF R&D WWW.CODE-ASTER.ORG 5# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY 6# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY 7# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR 8# (AT YOUR OPTION) ANY LATER VERSION. 9# 10# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT 11# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF 12# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU 13# GENERAL PUBLIC LICENSE FOR MORE DETAILS. 14# 15# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE 16# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER, 17# 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE. 18# ============================================================================== 19 20# ----- differ messages translation 21 22 23def _(mesg): 24 return mesg 25 26import sys 27# ----- check for Python version 28if sys.hexversion < 0x030500F0: 29 print(_('This script requires Python 3.5 or higher, sorry!')) 30 sys.exit(4) 31 32from glob import glob 33import os 34import os.path as osp 35import time 36import re 37import tempfile 38import traceback 39import shutil 40from types import ModuleType 41from optparse import OptionParser 42import distutils.sysconfig as SC 43 44from as_setup import ( 45 SUMMARY, 46 SYSTEM, 47 DEPENDENCIES, 48 FIND_TOOLS, 49 check_pymodule, 50 should_continue, 51 should_continue_reg, 52 less_than_version, 53 get_install_message, 54 relative_symlink, 55 SetupError, 56) 57 58try: 59 from __pkginfo__ import dict_prod, dict_prod_param 60 short_version = '.'.join(dict_prod['aster'].split('.')[:2]) 61 available_products = dict_prod_param['__to_install__'] 62 numeric_version = tuple(map(int, dict_prod['aster'].split('.')[:2])) 63except (ImportError, KeyError) as msg: 64 print("File not found or invalid : '__pkginfo__.py'") 65 print("Error :") 66 print(msg) 67 sys.exit(4) 68 69import products 70import mprint 71 72python_version = '.'.join([str(n) for n in sys.version_info[:3]]) 73pythonXY = 'python' + '.'.join([str(n) for n in sys.version_info[:2]]) 74PY3 = sys.version_info.major >= 3 75 76log_file = 'setup.log' 77log = mprint.MPRINT(log_file, 'w') 78 79 80def product_alias(product): 81 return re.sub("[\-\+\.]+", "_", product) 82 83 84def main(): 85 #------------------------------------------------------------------------------- 86 # 0. initialisation, configuration of the command-line parser 87 #------------------------------------------------------------------------------- 88 # 0.1. ----- list of products to install (could be skip through cfg) 89 t_ini = time.time() 90 to_install_ordered = ['hdf5', 'med', 91 'scotch', 92 'astk', 'metis', 'tfel', 93 'mumps', 94 'homard', 95 'aster'] 96 to_install = [ 97 prod for prod in to_install_ordered if prod in available_products] 98 99 __aster_version__ = short_version 100 101 # 0.2. ----- version 102 import __pkginfo__ 103 104 svers = os.linesep.join(['Code_Aster Setup version ' + 105 __pkginfo__.version + '-' + __pkginfo__.release, __pkginfo__.copyright]) 106 107 usage = "usage: python %prog [options] [install|test] [arg]\n" + \ 108 _(""" 109 110 Setup script for Code_Aster distribution. 111 112 NOTE : Code_Aster or eventually other products will be configured with 113 the Python you use to run this setup : 114 interpreter : %(interp)s (version %(vers)s) 115 prefix : %(prefix)s 116 117 arguments : 118 action : only 'install' or 'test'. 119 120 By default all products are installed, but you can install only one (if a 121 first attempt failed). Example : python setup.py install aster. 122 123 Available products (the order is important) : 124 %(prod)s.""") % { 125 'vers': python_version, 126 'prefix': os.path.abspath(sys.prefix), 127 'interp': sys.executable, 128 'prod': ', '.join(to_install), 129 } 130 131 _separ = '\n' + '-' * 80 + '\n' 132 _fmt_err = _(' *** Exception raised : %s') 133 _fmt_search = _('Checking for %s... ') 134 135 log._print(_separ, svers, _separ) 136 137 scmd = """Command line :\n %s""" % ' '.join([sys.executable] + sys.argv) 138 log._print(_separ, scmd, _separ) 139 140 # 0.3. ----- command line parser 141 parser = OptionParser( 142 usage=usage, 143 version='Code_Aster Setup version ' + __pkginfo__.version + '-' + __pkginfo__.release) 144 parser.add_option("--prefix", dest="prefix", action='store', 145 help=_("define toplevel directory for Code_Aster (identical to --aster_root)"), metavar="DIR") 146 parser.add_option("--aster_root", dest="ASTER_ROOT", action='store', 147 # default='/opt/aster', not here ! 148 help=_("define toplevel directory for Code_Aster (default '/opt/aster')"), metavar="DIR") 149 parser.add_option("--sourcedir", dest="SOURCEDIR", action='store', 150 # default='./SRC', not here ! 151 help=_( 152 "directory which contains archive files (default './SRC')"), 153 metavar="DIR") 154 parser.add_option("--cfg", dest="fcfg", action='store', metavar="FILE", 155 help=_("file which contains the installation parameters"),) 156 parser.add_option("--nocache", dest="cache", action='store_false', 157 default=True, 158 help=_("delete cache file before starting (it's default if you do not specify a product name)"),) 159 parser.add_option("--ignore_error", dest="ign_err", action='store_true', 160 default=False, 161 help=_("ignore error when checking prerequisites"),) # same as the old --force option 162 parser.add_option("--reinstall", dest="reinstall", action='store', 163 default='ask', 164 help=_("tell what to do if a product is already installed: force, ignore, ask " 165 "('force' reinstalls the product, 'ignore' keeps the current one, 'ask' prompts " 166 "for each product)"),) 167 parser.add_option("-q", "--quiet", dest="verbose", action='store_false', 168 default=True, 169 help=_("turn off verbose mode"),) 170 parser.add_option("-g", "--debug", dest="debug", action='store_true', 171 default=False, 172 help=_("turn on debug mode"),) 173 parser.add_option("--noprompt", dest="noprompt", action='store_true', 174 default=False, 175 help=_("do not ask any questions"),) 176 177 opts, args = parser.parse_args() 178 fcfg = opts.fcfg 179 verbose = opts.verbose 180 debug = opts.debug 181 noprompt = opts.noprompt 182 should_continue_reg(noprompt) 183 184 main_script = sys.argv[0] 185 setup_maindir = os.path.normpath( 186 os.path.dirname(os.path.abspath(main_script))) 187 188 default_cfgfile = os.path.join(setup_maindir, 'setup.cfg') 189 cache_file = os.path.join(setup_maindir, 'setup.cache') 190 191 def_opts = { 192 'ASTER_ROOT': '/opt/aster', 193 'SOURCEDIR': os.path.normpath(os.path.join(setup_maindir, 'SRC')), 194 } 195 if opts.prefix is not None and opts.ASTER_ROOT is None: 196 opts.ASTER_ROOT = opts.prefix 197 198 # 0.4. ----- check for argument value 199 _install = True 200 _test = False 201 if len(args) > 0: 202 if args[0] == 'install': 203 pass 204 elif args[0] == 'test': 205 _test = True 206 elif args[0] == 'clean': 207 for fname in glob(log_file + '*') + glob('setup.dbg*') \ 208 + glob('*.pyc') + glob(cache_file): 209 print(_("remove %s") % fname) 210 os.remove(fname) 211 print(_("temporary files deleted!")) 212 return 213 else: 214 parser.error(_("unexpected argument %s") % repr(args[0])) 215 if opts.reinstall not in ('force', 'ignore', 'ask'): 216 parser.error(_("--reinstall must be one of 'force', 'ignore' or 'ask'. " 217 "'%s' is not allowed") % opts.reinstall) 218 219 # 0.5. ----- adjust to_install list 220 to_install0 = to_install[:] 221 if len(args) > 1: 222 arg0 = args.pop(0) 223 for p in to_install[:]: 224 if not p in args: 225 to_install.remove(p) 226 227 # 0.6. ----- list of exceptions to handle during installation 228 if not debug: 229 safe_exceptions = (SetupError,) 230 else: 231 safe_exceptions = None 232 233 #------------------------------------------------------------------------------- 234 # 1. fill cfg reading setup.cfg + setup.cache files 235 #------------------------------------------------------------------------- 236 cfg = {} 237 cfg_init_keys = [] 238 # 1.1.1. ----- read parameters from 'fcfg' 239 if fcfg == None and os.path.isfile(default_cfgfile): 240 fcfg = default_cfgfile 241 if fcfg != None: 242 fcfg = os.path.expanduser(fcfg) 243 if not os.path.isfile(fcfg): 244 log._print(_('file not found %s') % fcfg) 245 sys.exit(4) 246 else: 247 log._print(_separ, _('Reading config file %s...' % repr(fcfg))) 248 context = {} 249 try: 250 exec(compile(open(fcfg).read(), fcfg, 'exec'), context) 251 except: 252 traceback.print_exc() 253 log._print(_separ, term='') 254 raise SetupError(_("reading '%s' failed (probably syntax" 255 " error occured, see traceback above)") % fcfg) 256 for k, v in list(context.items()): 257 if re.search('^__', k) == None and not type(v) is ModuleType: 258 cfg[k] = v 259 cfg_init_keys.append(k) 260 log._print(_(' %15s (from cfg) : %s') % (k, repr(v))) 261 262 # 1.1.2. ----- read cache file 263 # delete it if --nocache or to_install list is full. 264 if (not opts.cache or to_install == to_install0) and os.path.exists(cache_file): 265 log._print(_separ, _('Deleting cache file %s...' % repr(cache_file))) 266 os.remove(cache_file) 267 if os.path.exists(cache_file): 268 if fcfg != None and os.stat(fcfg).st_ctime > os.stat(cache_file).st_ctime: 269 log._print(_separ, _(""" WARNING : %(cfg)s is newer than %(cache)s. 270 The modifications you made in %(cfg)s might be overriden with 271 cached values. If errors occur delete %(cache)s and restart at 272 the beginning !""") 273 % {'cfg': repr(fcfg), 'cache': repr(cache_file)}, _separ) 274 should_continue() 275 log._print(_separ, _('Reading cache file %s...' % repr(cache_file))) 276 context = {} 277 try: 278 exec(compile(open(cache_file).read(), cache_file, 'exec'), context) 279 except: 280 traceback.print_exc() 281 log._print(_separ, term='') 282 raise SetupError( 283 _("reading '%s' failed (probably syntax error occured)") % cache_file) 284 os.remove(cache_file) 285 lk = list(context.keys()) 286 lk.sort() 287 for k in lk: 288 v = context[k] 289 if re.search('^__', k) == None and not type(v) is ModuleType: 290 cfg[k] = v 291 if not k in cfg_init_keys: 292 cfg_init_keys.append(k) 293 log._print(_(' %15s (from cache) : %s') % (k, repr(v))) 294 295 # 1.1.3. ----- list of options to put in cfg 296 for o in ('ASTER_ROOT', 'SOURCEDIR',): 297 if getattr(opts, o) is not None: 298 cfg[o] = os.path.normpath(os.path.abspath(getattr(opts, o))) 299 log._print(_separ, _(' %15s (from arguments) : %s') % (o, cfg[o])) 300 elif o not in cfg: 301 cfg[o] = def_opts[o] 302 # if all options are not directories write a different loop 303 cfg[o] = os.path.abspath(os.path.expanduser(cfg[o])) 304 305 # 1.2. ----- start a wizard 306 # ... perhaps one day ! 307 os.environ['ASTER_ROOT'] = cfg['ASTER_ROOT'] 308 309 # 1.3.1. ----- configure standard directories 310 # {bin,lib,inc}dirs are used to search files 311 # Search first from ASTER_ROOT/public/{bin,lib,include} 312 # and ASTER_ROOT/public is added for recursive search. 313 bindirs = [os.path.join(cfg['ASTER_ROOT'], 'public', 'bin'), 314 os.path.join(cfg['ASTER_ROOT'], 'public'), ] 315 bindirs.extend(os.environ.get('PATH', '').strip(':').split(':')) 316 bindirs.extend(['/usr/local/bin', '/usr/bin', '/bin', 317 '/usr/X11R6/bin', '/usr/bin/X11', '/usr/openwin/bin', ]) 318 319 libdirs = [os.path.join(cfg['ASTER_ROOT'], 'public', 'lib'), 320 os.path.join(cfg['ASTER_ROOT'], 'public'), ] 321 libdirs.extend(os.environ.get('LD_LIBRARY_PATH', '').strip(':').split(':')) 322 libdirs.extend(['/usr/local/lib', '/usr/lib', '/lib', 323 '/usr/lib/x86_64-linux-gnu', 324 '/usr/X11R6/lib', '/usr/lib/X11', '/usr/openwin/lib', ]) 325 326 incdirs = [os.path.join(cfg['ASTER_ROOT'], 'public', 'include'), 327 os.path.join(cfg['ASTER_ROOT'], 'public'), ] 328 incdirs.extend(os.environ.get('INCLUDE', '').split(':')) 329 incdirs.extend(['/usr/local/include', '/usr/include', '/include', 330 '/usr/X11R6/include', '/usr/include/X11', '/usr/openwin/include', ]) 331 332 # 1.3.2. ----- convert uname value to Code_Aster terminology... 333 sysname, nodename, release, version, machine = os.uname() 334 log._print('Architecture : os.uname = %s' % str(os.uname()), DBG=True) 335 plt = sys.platform 336 log._print('Architecture : sys.platform = %s os.name = %s' % 337 (plt, os.name), DBG=True) 338 339 sident = ' '.join(os.uname()) 340 if os.path.isfile('/etc/issue'): 341 sident = re.sub(r'\\.', '', open('/etc/issue', 'r').read()) + sident 342 log._print(_separ, """Installation on :\n%s""" % sident, _separ) 343 344 common_libs = ['pthread', 'z'] 345 cfg['PLATFORM'] = plt 346 if plt.startswith('linux'): 347 plt = 'linux' 348 if plt == 'win32': 349 cfg['IFDEF'] = 'WIN32' 350 elif plt in ('linux', 'cygwin'): 351 cfg['ARCH'] = 'x86' 352 if machine.endswith('64'): 353 cfg['IFDEF'] = 'LINUX64' 354 if machine in ('x86_64', 'ia64', 'ppc64'): 355 cfg['ARCH'] = machine 356 else: # force to x86_64 357 cfg['ARCH'] = 'x86_64' 358 else: 359 cfg['IFDEF'] = 'LINUX' 360 elif plt == 'darwin': 361 cfg['ARCH'] = 'x86' 362 if machine.endswith('64'): 363 cfg['IFDEF'] = 'DARWIN64' 364 if machine in ('x86_64', 'ia64', 'ppc64'): 365 cfg['ARCH'] = machine 366 else: # force to x86_64 367 cfg['ARCH'] = 'x86_64' 368 else: 369 cfg['IFDEF'] = 'DARWIN' 370 elif plt.startswith('freebsd'): 371 common_libs = [] 372 cfg['IFDEF'] = 'FREEBSD' 373 cfg['ARCH'] = 'x86' 374 if machine.endswith('64'): 375 if machine in ('x86_64', 'ia64', 'ppc64'): 376 cfg['ARCH'] = machine 377 else: # force to x86_64 378 cfg['ARCH'] = 'x86_64' 379 elif plt.startswith('osf1'): 380 cfg['IFDEF'] = 'TRU64' 381 elif plt == 'sunos5': 382 cfg['IFDEF'] = 'SOLARIS' 383 # elif plt.startswith('irix64'): 384 # cfg['IFDEF']='IRIX64' 385 elif plt.startswith('irix'): 386 cfg['IFDEF'] = 'IRIX' 387 else: 388 raise SetupError(_("Unsupported platform : sys.platform=%s, os.name=%s") % 389 (sys.platform, os.name)) 390 if cfg.get('_solaris64', False) and plt == 'sunos5': 391 cfg['IFDEF'] = 'SOLARIS64' 392 cfg['DEFINED'] = cfg['IFDEF'] 393 394 # ----- insert 'lib64' at the beginning on 64 bits platforms 395 if cfg['IFDEF'].endswith('64'): 396 libdirs = [path.replace('lib', 'lib64') for path in libdirs 397 if path.find('lib') > -1 and path.find('lib64') < 0] + libdirs 398 bindirs = cfg.get('BINDIR', []) + bindirs 399 libdirs = cfg.get('LIBDIR', []) + libdirs 400 incdirs = cfg.get('INCLUDEDIR', []) + incdirs 401 402 # 1.3.3. ----- variables with predefined value 403 cfg['ASTER_VERSION'] = cfg.get('ASTER_VERSION', __aster_version__) 404 cfg['ASTER_NUMVERS'] = numeric_version 405 cfg['ASTER_VERSLABEL'] = cfg.get('ASTER_VERSLABEL', 406 dict_prod_param['aster-verslabel']) 407 408 cfg['NODE'] = cfg.get('NODE', nodename.split('.')[0]) 409 410 cfg['HOME_PYTHON'] = cfg.get('HOME_PYTHON', os.path.abspath(sys.prefix)) 411 cfg['PYTHON_EXE'] = cfg.get('PYTHON_EXE', sys.executable) 412 cfg['PYTHON_XY'] = pythonXY.lstrip('python') # only major.minor 413 # these directories should respectively contain shared and static 414 # librairies 415 pylib = SC.get_python_lib(standard_lib=True) 416 # python modules location 417 cfg['PYTHONPATH'] = cfg.get('PYTHONPATH', '') 418 cfg['OPT_ENV'] = cfg.get('OPT_ENV', '') 419 420 #------------------------------------------------------------------------------- 421 # 1.4. ----- auto-configuration 422 #------------------------------------------------------------------------- 423 log._print(_separ, term='') 424 425 # 1.4.0. ----- checking for maximum command line length (as configure does) 426 log._print(_fmt_search % _('max command length'), term='') 427 system = SYSTEM({'verbose': verbose, 'debug': False}, 428 **{'maxcmdlen': 2 ** 31, 'log': log}) 429 system.AddToEnv(cfg['OPT_ENV'], verbose=False) 430 default_value = 1024 431 lenmax = 0 432 i = 0 433 teststr = 'ABCD' 434 iret = 0 435 while iret == 0: 436 i += 1 437 cmd = 'echo ' + teststr 438 iret, out = system.local_shell(cmd, verbose=False) 439 out = out.replace('\n', '') 440 if len(out) != len(teststr) or len(teststr) > 2 ** 16: 441 lenmax = len(teststr) / 2 442 break 443 teststr = teststr * 2 444 # Add a significant safety factor because C++ compilers can tack on massive 445 # amounts of additional arguments before passing them to the linker. 446 # It appears as though 1/2 is a usable value. 447 system.MaxCmdLen = max(default_value, lenmax / 2) 448 log._print(system.MaxCmdLen) 449 cfg['MAXCMDLEN'] = system.MaxCmdLen 450 system.debug = debug 451 452 # ----- initialize DEPENDENCIES object 453 dep = DEPENDENCIES( 454 cfg=cfg, 455 cache=cache_file, 456 debug=debug, 457 system=system, 458 log=log) 459 460 # ----- initialize FIND_TOOLS object 461 ftools = FIND_TOOLS(log=log, 462 maxdepth=cfg.get('MAXDEPTH', 5), 463 use_locate=cfg.get('USE_LOCATE', False), 464 prefshared=cfg.get('PREFER_SHARED_LIBS', False), 465 debug=debug, 466 system=system, 467 arch=cfg.get('ARCH'), 468 bindirs=bindirs, 469 libdirs=libdirs, 470 incdirs=incdirs, 471 noerror=_test) 472 473 # 1.4.0a. ----- system info 474 ftools.check( 475 ' '.join([sysname, '/', os.name, '/', cfg['ARCH']]), 'architecture') 476 ftools.get_cpu_number() 477 ftools.check(cfg['IFDEF'], 'Code_Aster platform type') 478 479 # 1.4.1a. ----- checking for shell script interpreter 480 ftools.find_and_set( 481 cfg, 'SHELL_EXECUTION', ['bash', 'ksh', 'zsh'], err=False) 482 ftools.check(python_version, 'Python version') 483 484 pylibrary = ftools.findlib_and_set(cfg, 'PYTHON_LIBRARY', 485 [pythonXY, pythonXY + "m"], 486 paths=[pylib], prefshared=True, err=True) 487 cfg['PYTHON_LIBRARY'] = pylibrary 488 cfg['PYTHON_LIBRARY_DIR'] = osp.dirname(pylibrary) 489 pyinc = ftools.find_and_set(cfg, 'PYTHON_INCLUDE', "Python.h", typ='inc', 490 paths=[osp.join(cfg['HOME_PYTHON'], 'include', 491 pythonXY)], 492 err=True) 493 cfg['PYTHON_INCLUDE'] = osp.dirname(pyinc) 494 cfg['PYTHON_ALIAS'] = '' 495 if PY3: 496 py3tmpdir = tempfile.mkdtemp() 497 os.symlink(cfg['PYTHON_EXE'], osp.join(py3tmpdir, "python")) 498 cfg['PYTHON_ALIAS'] = "export PATH={0}:${{PATH}}".format(py3tmpdir) 499 500 resp = ftools.pymod_exists("numpy") 501 if resp: 502 import numpy 503 cfg['PYPATH_NUMPY'] = cfg.get('PYPATH_NUMPY', 504 osp.dirname(numpy.__path__[0])) 505 else: 506 log._print("'import numpy' failed. Please check your numpy installation.") 507 508 # 1.4.1b. ----- check for popen/threading bug : 509 response = sys.hexversion >= 0x020700F0 510 cfg['MULTITHREADING'] = response 511 512 # 1.4.1d. ----- check for mpirun command 513 # ftools.find_and_set(cfg, 'MPIRUN', ['mpirun', 'prun'], err=False) 514 cfg['MPIRUN'] = cfg.get('MPIRUN', 'mpiexec') 515 516 # 1.4.1e. ----- check for gcc libraries path 517 cc = cfg.get('CC') 518 if cc is None or not ftools.check_compiler_name(cc, 'GCC'): 519 cc = 'gcc' 520 ftools.find_and_set(cfg, 'gcc', cc) 521 if cfg.get('gcc'): # for 'test' mode 522 ftools.GccPrintSearchDirs(cfg['gcc']) 523 524 # 1.4.1f. ----- check for system libraries 525 math_lib = cfg.get('MATH_LIST', []) 526 if not type(math_lib) in (list, tuple): 527 math_lib = [math_lib, ] 528 sys_lib = [] 529 for glob_lib in common_libs: 530 cfg['__tmp__'] = '' 531 del cfg['__tmp__'] 532 ftools.findlib_and_set( 533 cfg, '__tmp__', glob_lib, prefshared=True, err=False, silent=False) 534 if cfg.get('__tmp__'): 535 ftools.AddToCache('lib', glob_lib, cfg['__tmp__']) 536 sys_lib.append(glob_lib) 537 538 # 1.4.1g. ----- check for system dependent libraries (and only used by 539 # Code_Aster) 540 cfg['SYSLIB'] = cfg.get('SYSLIB', '') 541 aster_sys_lib = [] 542 if cfg['IFDEF'] in ('LINUX', 'P_LINUX', 'LINUX64'): 543 cfg['SYSLIB'] += ' -Wl,--allow-multiple-definition -Wl,--export-dynamic' 544 aster_sys_lib.extend(['dl', 'util', 'm']) 545 elif cfg['IFDEF'] == 'TRU64': 546 aster_sys_lib.extend('/usr/lib/libots3.a /usr/lib/libpthread.a /usr/lib/libnuma.a ' 547 '/usr/lib/libpset.a /usr/lib/libmach.a -lUfor -lfor -lFutil -lm ' 548 '-lots -lm_c32 -lmld /usr/ccs/lib/cmplrs/cc/libexc.a'.split()) 549 elif cfg['IFDEF'] == 'SOLARIS': 550 aster_sys_lib.extend( 551 ['socket', 'nsl', 'm', '/usr/lib/libintl.so.1', 'dl', 'c']) 552 elif cfg['IFDEF'] == 'SOLARIS64': 553 aster_sys_lib.extend(['socket', 'nsl', 'm', 'dl', 'c', 'm']) 554 elif cfg['IFDEF'] == 'IRIX': 555 aster_sys_lib.extend(['fpe', 'm']) 556 else: 557 pass 558 list_lib = [] 559 for glob_lib in aster_sys_lib: 560 cfg['__tmp__'] = '' 561 del cfg['__tmp__'] 562 ftools.findlib_and_set(cfg, '__tmp__', glob_lib, prefshared=True, 563 err=not opts.ign_err, silent=False) 564 if cfg.get('__tmp__'): 565 ftools.AddToCache('lib', glob_lib, cfg['__tmp__']) 566 list_lib.append(cfg['__tmp__']) 567 cfg['SYSLIB'] += ' ' + ' '.join(list_lib) 568 cfg['SYSLIB'] = cfg['SYSLIB'].strip() 569 570 # 1.4.2. ----- check for compilers 571 cfg_ini = cfg.copy() 572 dict_pref = dict([(k.replace('PREFER_COMPILER_', ''), v) 573 for k, v in list(cfg.items()) if k.startswith('PREFER_COMPILER')]) 574 if not dict_pref.get('PREFER_COMPILER'): 575 dict_pref['PREFER_COMPILER'] = 'GNU' 576 577 from check_compilers import COMPILER_MANAGER 578 compiler_manager = COMPILER_MANAGER(debug, print_func=log._print) 579 lkeys = list(dict_pref.keys()) 580 lkeys.sort() 581 log._print('PREFER_COMPILER keys : %s' % lkeys, DBG=True) 582 583 # general compiler options 584 compiler_option = [] 585 if cfg.get('USE_FPIC', True): 586 compiler_option.append('-fPIC') 587 588 for prod in lkeys: 589 prefcompiler = dict_pref[prod] 590 log._print(_separ, term='') 591 if prod == 'PREFER_COMPILER': 592 lprod = [p for p in list(dict_pref.keys()) if p != prod] 593 if len(lprod) > 0: 594 sprod = ' except %s' % ', '.join(lprod) 595 else: 596 sprod = '' 597 ftools.check(None, 'default compiler (for all products%s)' % sprod) 598 prod = '__main__' 599 else: 600 ftools.check(None, 'compiler for "%s"' % prod) 601 success = compiler_manager.check_compiler(name=prefcompiler, 602 product=prod, 603 system=system, ftools=ftools, 604 necessary=( 605 'CC', 'CXX', 'F90'), 606 init=cfg_ini, 607 platform=cfg['IFDEF'], 608 arch=cfg.get('ARCH', ''), 609 math_lib=math_lib, 610 sys_lib=sys_lib, 611 add_option=compiler_option) 612 if not success: 613 log._print(_separ, term='') 614 log._print(_('Unable to configure automatically %s compiler for "%s" product.') % 615 (prefcompiler.upper(), prod)) 616 return 617 else: 618 txt = compiler_manager.switch_in_dep( 619 dep, prod, system=system, verbose=True) 620 log._print( 621 os.linesep, 'Compiler variables (set as environment variables):', os.linesep) 622 log._print(txt) 623 if debug: 624 from pprint import pprint 625 pprint(compiler_manager.get_config(prod)) 626 627 # activate main compiler 628 compiler_manager.switch_in_dep( 629 dep, product='__main__', system=system, verbose=False) 630 631 # 1.4.3. ----- check for ps commands : 632 # PS_COMMAND_CPU returns (field 1) cputime and (field 2) command line 633 # PS_COMMAND_PID returns (field 1) pid and (field 2) command line 634 log._print(_separ, term='') 635 ftools.find_and_set(cfg, 'PS_COMMAND', 'ps', err=False) 636 ps_command = cfg.get('PS_COMMAND') 637 if ps_command != None: 638 if cfg['IFDEF'].find('SOLARIS') > -1: 639 cfg['PS_COMMAND_CPU'] = '%s -e -otime -oargs' % ps_command 640 cfg['PS_COMMAND_PID'] = '%s -e -opid -oargs' % ps_command 641 elif cfg['IFDEF'].find('IRIX') > -1 or cfg['IFDEF'] == 'TRU64': 642 cfg['PS_COMMAND_CPU'] = '%s -e -ocputime -ocommand' % ps_command 643 cfg['PS_COMMAND_PID'] = '%s -e -opid -ocommand' % ps_command 644 elif plt == 'darwin': 645 # per man page for Mac OS X (darwin) ps command 646 # if -w option is specified more than once, ps will use as many columns as necessary without 647 # regard for your window size. When output is not to a terminal, an unlimited number of 648 # columns are always used. 649 cfg['PS_COMMAND_CPU'] = '%s -e -w -w -ocputime -ocommand' % ps_command 650 cfg['PS_COMMAND_PID'] = '%s -e -w -w -opid -ocommand' % ps_command 651 else: 652 cfg['PS_COMMAND_CPU'] = '%s -e --width=512 -ocputime -ocommand' % ps_command 653 cfg['PS_COMMAND_PID'] = '%s -e --width=512 -opid -ocommand' % ps_command 654 655 # 1.4.4. ----- check for a terminal 656 ListTerm = [ 657 ['xterm', 'xterm -e @E', ], 658 ['gnome-terminal', 'gnome-terminal --command=@E', ], 659 ['konsole', 'konsole -e @E'], ] 660 for prg, cmd in ListTerm: 661 term = ftools.find_file(prg, typ='bin') 662 if term != None: 663 term = cmd.replace(prg, term) 664 break 665 # an empty string means no terminal for asrun 666 cfg['TERMINAL'] = cfg.get('TERMINAL', term) or "" 667 668 # 1.4.5. ----- check for a text editor 669 ListEdit = [ 670 ['nedit', 'nedit', ], 671 ['geany', 'geany', ], 672 ['gvim', 'gvim', ], 673 ['gedit', 'gedit', ], 674 ['kwrite', 'kwrite', ], 675 ['xemacs', 'xemacs', ], 676 ['emacs', 'emacs', ], 677 ['xedit', 'xedit', ], 678 ['vi', cfg.get('TERMINAL', 'xterm') + ' -e vi', ], ] 679 for prg, cmd in ListEdit: 680 edit = ftools.find_file(prg, typ='bin') 681 if edit != None: 682 edit = cmd.replace(prg, edit) 683 break 684 cfg['EDITOR'] = cfg.get('EDITOR', edit) or 'gedit' 685 686 # 1.4.6. ----- check for debugger 687 # DEBUGGER_COMMAND runs an interactive debugger 688 # DEBUGGER_COMMAND_POST dumps a post-mortem traceback 689 # @E will be remplaced by the name of the executable 690 # @C will be remplaced by the name of the corefile 691 # @D will be remplaced by the filename which contains "where+quit" 692 # @d will be remplaced by the string 'where ; quit' 693 cfg['DEBUGGER_COMMAND'] = '' 694 cfg['DEBUGGER_COMMAND_POST'] = '' 695 ListDebbuger = [ 696 ['gdb', '%s -batch --command=@D @E @C', ], 697 ['dbx', '%s -c @D @E @C', ], 698 ['ladebug', '%s -c @D @E @C', ], ] 699 for debugger, debugger_command_format in ListDebbuger: 700 debugger_command = ftools.find_file(debugger, typ='bin') 701 if debugger_command != None: 702 cfg['DEBUGGER_COMMAND_POST'] = debugger_command_format % debugger_command 703 break 704 705 if debugger_command != None: 706 ddd = ftools.find_file('ddd', typ='bin') 707 if ddd != None: 708 cfg['DEBUGGER_COMMAND'] = '%s --%s --debugger %s --command=@D @E @C' \ 709 % (ddd, debugger, debugger_command) 710 711 # 1.4.7. ----- check for utilities (for scotch) 712 ftools.find_and_set(cfg, 'FLEX', 'flex', err=False) 713 ftools.find_and_set(cfg, 'RANLIB', 'ranlib', err=False) 714 ftools.find_and_set(cfg, 'YACC', 'bison', err=False) 715 if cfg.get('YACC') and cfg.get('YACC', '').find('-y') < 0: 716 cfg['YACC'] += ' -y' 717 if not opts.ign_err and 'scotch' in to_install \ 718 and (not cfg.get('FLEX') or not cfg.get('RANLIB') or not cfg.get('YACC')): 719 to_install.remove('scotch') 720 721 # 1.4.8. ----- check for utilities (for tfel) 722 ftools.find_and_set(cfg, 'CMAKE', 'cmake', err=False) 723 if not opts.ign_err and 'tfel' in to_install and not cfg.get('CMAKE'): 724 log._print( 725 "\nWARNING: cmake is missing. You won't be able to install Mfront.") 726 to_install.remove('tfel') 727 728 #------------------------------------------------------------------------------- 729 # 1.5. ----- products configuration 730 #------------------------------------------------------------------------- 731 log._print(_separ, term='') 732 733 # 1.5.1. ----- check for hostname (for client part of astk) 734 log._print(_fmt_search % _('host name'), term='') 735 host = system.GetHostName() 736 # deduce domain name 737 tmp = host.split('.') 738 if len(tmp) > 1: 739 host = tmp[0] 740 domain = '.'.join(tmp[1:]) 741 else: 742 domain = '' 743 cfg['SERVER_NAME'] = cfg.get('SERVER_NAME', host) 744 cfg['DOMAIN_NAME'] = cfg.get('DOMAIN_NAME', domain) 745 cfg['FULL_SERVER_NAME'] = cfg.get('FULL_SERVER_NAME', '.'.join(tmp)) 746 domain = cfg['DOMAIN_NAME'] 747 if domain == '': 748 domain = '(empty)' 749 log._print(cfg['SERVER_NAME']) 750 log._print(_fmt_search % _('network domain name'), domain) 751 log._print(_fmt_search % 752 _('full qualified network name'), cfg['FULL_SERVER_NAME']) 753 754 # 1.5.2. ----- check boost 755 if cfg['ASTER_NUMVERS'] >= (15, 2): 756 boostlib = ftools.findlib_and_set( 757 cfg, 'unused_boost', 758 cfg.get("LIBNAME_BOOST", ["boost_python3", "boost_python3-mt"]), 759 paths=cfg.get("HOME_BOOST", ""), 760 prefshared=True, err=True) 761 path, base = osp.split(boostlib) 762 home = re.sub("/lib(64)?$", "", path) 763 name = re.sub("^lib", "", re.sub("\.so.*", "", base)) 764 cfg["HOME_BOOST"] = cfg.get("HOME_BOOST", home) 765 cfg["LIBNAME_BOOST"] = cfg.get("LIBNAME_BOOST", name) 766 cfg["LIBPATH_BOOST"] = cfg.get("LIBPATH_BOOST", path) 767 else: 768 cfg['HOME_BOOST'] = cfg.get('HOME_BOST', '') 769 cfg['LIBNAME_BOOST'] = cfg.get('LIBNAME_BOOST', '') 770 cfg["LIBPATH_BOOST"] = cfg.get("LIBPATH_BOOST", '') 771 772 #------------------------------------------------------------------------------- 773 # 1.6. ----- optional tools/libs 774 #------------------------------------------------------------------------------- 775 # 1.6.1. ----- check for F90 compiler : is now compulsory 776 777 # 1.6.2. ----- optional packages for aster 778 # hdf5 779 cfg['HOME_HDF'] = cfg.get('HOME_HDF', '') 780 # med 781 cfg['HOME_MED'] = cfg.get('HOME_MED', '') 782 # MUMPS 783 cfg['HOME_MUMPS'] = cfg.get('HOME_MUMPS', '') 784 # MFRONT 785 cfg['HOME_MFRONT'] = cfg.get('HOME_MFRONT', '') 786 # SCOTCH 787 cfg['HOME_SCOTCH'] = cfg.get('HOME_SCOTCH', '') 788 # MPI 789 cfg['HOME_MPI'] = cfg.get('HOME_MPI', '') 790 791 # 1.6.4. ----- mumps 792 cfg['INCLUDE_MUMPS'] = cfg.get('INCLUDE_MUMPS', 793 'include_mumps-%s' % dict_prod['mumps']) 794 795 # 1.6.5. ----- grace 5 796 grace_add_symlink = False 797 if not opts.ign_err and 'grace' in to_install: 798 ftools.find_and_set(cfg, 'XMGRACE', ['xmgrace', 'grace'], err=False) 799 if cfg.get('XMGRACE'): 800 # try to use grace instead of xmgrace that does not work without 801 # DISPLAY 802 ftools.find_and_set( 803 cfg, 'GRACEBAT', ['grace', 'gracebat'], err=False) 804 grace = cfg.get('GRACEBAT', cfg['XMGRACE']) 805 iret, out, outspl = ftools.get_product_version(grace, '-version') 806 vers = None 807 svers = '?' 808 mat = re.search('(Grace.*?)([0-9\.]+)', out, re.MULTILINE) 809 if mat is not None: 810 vers = mat.group(2).strip('.').split('.') 811 try: 812 vers = [int(v) for v in vers] 813 svers = '.'.join([str(i) for i in vers]) 814 except: 815 vers = None 816 log._print( 817 'XMGRACE', ''.join(mat.groups()), ': version', vers, DBG=True) 818 if vers is not None and vers < [5, 90]: 819 res = 'version is %s : ok. Do not need compile grace from sources.' % svers 820 to_install.remove('grace') 821 grace_add_symlink = True 822 else: 823 res = 'version is %s. Trying to compile grace from sources.' % svers 824 ftools.check(res, 'Grace version < 5.99') 825 826 # 1.6.6. ----- OS X 827 if plt == 'darwin': 828 # gmsh and homard are x86 binaries 829 for prod in ('gmsh', 'homard'): 830 if prod in to_install: 831 to_install.remove(prod) 832 833 #------------------------------------------------------------------------------- 834 # 2. dependencies 835 #------------------------------------------------------------------------------- 836 # 2.1. ----- add in DEPENDENCIES instance values set by __main__... 837 dep.Add(product='__main__', 838 set=[k for k in list(cfg.keys()) if not k in cfg_init_keys],) 839 840 # 2.2. ----- ... and during configuration step 841 dep.Add(product='__cfg__', 842 set=cfg_init_keys) 843 dep.FillCache() 844 845 #------------------------------------------------------------------------------- 846 # 2.99. ----- stop here if 'test' 847 err = False 848 if not os.path.exists(cfg['ASTER_ROOT']): 849 try: 850 os.makedirs(cfg['ASTER_ROOT']) 851 except OSError: 852 err = True 853 if not os.path.exists(osp.join(cfg['ASTER_ROOT'], 'bin')): 854 try: 855 os.makedirs(osp.join(cfg['ASTER_ROOT'], 'bin')) 856 except OSError: 857 err = True 858 err = err or not os.access(cfg['ASTER_ROOT'], os.W_OK) 859 if err: 860 log._print(_separ, term='') 861 log._print(_('No write access to %s.\n' 862 'Use --aster_root=XXX to change destination directory.') % 863 cfg['ASTER_ROOT']) 864 return 865 866 t_ini = time.time() - t_ini 867 if _test: 868 print() 869 print('Stop here !') 870 print('Settings are saved in setup.cache. Remove it if you ' 871 'change something.') 872 return 873 else: 874 print() 875 log._print(_separ, term='') 876 if cfg['F90'] == '': 877 log._print( 878 get_install_message('gfortran', 'a fortran 90 compiler')) 879 raise SetupError(_("Error: no fortran90 compiler found !")) 880 881 if noprompt: 882 log._print('Continue without prompting.') 883 else: 884 log._print( 885 _("Check if found values seem correct. If not you can change them using 'setup.cfg'.")) 886 should_continue() 887 888 t_ini = time.time() - t_ini 889 890 #------------------------------------------------------------------------------- 891 # 4. products installation 892 #------------------------------------------------------------------------- 893 894 #------------------------------------------------------------------------------- 895 # product for which full installation is required 896 summary = SUMMARY(to_install, system=system, log=log, t_ini=t_ini) 897 summary.SetGlobal(cfg['ASTER_ROOT'], '') 898 899 for product in to_install: 900 alias = product_alias(product) 901 if cfg.get('_install_' + alias, product in to_install): 902 t0 = time.time() 903 setup = None 904 if hasattr(products, 'setup_%s' % alias): 905 txt = compiler_manager.switch_in_dep(dep, 906 product=alias, 907 system=system, 908 verbose=True) 909 log._print( 910 _separ, _('Compiler variables for %s (set as environment variables):') % product) 911 log._print(txt) 912 log._print() 913 # export environment 914 ftools.AddToPathVar(dep.cfg, 'PATH', None) 915 ftools.AddToPathVar(dep.cfg, 'LD_LIBRARY_PATH', None) 916 system.AddToEnv(dep.cfg['OPT_ENV'], verbose=False) 917 # 918 setup = getattr(products, 'setup_%s' % alias)(**{ 919 'dep': dep, 920 'summary': summary, 921 'verbose': verbose, 922 'debug': debug, 923 'system': system, 924 'find_tools': ftools, 925 'log': log, 926 'reinstall': opts.reinstall, 927 }) 928 else: 929 raise SetupError( 930 _('Setup script for %s not available.') % product) 931 try: 932 if not _test: 933 setup.Go() 934 else: 935 setup.PreCheck() 936 except safe_exceptions as msg: 937 log._print(_fmt_err % msg) 938 # how to continue if failed 939 if setup.exit_code != 0: 940 setup.IfFailed() 941 dt = time.time() - t0 942 summary.Set(product, setup, dt, sys.exc_info()[:2]) 943 944 #------------------------------------------------------------------------------- 945 # 5. Summary 946 #------------------------------------------------------------------------- 947 summary.Print() 948 949 # 6. Clean up 950 ftools.clear_temporary_folder() 951 if PY3: 952 os.system('rm -rf %s' % py3tmpdir) 953 954 955def seedetails(): 956 print('\n' * 2 + 957 _('Exception raised. See %s file for details.') % repr(log_file)) 958 959 960#------------------------------------------------------------------------- 961if __name__ == '__main__': 962 try: 963 main() 964 except SystemExit as msg: 965 log._print(msg) 966 seedetails() 967 sys.exit(msg) 968 except: 969 traceback.print_exc() 970 seedetails() 971 log.close() 972