/[escript]/trunk/SConstruct
ViewVC logotype

Diff of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1705 by ksteube, Thu Aug 14 05:56:40 2008 UTC revision 1811 by ksteube, Thu Sep 25 23:11:13 2008 UTC
# Line 1  Line 1 
1  #         Copyright 2006 by ACcESS MNRF  
2    ########################################################
3    #
4    # Copyright (c) 2003-2008 by University of Queensland
5    # Earth Systems Science Computational Center (ESSCC)
6    # http://www.uq.edu.au/esscc
7    #
8    # Primary Business: Queensland, Australia
9    # Licensed under the Open Software License version 3.0
10    # http://www.opensource.org/licenses/osl-3.0.php
11  #  #
12  #              http://www.access.edu.au  ########################################################
13  #       Primary Business: Queensland, Australia  
 #  Licensed under the Open Software License version 3.0  
 #     http://www.opensource.org/licenses/osl-3.0.php  
14    
15  EnsureSConsVersion(0,96,91)  EnsureSConsVersion(0,96,91)
16  EnsurePythonVersion(2,3)  EnsurePythonVersion(2,3)
# Line 31  hostname = re.sub("[^0-9a-zA-Z]", "_", s Line 38  hostname = re.sub("[^0-9a-zA-Z]", "_", s
38  tmp = os.path.join("scons",hostname+"_options.py")  tmp = os.path.join("scons",hostname+"_options.py")
39  options_file = ARGUMENTS.get('options_file', tmp)  options_file = ARGUMENTS.get('options_file', tmp)
40  if not os.path.isfile(options_file): options_file = False  if not os.path.isfile(options_file): options_file = False
41    else: print "Options file is", options_file
42    
43  # Load options file and command-line arguments  # Load options file and command-line arguments
44  opts = Options(options_file, ARGUMENTS)  opts = Options(options_file, ARGUMENTS)
# Line 41  opts.AddOptions( Line 49  opts.AddOptions(
49  # Where to install esys stuff  # Where to install esys stuff
50    ('prefix', 'where everything will be installed',                       Dir('#.').abspath),    ('prefix', 'where everything will be installed',                       Dir('#.').abspath),
51    ('incinstall', 'where the esys headers will be installed',             os.path.join(Dir('#.').abspath,'include')),    ('incinstall', 'where the esys headers will be installed',             os.path.join(Dir('#.').abspath,'include')),
52      ('bininstall', 'where the esys binaries will be installed',            os.path.join(prefix,'bin')),
53    ('libinstall', 'where the esys libraries will be installed',           os.path.join(prefix,'lib')),    ('libinstall', 'where the esys libraries will be installed',           os.path.join(prefix,'lib')),
54    ('pyinstall', 'where the esys python modules will be installed',       os.path.join(prefix,'esys')),    ('pyinstall', 'where the esys python modules will be installed',       os.path.join(prefix,'esys')),
55  # Compilation options  # Compilation options
# Line 56  opts.AddOptions( Line 65  opts.AddOptions(
65    ('omp_debug', 'OpenMP compiler flags to use (Debug build)', '-DEFAULT_5'),    ('omp_debug', 'OpenMP compiler flags to use (Debug build)', '-DEFAULT_5'),
66    ('omp_libs', 'OpenMP compiler libraries to link with', '-DEFAULT_6'),    ('omp_libs', 'OpenMP compiler libraries to link with', '-DEFAULT_6'),
67    ('cc_extra', 'Extra C/C++ flags', ''),    ('cc_extra', 'Extra C/C++ flags', ''),
68      ('ld_extra', 'Extra linker flags', ''),
69    ('sys_libs', 'System libraries to link with', []),    ('sys_libs', 'System libraries to link with', []),
70    ('ar_flags', 'Static library archiver flags to use', ''),    ('ar_flags', 'Static library archiver flags to use', ''),
71    BoolOption('useopenmp', 'Compile parallel version using OpenMP', 'yes'),    BoolOption('useopenmp', 'Compile parallel version using OpenMP', 'yes'),
# Line 99  opts.AddOptions( Line 109  opts.AddOptions(
109    ('mkl_lib_path', 'Path to MKL libs', '/sw/sdev/cmkl/10.0.2.18/lib/em64t'),    ('mkl_lib_path', 'Path to MKL libs', '/sw/sdev/cmkl/10.0.2.18/lib/em64t'),
110    ('mkl_libs', 'MKL libraries to link with', ['mkl_solver', 'mkl_em64t', 'guide', 'pthread']),    ('mkl_libs', 'MKL libraries to link with', ['mkl_solver', 'mkl_em64t', 'guide', 'pthread']),
111  # UMFPACK  # UMFPACK
112    BoolOption('useumfpack', 'switch on/off the usage of UMFPACK', 'yes'),    BoolOption('useumfpack', 'switch on/off the usage of UMFPACK', 'no'),
113    ('ufc_path', 'Path to UFconfig includes', '/usr/include/suitesparse'),    ('ufc_path', 'Path to UFconfig includes', '/usr/include/suitesparse'),
114    ('umf_path', 'Path to UMFPACK includes', '/usr/include/suitesparse'),    ('umf_path', 'Path to UMFPACK includes', '/usr/include/suitesparse'),
115    ('umf_lib_path', 'Path to UMFPACK libs', usr_lib),    ('umf_lib_path', 'Path to UMFPACK libs', usr_lib),
# Line 145  if env["CC"] == "icc": Line 155  if env["CC"] == "icc":
155    # Intel compilers    # Intel compilers
156    cc_flags      = "-fPIC -ansi -wd161 -w1 -vec-report0 -DBLOCKTIMER -DCORE_ID1"    cc_flags      = "-fPIC -ansi -wd161 -w1 -vec-report0 -DBLOCKTIMER -DCORE_ID1"
157    cc_optim      = "-O3 -ftz -IPF_ftlacc- -IPF_fma -fno-alias"    cc_optim      = "-O3 -ftz -IPF_ftlacc- -IPF_fma -fno-alias"
158    cc_debug      = "-g -O0 -UDOASSERT -DDOPROF -DBOUNDS_CHECK"    cc_debug      = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
159    omp_optim     = "-openmp -openmp_report0"    omp_optim     = "-openmp -openmp_report0"
160    omp_debug     = "-openmp -openmp_report0"    omp_debug     = "-openmp -openmp_report0"
161    omp_libs      = ['guide', 'pthread']    omp_libs      = ['guide', 'pthread']
# Line 154  elif env["CC"] == "gcc": Line 164  elif env["CC"] == "gcc":
164    # GNU C on any system    # GNU C on any system
165    cc_flags      = "-fPIC -ansi -ffast-math -Wno-unknown-pragmas -DBLOCKTIMER"    cc_flags      = "-fPIC -ansi -ffast-math -Wno-unknown-pragmas -DBLOCKTIMER"
166    cc_optim      = "-O3"    cc_optim      = "-O3"
167    cc_debug      = "-g -O0 -UDOASSERT -DDOPROF -DBOUNDS_CHECK"    cc_debug      = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
168    omp_optim     = ""    omp_optim     = ""
169    omp_debug     = ""    omp_debug     = ""
170    omp_libs      = []    omp_libs      = []
# Line 221  except KeyError: pass Line 231  except KeyError: pass
231  env.PrependENVPath('PYTHONPATH', prefix)  env.PrependENVPath('PYTHONPATH', prefix)
232  env.PrependENVPath('LD_LIBRARY_PATH', env['libinstall'])  env.PrependENVPath('LD_LIBRARY_PATH', env['libinstall'])
233    
234    env['ENV']['ESCRIPT_ROOT'] = prefix
235    
236  ############ Set up paths for Configure() ######################  ############ Set up paths for Configure() ######################
237    
238  # Make a copy of an environment  # Make a copy of an environment
# Line 233  def clone_env(env): Line 245  def clone_env(env):
245  env.Append(CPPPATH      = [Dir('include')])  env.Append(CPPPATH      = [Dir('include')])
246    
247  # Add cc option -L<Escript>/trunk/lib  # Add cc option -L<Escript>/trunk/lib
248  env.Append(LIBPATH      = [Dir('lib')])  env.Append(LIBPATH      = [Dir(env['libinstall'])])
249    
250  env.Append(CPPDEFINES = ['ESCRIPT_EXPORTS', 'FINLEY_EXPORTS'])  env.Append(CPPDEFINES = ['ESCRIPT_EXPORTS', 'FINLEY_EXPORTS'])
251    
252  if env['cc_extra'] != '': env.Append(CCFLAGS = env['cc_extra'])  if env['cc_extra'] != '': env.Append(CCFLAGS = env['cc_extra'])
253    if env['ld_extra'] != '': env.Append(LINKFLAGS = env['ld_extra'])
254    
255  if env['usepedantic']: env.Append(CCFLAGS = pedantic)  if env['usepedantic']: env.Append(CCFLAGS = pedantic)
256    
# Line 278  if not conf.CheckFunc('printf'): Line 291  if not conf.CheckFunc('printf'):
291    print "Cannot run C compiler '%s' (or libc is missing)" % (env['CC'])    print "Cannot run C compiler '%s' (or libc is missing)" % (env['CC'])
292    sys.exit(1)    sys.exit(1)
293    
294  if not conf.CheckFunc('gethostname'):  if conf.CheckFunc('gethostname'):
295    env.Append(CPPDEFINES = ['HAVE_GETHOSTNAME'])    conf.env.Append(CPPDEFINES = ['HAVE_GETHOSTNAME'])
296    
297  ############ python libraries (required) #######################  ############ python libraries (required) #######################
298    
# Line 287  conf.env.AppendUnique(CPPPATH      = [env['p Line 300  conf.env.AppendUnique(CPPPATH      = [env['p
300  conf.env.AppendUnique(LIBPATH       = [env['python_lib_path']])  conf.env.AppendUnique(LIBPATH       = [env['python_lib_path']])
301  conf.env.AppendUnique(LIBS      = [env['python_libs']])  conf.env.AppendUnique(LIBS      = [env['python_libs']])
302    
303    conf.env.PrependENVPath('LD_LIBRARY_PATH', env['python_lib_path'])  # The wrapper script needs to find these libs
304    
305  if not conf.CheckCHeader('Python.h'):  if not conf.CheckCHeader('Python.h'):
306    print "Cannot find python include files (tried 'Python.h' in directory %s)" % (env['python_path'])    print "Cannot find python include files (tried 'Python.h' in directory %s)" % (env['python_path'])
307    sys.exit(1)    sys.exit(1)
# Line 300  conf.env.AppendUnique(CPPPATH      = [env['b Line 315  conf.env.AppendUnique(CPPPATH      = [env['b
315  conf.env.AppendUnique(LIBPATH       = [env['boost_lib_path']])  conf.env.AppendUnique(LIBPATH       = [env['boost_lib_path']])
316  conf.env.AppendUnique(LIBS      = [env['boost_libs']])  conf.env.AppendUnique(LIBS      = [env['boost_libs']])
317    
318    conf.env.PrependENVPath('LD_LIBRARY_PATH', env['boost_lib_path'])   # The wrapper script needs to find these libs
319    
320  if not conf.CheckCXXHeader('boost/python.hpp'):  if not conf.CheckCXXHeader('boost/python.hpp'):
321    print "Cannot find boost include files (tried boost/python.hpp in directory %s)" % (env['boost_path'])    print "Cannot find boost include files (tried boost/python.hpp in directory %s)" % (env['boost_path'])
322    sys.exit(1)    sys.exit(1)
# Line 331  if env['usenetcdf']: Line 348  if env['usenetcdf']:
348    conf.env.AppendUnique(CPPPATH = [env['netCDF_path']])    conf.env.AppendUnique(CPPPATH = [env['netCDF_path']])
349    conf.env.AppendUnique(LIBPATH = [env['netCDF_lib_path']])    conf.env.AppendUnique(LIBPATH = [env['netCDF_lib_path']])
350    conf.env.AppendUnique(LIBS    = [env['netCDF_libs']])    conf.env.AppendUnique(LIBS    = [env['netCDF_libs']])
351      conf.env.PrependENVPath('LD_LIBRARY_PATH', env['netCDF_lib_path'])    # The wrapper script needs to find these libs
352    
353  if env['usenetcdf'] and not conf.CheckCHeader('netcdf.h'): env['usenetcdf'] = 0  if env['usenetcdf'] and not conf.CheckCHeader('netcdf.h'): env['usenetcdf'] = 0
354  if env['usenetcdf'] and not conf.CheckFunc('nc_open'): env['usenetcdf'] = 0  if env['usenetcdf'] and not conf.CheckFunc('nc_open'): env['usenetcdf'] = 0
# Line 351  if env['usepapi']: Line 369  if env['usepapi']:
369    conf.env.AppendUnique(CPPPATH = [env['papi_path']])    conf.env.AppendUnique(CPPPATH = [env['papi_path']])
370    conf.env.AppendUnique(LIBPATH = [env['papi_lib_path']])    conf.env.AppendUnique(LIBPATH = [env['papi_lib_path']])
371    conf.env.AppendUnique(LIBS    = [env['papi_libs']])    conf.env.AppendUnique(LIBS    = [env['papi_libs']])
372      conf.env.PrependENVPath('LD_LIBRARY_PATH', env['papi_lib_path'])  # The wrapper script needs to find these libs
373    
374  if env['usepapi'] and not conf.CheckCHeader('papi.h'): env['usepapi'] = 0  if env['usepapi'] and not conf.CheckCHeader('papi.h'): env['usepapi'] = 0
375  if env['usepapi'] and not conf.CheckFunc('PAPI_start_counters'): env['usepapi'] = 0  if env['usepapi'] and not conf.CheckFunc('PAPI_start_counters'): env['usepapi'] = 0
# Line 371  if env['usemkl']: Line 390  if env['usemkl']:
390    conf.env.AppendUnique(CPPPATH = [env['mkl_path']])    conf.env.AppendUnique(CPPPATH = [env['mkl_path']])
391    conf.env.AppendUnique(LIBPATH = [env['mkl_lib_path']])    conf.env.AppendUnique(LIBPATH = [env['mkl_lib_path']])
392    conf.env.AppendUnique(LIBS    = [env['mkl_libs']])    conf.env.AppendUnique(LIBS    = [env['mkl_libs']])
393      conf.env.PrependENVPath('LD_LIBRARY_PATH', env['mkl_lib_path'])   # The wrapper script needs to find these libs
394    
395  if env['usemkl'] and not conf.CheckCHeader('mkl_solver.h'): env['usemkl'] = 0  if env['usemkl'] and not conf.CheckCHeader('mkl_solver.h'): env['usemkl'] = 0
396  if env['usemkl'] and not conf.CheckFunc('pardiso_'): env['usemkl'] = 0  if env['usemkl'] and not conf.CheckFunc('pardiso_'): env['usemkl'] = 0
# Line 398  if env['useumfpack']: Line 418  if env['useumfpack']:
418    conf.env.AppendUnique(CPPPATH = [env['blas_path']])    conf.env.AppendUnique(CPPPATH = [env['blas_path']])
419    conf.env.AppendUnique(LIBPATH = [env['blas_lib_path']])    conf.env.AppendUnique(LIBPATH = [env['blas_lib_path']])
420    conf.env.AppendUnique(LIBS    = [env['blas_libs']])    conf.env.AppendUnique(LIBS    = [env['blas_libs']])
421      conf.env.PrependENVPath('LD_LIBRARY_PATH', env['umf_lib_path'])   # The wrapper script needs to find these libs
422      conf.env.PrependENVPath('LD_LIBRARY_PATH', env['amd_lib_path'])   # The wrapper script needs to find these libs
423      conf.env.PrependENVPath('LD_LIBRARY_PATH', env['blas_lib_path'])  # The wrapper script needs to find these libs
424    
425  if env['useumfpack'] and not conf.CheckCHeader('umfpack.h'): env['useumfpack'] = 0  if env['useumfpack'] and not conf.CheckCHeader('umfpack.h'): env['useumfpack'] = 0
426  if env['useumfpack'] and not conf.CheckFunc('umfpack_di_symbolic'): env['useumfpack'] = 0  if env['useumfpack'] and not conf.CheckFunc('umfpack_di_symbolic'): env['useumfpack'] = 0
# Line 435  if env_mpi['usempi']: Line 458  if env_mpi['usempi']:
458    conf.env.AppendUnique(CPPPATH = [env_mpi['mpi_path']])    conf.env.AppendUnique(CPPPATH = [env_mpi['mpi_path']])
459    conf.env.AppendUnique(LIBPATH = [env_mpi['mpi_lib_path']])    conf.env.AppendUnique(LIBPATH = [env_mpi['mpi_lib_path']])
460    conf.env.AppendUnique(LIBS    = [env_mpi['mpi_libs']])    conf.env.AppendUnique(LIBS    = [env_mpi['mpi_libs']])
461      conf.env.PrependENVPath('LD_LIBRARY_PATH', env['mpi_lib_path'])   # The wrapper script needs to find these libs
462    
463  if env_mpi['usempi'] and not conf.CheckCHeader('mpi.h'): env_mpi['usempi'] = 0  if env_mpi['usempi'] and not conf.CheckCHeader('mpi.h'): env_mpi['usempi'] = 0
464  if env_mpi['usempi'] and not conf.CheckFunc('MPI_Init'): env_mpi['usempi'] = 0  if env_mpi['usempi'] and not conf.CheckFunc('MPI_Init'): env_mpi['usempi'] = 0
# Line 459  if env_mpi['useparmetis']: Line 483  if env_mpi['useparmetis']:
483    conf.env.AppendUnique(CPPPATH = [env_mpi['parmetis_path']])    conf.env.AppendUnique(CPPPATH = [env_mpi['parmetis_path']])
484    conf.env.AppendUnique(LIBPATH = [env_mpi['parmetis_lib_path']])    conf.env.AppendUnique(LIBPATH = [env_mpi['parmetis_lib_path']])
485    conf.env.AppendUnique(LIBS    = [env_mpi['parmetis_libs']])    conf.env.AppendUnique(LIBS    = [env_mpi['parmetis_libs']])
486      conf.env.PrependENVPath('LD_LIBRARY_PATH', env['parmetis_lib_path'])  # The wrapper script needs to find these libs
487    
488  if env_mpi['useparmetis'] and not conf.CheckCHeader('parmetis.h'): env_mpi['useparmetis'] = 0  if env_mpi['useparmetis'] and not conf.CheckCHeader('parmetis.h'): env_mpi['useparmetis'] = 0
489  if env_mpi['useparmetis'] and not conf.CheckFunc('ParMETIS_V3_PartGeomKway'): env_mpi['useparmetis'] = 0  if env_mpi['useparmetis'] and not conf.CheckFunc('ParMETIS_V3_PartGeomKway'): env_mpi['useparmetis'] = 0
# Line 500  else: print "  Not compiling for debug" Line 525  else: print "  Not compiling for debug"
525  print " Installing in", prefix  print " Installing in", prefix
526  print ""  print ""
527    
528    ############ Delete option-dependent files #####################
529    
530    Execute(Delete(env['libinstall'] + "/Compiled.with.debug"))
531    Execute(Delete(env['libinstall'] + "/Compiled.with.mpi"))
532    Execute(Delete(env['libinstall'] + "/Compiled.with.openmp"))
533    if not env['usempi']: Execute(Delete(env['libinstall'] + "/pythonMPI"))
534    
535  ############ Add some custom builders ##########################  ############ Add some custom builders ##########################
536    
537  py_builder = Builder(action = scons_extensions.build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)  py_builder = Builder(action = scons_extensions.build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)
# Line 511  env.Append(BUILDERS = {'RunUnitTest' : r Line 543  env.Append(BUILDERS = {'RunUnitTest' : r
543  runPyUnitTest_builder = Builder(action = scons_extensions.runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)  runPyUnitTest_builder = Builder(action = scons_extensions.runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
544  env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});  env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
545    
546  ############ Build the desired subdirectories ##################  ############ Build the subdirectories ##########################
547    
548  Export(["env", "env_mpi", "clone_env"])  Export(["env", "env_mpi", "clone_env"])
549    
# Line 525  env.SConscript(dirs = ['doc'], build_dir Line 557  env.SConscript(dirs = ['doc'], build_dir
557  env.SConscript(dirs = ['pyvisi/py_src'], build_dir='build/$PLATFORM/pyvisi', duplicate=0)  env.SConscript(dirs = ['pyvisi/py_src'], build_dir='build/$PLATFORM/pyvisi', duplicate=0)
558  env.SConscript(dirs = ['pycad/py_src'], build_dir='build/$PLATFORM/pycad', duplicate=0)  env.SConscript(dirs = ['pycad/py_src'], build_dir='build/$PLATFORM/pycad', duplicate=0)
559  env.SConscript(dirs = ['pythonMPI/src'], build_dir='build/$PLATFORM/pythonMPI', duplicate=0)  env.SConscript(dirs = ['pythonMPI/src'], build_dir='build/$PLATFORM/pythonMPI', duplicate=0)
560    env.SConscript(dirs = ['scripts'], build_dir='build/$PLATFORM/scripts', duplicate=0)
561    
562  ############ Remember what optimizations we used ###############  ############ Remember what optimizations we used ###############
563    
# Line 532  remember_list = [] Line 565  remember_list = []
565    
566  if env['usedebug']:  if env['usedebug']:
567    remember_list += env.Command(env['libinstall'] + "/Compiled.with.debug", None, Touch('$TARGET'))    remember_list += env.Command(env['libinstall'] + "/Compiled.with.debug", None, Touch('$TARGET'))
 else:  
   remember_list += env.Command(env['libinstall'] + "/Compiled.with.debug", None, Delete('$TARGET'))  
568    
569  if env['usempi']:  if env['usempi']:
570    remember_list += env.Command(env['libinstall'] + "/Compiled.with.mpi", None, Touch('$TARGET'))    remember_list += env.Command(env['libinstall'] + "/Compiled.with.mpi", None, Touch('$TARGET'))
 else:  
   remember_list += env.Command(env['libinstall'] + "/Compiled.with.mpi", None, Delete('$TARGET'))  
571    
572  if env['omp_optim'] != '':  if env['omp_optim'] != '':
573    remember_list += env.Command(env['libinstall'] + "/Compiled.with.openmp", None, Touch('$TARGET'))    remember_list += env.Command(env['libinstall'] + "/Compiled.with.openmp", None, Touch('$TARGET'))
 else:  
   remember_list += env.Command(env['libinstall'] + "/Compiled.with.openmp", None, Delete('$TARGET'))  
574    
575  env.Alias('remember_options', remember_list)  env.Alias('remember_options', remember_list)
576    
# Line 571  build_all_list += ['build_esysUtils'] Line 598  build_all_list += ['build_esysUtils']
598  build_all_list += ['build_paso']  build_all_list += ['build_paso']
599  build_all_list += ['build_escript']  build_all_list += ['build_escript']
600  build_all_list += ['build_finley']  build_all_list += ['build_finley']
601  if env['usempi']: build_all_list += ['target_pythonMPI_exe']  if env['usempi']:       build_all_list += ['target_pythonMPI_exe']
602    if not IS_WINDOWS_PLATFORM: build_all_list += ['target_finley_wrapper']
603  env.Alias('build_all', build_all_list)  env.Alias('build_all', build_all_list)
604    
605  install_all_list = []  install_all_list = []
# Line 583  install_all_list += ['install_finley'] Line 611  install_all_list += ['install_finley']
611  install_all_list += ['target_install_pyvisi_py']  install_all_list += ['target_install_pyvisi_py']
612  install_all_list += ['target_install_modellib_py']  install_all_list += ['target_install_modellib_py']
613  install_all_list += ['target_install_pycad_py']  install_all_list += ['target_install_pycad_py']
614  if env['usempi']: install_all_list += ['target_install_pythonMPI_exe']  if env['usempi']:       install_all_list += ['target_install_pythonMPI_exe']
615    if not IS_WINDOWS_PLATFORM: install_all_list += ['target_install_finley_wrapper']
616  install_all_list += ['remember_options']  install_all_list += ['remember_options']
617  env.Alias('install_all', install_all_list)  env.Alias('install_all', install_all_list)
618    

Legend:
Removed from v.1705  
changed lines
  Added in v.1811

  ViewVC Help
Powered by ViewVC 1.1.26