1import config.base 2 3import os 4import sys 5import re 6import cPickle 7import string 8 9# The sorted() builtin is not available with python-2.3 10try: sorted 11except NameError: 12 def sorted(lst): 13 lst.sort() 14 return lst 15 16class Configure(config.base.Configure): 17 def __init__(self, framework): 18 config.base.Configure.__init__(self, framework) 19 self.headerPrefix = 'PETSC' 20 self.substPrefix = 'PETSC' 21 self.installed = 0 # 1 indicates that Configure itself has already compiled and installed PETSc 22 return 23 24 def __str2__(self): 25 desc = [] 26 if not self.installed: 27 desc.append('xxx=========================================================================xxx') 28 if self.make.getMakeMacro('MAKE_IS_GNUMAKE'): 29 build_type = 'gnumake build' 30 elif self.getMakeMacro('PETSC_BUILD_USING_CMAKE'): 31 build_type = 'cmake build' 32 else: 33 build_type = 'legacy build' 34 desc.append(' Configure stage complete. Now build PETSc libraries with (%s):' % build_type) 35 desc.append(' make PETSC_DIR='+self.petscdir.dir+' PETSC_ARCH='+self.arch.arch+' all') 36 desc.append('xxx=========================================================================xxx') 37 else: 38 desc.append('xxx=========================================================================xxx') 39 desc.append(' Installation complete. You do not need to run make to compile or install the software') 40 desc.append('xxx=========================================================================xxx') 41 return '\n'.join(desc)+'\n' 42 43 def setupHelp(self, help): 44 import nargs 45 help.addArgument('PETSc', '-prefix=<dir>', nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)')) 46 help.addArgument('PETSc', '-with-prefetch=<bool>', nargs.ArgBool(None, 1,'Enable checking for prefetch instructions')) 47 help.addArgument('Windows','-with-windows-graphics=<bool>', nargs.ArgBool(None, 1,'Enable check for Windows Graphics')) 48 help.addArgument('PETSc', '-with-default-arch=<bool>', nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH')) 49 help.addArgument('PETSc','-with-single-library=<bool>', nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library')) 50 help.addArgument('PETSc','-with-fortran-bindings=<bool>', nargs.ArgBool(None, 1,'Build PETSc fortran bindings in the library and corresponding module files')) 51 help.addArgument('PETSc', '-with-ios=<bool>', nargs.ArgBool(None, 0, 'Build an iPhone/iPad version of PETSc library')) 52 help.addArgument('PETSc', '-with-xsdk-defaults', nargs.ArgBool(None, 0, 'Set the following as defaults for the xSDK standard: --enable-debug=1, --enable-shared=1, --with-precision=double, --with-index-size=32, locate blas/lapack automatically')) 53 help.addArgument('PETSc', '-known-has-attribute-aligned=<bool>',nargs.ArgBool(None, None, 'Indicates __attribute((aligned(16)) directive works (the usual test will be skipped)')) 54 help.addArgument('PETSc','-with-viewfromoptions=<bool>', nargs.ArgBool(None, 1,'Support XXXSetFromOptions() calls, for calls with many small solvers turn this off')) 55 help.addArgument('PETSc', '-with-display=<x11display>', nargs.Arg(None, '', 'Specifiy DISPLAY env variable for use with matlab test)')) 56 return 57 58 def registerPythonFile(self,filename,directory): 59 ''' Add a python file to the framework and registers its headerprefix, ... externalpackagedir 60 directory is the directory where the file relative to the BuildSystem or config path in python notation with . ''' 61 (utilityName, ext) = os.path.splitext(filename) 62 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 63 if directory: directory = directory+'.' 64 utilityObj = self.framework.require(directory+utilityName, self) 65 utilityObj.headerPrefix = self.headerPrefix 66 utilityObj.archProvider = self.arch 67 utilityObj.languageProvider = self.languages 68 utilityObj.installDirProvider = self.installdir 69 utilityObj.externalPackagesDirProvider = self.externalpackagesdir 70 utilityObj.precisionProvider = self.scalartypes 71 utilityObj.indexProvider = self.indexTypes 72 setattr(self, utilityName.lower(), utilityObj) 73 return utilityObj 74 return None 75 76 def setupDependencies(self, framework): 77 config.base.Configure.setupDependencies(self, framework) 78 self.programs = framework.require('config.programs', self) 79 self.setCompilers = framework.require('config.setCompilers', self) 80 self.compilers = framework.require('config.compilers', self) 81 self.arch = framework.require('PETSc.options.arch', self.setCompilers) 82 self.petscdir = framework.require('PETSc.options.petscdir', self.arch) 83 self.installdir = framework.require('PETSc.options.installDir', self) 84 self.scalartypes = framework.require('PETSc.options.scalarTypes', self) 85 self.indexTypes = framework.require('PETSc.options.indexTypes', self) 86 self.languages = framework.require('PETSc.options.languages', self.setCompilers) 87 self.debugging = framework.require('PETSc.options.debugging', self.compilers) 88 self.indexTypes = framework.require('PETSc.options.indexTypes', self.compilers) 89 self.compilers = framework.require('config.compilers', self) 90 self.types = framework.require('config.types', self) 91 self.headers = framework.require('config.headers', self) 92 self.functions = framework.require('config.functions', self) 93 self.libraries = framework.require('config.libraries', self) 94 self.atomics = framework.require('config.atomics', self) 95 self.make = framework.require('config.packages.make', self) 96 self.blasLapack = framework.require('config.packages.BlasLapack',self) 97 self.cmake = framework.require('config.packages.cmake',self) 98 self.externalpackagesdir = framework.require('PETSc.options.externalpackagesdir',self) 99 self.mpi = framework.require('config.packages.MPI',self) 100 101 for utility in os.listdir(os.path.join('config','PETSc','options')): 102 self.registerPythonFile(utility,'PETSc.options') 103 104 for utility in os.listdir(os.path.join('config','BuildSystem','config','utilities')): 105 self.registerPythonFile(utility,'config.utilities') 106 107 for package in os.listdir(os.path.join('config', 'BuildSystem', 'config', 'packages')): 108 obj = self.registerPythonFile(package,'config.packages') 109 if obj: 110 obj.archProvider = self.framework.requireModule(obj.archProvider, obj) 111 obj.languageProvider = self.framework.requireModule(obj.languageProvider, obj) 112 obj.installDirProvider = self.framework.requireModule(obj.installDirProvider, obj) 113 obj.externalPackagesDirProvider = self.framework.requireModule(obj.externalPackagesDirProvider, obj) 114 obj.precisionProvider = self.framework.requireModule(obj.precisionProvider, obj) 115 obj.indexProvider = self.framework.requireModule(obj.indexProvider, obj) 116 117 # Force blaslapack and opencl to depend on scalarType so precision is set before BlasLapack is built 118 framework.require('PETSc.options.scalarTypes', self.f2cblaslapack) 119 framework.require('PETSc.options.scalarTypes', self.fblaslapack) 120 framework.require('PETSc.options.scalarTypes', self.blaslapack) 121 framework.require('PETSc.options.scalarTypes', self.opencl) 122 framework.require('PETSc.Regression', self) 123 124 self.programs.headerPrefix = self.headerPrefix 125 self.compilers.headerPrefix = self.headerPrefix 126 self.types.headerPrefix = self.headerPrefix 127 self.headers.headerPrefix = self.headerPrefix 128 self.functions.headerPrefix = self.headerPrefix 129 self.libraries.headerPrefix = self.headerPrefix 130 131 # Look for any user provided --download-xxx=directory packages 132 for arg in sys.argv: 133 if arg.startswith('--download-') and arg.find('=') > -1: 134 pname = arg[11:arg.find('=')] 135 if not hasattr(self,pname): 136 dname = os.path.dirname(arg[arg.find('=')+1:]) 137 if os.path.isdir(dname) and not os.path.isfile(os.path.join(dname,pname+'.py')): 138 self.framework.logPrint('User is registering a new package: '+arg) 139 sys.path.append(dname) 140 self.registerPythonFile(pname+'.py','') 141 142 # test for a variety of basic headers and functions 143 headersC = map(lambda name: name+'.h', ['setjmp','dos', 'endian', 'fcntl', 'float', 'io', 'limits', 'malloc', 'pwd', 'search', 'strings', 144 'unistd', 'sys/sysinfo', 'machine/endian', 'sys/param', 'sys/procfs', 'sys/resource', 145 'sys/systeminfo', 'sys/times', 'sys/utsname','string', 'stdlib', 146 'sys/socket','sys/wait','netinet/in','netdb','Direct','time','Ws2tcpip','sys/types', 147 'WindowsX', 'cxxabi','float','ieeefp','stdint','sched','pthread','mathimf','inttypes','immintrin','zmmintrin']) 148 functions = ['access', '_access', 'clock', 'drand48', 'getcwd', '_getcwd', 'getdomainname', 'gethostname', 149 'gettimeofday', 'getwd', 'memalign', 'memmove', 'mkstemp', 'popen', 'PXFGETARG', 'rand', 'getpagesize', 150 'readlink', 'realpath', 'sigaction', 'signal', 'sigset', 'usleep', 'sleep', '_sleep', 'socket', 151 'times', 'gethostbyname', 'uname','snprintf','_snprintf','lseek','_lseek','time','fork','stricmp', 152 'strcasecmp', 'bzero', 'dlopen', 'dlsym', 'dlclose', 'dlerror','get_nprocs','sysctlbyname', 153 '_set_output_format','_mkdir'] 154 libraries1 = [(['socket', 'nsl'], 'socket'), (['fpe'], 'handle_sigfpes')] 155 self.headers.headers.extend(headersC) 156 self.functions.functions.extend(functions) 157 self.libraries.libraries.extend(libraries1) 158 159 return 160 161 def DumpPkgconfig(self): 162 ''' Create a pkg-config file ''' 163 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')): 164 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')) 165 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig','PETSc.pc'),'w') 166 if self.framework.argDB['prefix']: 167 fd.write('prefix='+self.installdir.dir+'\n') 168 fd.write('exec_prefix=${prefix}\n') 169 fd.write('includedir=${prefix}/include\n') 170 else: 171 fd.write('prefix='+self.petscdir.dir+'\n') 172 fd.write('exec_prefix=${prefix}\n') 173 fd.write('includedir=${prefix}/include\n') 174 fd.write('libdir='+os.path.join(self.installdir.dir,'lib')+'\n') 175 176 self.setCompilers.pushLanguage('C') 177 fd.write('ccompiler='+self.setCompilers.getCompiler()+'\n') 178 fd.write('cflags_extra="'+self.setCompilers.getCompilerFlags().strip()+'"\n') 179 fd.write('cflags_dep="'+self.compilers.dependenciesGenerationFlag.get('C','')+'"\n') 180 fd.write('ldflag_rpath="'+self.setCompilers.CSharedLinkerFlag+'"\n') 181 self.setCompilers.popLanguage() 182 if hasattr(self.compilers, 'C++'): 183 self.setCompilers.pushLanguage('C++') 184 fd.write('cxxcompiler='+self.setCompilers.getCompiler()+'\n') 185 fd.write('cxxflags_extra="'+self.setCompilers.getCompilerFlags().strip()+'"\n') 186 self.setCompilers.popLanguage() 187 if hasattr(self.compilers, 'FC'): 188 self.setCompilers.pushLanguage('FC') 189 fd.write('fcompiler='+self.setCompilers.getCompiler()+'\n') 190 fd.write('fflags_extra="'+self.setCompilers.getCompilerFlags().strip()+'"\n') 191 self.setCompilers.popLanguage() 192 193 fd.write('\n') 194 fd.write('Name: PETSc\n') 195 fd.write('Description: Library to solve ODEs and algebraic equations\n') 196 fd.write('Version: %s\n' % self.petscdir.version) 197 fd.write('Cflags: ' + self.setCompilers.CPPFLAGS + ' ' + self.PETSC_CC_INCLUDES + '\n') 198 fd.write('Libs: '+self.libraries.toStringNoDupes(['-L${libdir}', self.petsclib], with_rpath=False)+'\n') 199 # Remove RPATH flags from library list. User can add them using 200 # pkg-config --variable=ldflag_rpath and pkg-config --libs-only-L 201 fd.write('Libs.private: '+self.libraries.toStringNoDupes([f for f in self.packagelibs+self.complibs if not f.startswith(self.setCompilers.CSharedLinkerFlag)], with_rpath=False)+'\n') 202 203 fd.close() 204 return 205 206 def DumpModule(self): 207 ''' Create a module file ''' 208 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')): 209 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')) 210 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')): 211 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')) 212 if self.framework.argDB['prefix']: 213 installdir = self.installdir.dir 214 installarch = '' 215 installpath = os.path.join(installdir,'bin') 216 else: 217 installdir = self.petscdir.dir 218 installarch = self.arch.arch 219 installpath = os.path.join(installdir,installarch,'bin')+':'+os.path.join(installdir,'bin') 220 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc',self.petscdir.version),'w') 221 fd.write('''\ 222#%%Module 223 224proc ModulesHelp { } { 225 puts stderr "This module sets the path and environment variables for petsc-%s" 226 puts stderr " see http://www.mcs.anl.gov/petsc/ for more information " 227 puts stderr "" 228} 229module-whatis "PETSc - Portable, Extensible Toolkit for Scientific Computation" 230 231set petsc_dir "%s" 232set petsc_arch "%s" 233 234setenv PETSC_ARCH "$petsc_arch" 235setenv PETSC_DIR "$petsc_dir" 236prepend-path PATH "%s" 237''' % (self.petscdir.version, installdir, installarch, installpath)) 238 fd.close() 239 return 240 241 def Dump(self): 242 ''' Actually put the values into the configuration files ''' 243 # eventually everything between -- should be gone 244 if self.mpi.usingMPIUni: 245 # 246 # Remove any MPI/MPICH include files that may have been put here by previous runs of ./configure 247 self.executeShellCommand('rm -rf '+os.path.join(self.petscdir.dir,self.arch.arch,'include','mpi*')+' '+os.path.join(self.petscdir.dir,self.arch.arch,'include','opa*'), log = self.log) 248 249 self.setCompilers.pushLanguage('C') 250 compiler = self.setCompilers.getCompiler() 251 if compiler.endswith('mpicc') or compiler.endswith('mpiicc'): 252 try: 253 output = self.executeShellCommand(compiler + ' -show', log = self.log)[0] 254 compiler = output.split(' ')[0] 255 self.addDefine('MPICC_SHOW','"'+output.strip().replace('\n','\\\\n')+'"') 256 except: 257 self.addDefine('MPICC_SHOW','"Unavailable"') 258 else: 259 self.addDefine('MPICC_SHOW','"Unavailable"') 260 self.setCompilers.popLanguage() 261#----------------------------------------------------------------------------------------------------- 262 263 # Sometimes we need C compiler, even if built with C++ 264 self.setCompilers.pushLanguage('C') 265 self.addMakeMacro('CC_FLAGS',self.setCompilers.getCompilerFlags()) 266 self.setCompilers.popLanguage() 267 268 # And sometimes we need a C++ compiler even when PETSc is built with C 269 if hasattr(self.compilers, 'CXX'): 270 self.setCompilers.pushLanguage('Cxx') 271 self.addDefine('HAVE_CXX','1') 272 self.addMakeMacro('CXX_FLAGS',self.setCompilers.getCompilerFlags()) 273 self.setCompilers.popLanguage() 274 275 # C preprocessor values 276 self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS) 277 278 # compiler values 279 self.setCompilers.pushLanguage(self.languages.clanguage) 280 self.addMakeMacro('PCC',self.setCompilers.getCompiler()) 281 self.addMakeMacro('PCC_FLAGS',self.setCompilers.getCompilerFlags()) 282 self.setCompilers.popLanguage() 283 # .o or .obj 284 self.addMakeMacro('CC_SUFFIX','o') 285 286 # executable linker values 287 self.setCompilers.pushLanguage(self.languages.clanguage) 288 pcc_linker = self.setCompilers.getLinker() 289 self.addMakeMacro('PCC_LINKER',pcc_linker) 290 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 291 self.setCompilers.popLanguage() 292 # '' for Unix, .exe for Windows 293 self.addMakeMacro('CC_LINKER_SUFFIX','') 294 295 if hasattr(self.compilers, 'FC'): 296 if self.framework.argDB['with-fortran-bindings']: 297 self.addDefine('HAVE_FORTRAN','1') 298 self.setCompilers.pushLanguage('FC') 299 # need FPPFLAGS in config/setCompilers 300 self.addMakeMacro('FPP_FLAGS',self.setCompilers.CPPFLAGS) 301 302 # compiler values 303 self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags()) 304 self.setCompilers.popLanguage() 305 # .o or .obj 306 self.addMakeMacro('FC_SUFFIX','o') 307 308 # executable linker values 309 self.setCompilers.pushLanguage('FC') 310 # Cannot have NAG f90 as the linker - so use pcc_linker as fc_linker 311 fc_linker = self.setCompilers.getLinker() 312 if config.setCompilers.Configure.isNAG(fc_linker, self.log): 313 self.addMakeMacro('FC_LINKER',pcc_linker) 314 else: 315 self.addMakeMacro('FC_LINKER',fc_linker) 316 self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 317 # apple requires this shared library linker flag on SOME versions of the os 318 if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1: 319 self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ') 320 self.setCompilers.popLanguage() 321 322 # F90 Modules 323 if self.setCompilers.fortranModuleIncludeFlag: 324 self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag) 325 else: # for non-f90 compilers like g77 326 self.addMakeMacro('FC_MODULE_FLAG', '-I') 327 if self.setCompilers.fortranModuleIncludeFlag: 328 self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag) 329 else: 330 self.addMakeMacro('FC','') 331 332 if hasattr(self.compilers, 'CUDAC'): 333 self.setCompilers.pushLanguage('CUDA') 334 self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags()) 335 self.setCompilers.popLanguage() 336 337 # shared library linker values 338 self.setCompilers.pushLanguage(self.languages.clanguage) 339 # need to fix BuildSystem to collect these separately 340 self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker()) 341 self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}') 342 self.setCompilers.popLanguage() 343 # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture 344 # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX 345 if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX: 346 self.addMakeMacro('SL_LINKER_SUFFIX', '') 347 self.addDefine('SLSUFFIX','""') 348 else: 349 self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt) 350 self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"') 351 352 self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}') 353 354#----------------------------------------------------------------------------------------------------- 355 356 # CONLY or CPP. We should change the PETSc makefiles to do this better 357 if self.languages.clanguage == 'C': lang = 'CONLY' 358 else: lang = 'CXXONLY' 359 self.addMakeMacro('PETSC_LANGUAGE',lang) 360 361 # real or complex 362 self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype) 363 # double or float 364 self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision) 365 366 if self.framework.argDB['with-batch']: 367 self.addMakeMacro('PETSC_WITH_BATCH','1') 368 369 # Test for compiler-specific macros that need to be defined. 370 if self.setCompilers.isCrayVector('CC', self.log): 371 self.addDefine('HAVE_CRAY_VECTOR','1') 372 373#----------------------------------------------------------------------------------------------------- 374 if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket') and self.headers.haveHeader('netinet/in.h'): 375 self.addDefine('USE_SOCKET_VIEWER','1') 376 if self.checkCompile('#include <sys/socket.h>','setsockopt(0,SOL_SOCKET,SO_REUSEADDR,0,0)'): 377 self.addDefine('HAVE_SO_REUSEADDR','1') 378 379#----------------------------------------------------------------------------------------------------- 380 # print include and lib for makefiles 381 self.framework.packages.reverse() 382 includes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')] 383 self.packagelibs = [] 384 for i in self.framework.packages: 385 if i.useddirectly: 386 self.addDefine('HAVE_'+i.PACKAGE.replace('-','_'), 1) # ONLY list package if it is used directly by PETSc (and not only by another package) 387 if not isinstance(i.lib, list): 388 i.lib = [i.lib] 389 if i.linkedbypetsc: self.packagelibs.extend(i.lib) 390 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_LIB', self.libraries.toStringNoDupes(i.lib)) 391 if hasattr(i,'include'): 392 if not isinstance(i.include,list): 393 i.include = [i.include] 394 includes.extend(i.include) 395 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include)) 396 if self.framework.argDB['with-single-library']: 397 self.petsclib = '-lpetsc' 398 else: 399 self.petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys' 400 self.complibs = self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split() 401 self.PETSC_WITH_EXTERNAL_LIB = self.libraries.toStringNoDupes(['-L'+os.path.join(self.petscdir.dir,self.arch.arch,'lib'), self.petsclib]+self.packagelibs+self.complibs) 402 self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(self.packagelibs+self.complibs) 403 if self.framework.argDB['prefix'] and self.setCompilers.CSharedLinkerFlag not in ['-L']: 404 string.replace(self.PETSC_EXTERNAL_LIB_BASIC,self.setCompilers.CSharedLinkerFlag+os.path.join(self.petscdir.dir,self.arch.arch,'lib'),self.setCompilers.CSharedLinkerFlag+os.path.join(self.installdir.dir,'lib')) 405 406 self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',self.PETSC_EXTERNAL_LIB_BASIC) 407 self.allincludes = self.headers.toStringNoDupes(includes) 408 self.addMakeMacro('PETSC_CC_INCLUDES',self.allincludes) 409 self.PETSC_CC_INCLUDES = self.allincludes 410 if hasattr(self.compilers, 'FC'): 411 if self.compilers.fortranIsF90: 412 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(includes,includes)) 413 else: 414 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(includes)) 415 416 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir.dir,'lib')+'"') 417 418 if self.framework.argDB['with-single-library']: 419 # overrides the values set in conf/variables 420 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 421 self.addMakeMacro('SHLIBS','libpetsc') 422 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 423 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 424 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 425 self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc') 426 self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.PETSC_WITH_EXTERNAL_LIB) 427 self.addDefine('USE_SINGLE_LIBRARY', '1') 428 if self.sharedlibraries.useShared: 429 self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 430 self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 431 self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 432 self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 433 self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 434 self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 435 self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 436 self.addMakeMacro('PETSC_TAO_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 437 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 438 self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 439 self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 440 else: 441 self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 442 self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 443 self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}') 444 self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}') 445 self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}') 446 self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}') 447 self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 448 self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}') 449 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 450 self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 451 self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}') 452 453 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 454 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 455 456# add a makefile endtry for display 457 if self.framework.argDB['with-display']: 458 self.addMakeMacro('DISPLAY',self.framework.argDB['with-display']) 459 460 # add a makefile entry for configure options 461 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 462 return 463 464 def dumpConfigInfo(self): 465 import time 466 fd = file(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 467 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')+'";\n') 468 fd.close() 469 return 470 471 def dumpMachineInfo(self): 472 import platform 473 import time 474 import script 475 def escape(s): 476 return s.replace('"',r'\"').replace(r'\ ',r'\\ ') 477 fd = file(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 478 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 479 fd.write('\"-----------------------------------------\\n\"\n') 480 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (time.ctime(time.time()), platform.node())) 481 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 482 fd.write('\"Using PETSc directory: %s\\n\"\n' % (escape(self.installdir.petscDir))) 483 fd.write('\"Using PETSc arch: %s\\n\"\n' % (escape(self.installdir.petscArch))) 484 fd.write('\"-----------------------------------------\\n\";\n') 485 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 486 self.setCompilers.pushLanguage(self.languages.clanguage) 487 fd.write('\"Using C compiler: %s %s \\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()))) 488 self.setCompilers.popLanguage() 489 if hasattr(self.compilers, 'FC'): 490 self.setCompilers.pushLanguage('FC') 491 fd.write('\"Using Fortran compiler: %s %s %s\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()), escape(self.setCompilers.CPPFLAGS))) 492 self.setCompilers.popLanguage() 493 fd.write('\"-----------------------------------------\\n\";\n') 494 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 495 fd.write('\"Using include paths: %s\\n\"\n' % (escape(self.PETSC_CC_INCLUDES).replace(self.petscdir.dir,self.installdir.petscDir).replace(self.arch.arch,self.installdir.petscArch))) 496 fd.write('\"-----------------------------------------\\n\";\n') 497 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 498 self.setCompilers.pushLanguage(self.languages.clanguage) 499 fd.write('\"Using C linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 500 self.setCompilers.popLanguage() 501 if hasattr(self.compilers, 'FC'): 502 self.setCompilers.pushLanguage('FC') 503 fd.write('\"Using Fortran linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 504 self.setCompilers.popLanguage() 505 fd.write('\"Using libraries: %s%s -L%s %s %s\\n\"\n' % (escape(self.setCompilers.CSharedLinkerFlag), escape(os.path.join(self.installdir.petscDir, self.installdir.petscArch, 'lib')), escape(os.path.join(self.installdir.petscDir, self.installdir.petscArch, 'lib')), escape(self.petsclib), escape(self.PETSC_EXTERNAL_LIB_BASIC))) 506 fd.write('\"-----------------------------------------\\n\";\n') 507 fd.close() 508 return 509 510 def dumpCMakeConfig(self): 511 ''' 512 Writes configuration-specific values to ${PETSC_ARCH}/lib/petsc/conf/PETScBuildInternal.cmake. 513 This file is private to PETSc and should not be included by third parties 514 (a suitable file can be produced later by CMake, but this is not it). 515 ''' 516 def cmakeset(fd,key,val=True): 517 if val == True: val = 'YES' 518 if val == False: val = 'NO' 519 fd.write('set (' + key + ' ' + val + ')\n') 520 def ensurelist(a): 521 if isinstance(a,list): 522 return a 523 else: 524 return [a] 525 def libpath(lib): 526 'Returns a search path if that is what this item provides, else "" which will be cleaned out later' 527 if not isinstance(lib,str): return '' 528 if lib.startswith('-L'): return lib[2:] 529 if lib.startswith('-R'): return lib[2:] 530 if lib.startswith('-Wl,-rpath,'): 531 # This case occurs when an external package needs a specific system library that is normally provided by the compiler. 532 # In other words, the -L path is builtin to the wrapper or compiler, here we provide it so that CMake can locate the 533 # corresponding library. 534 return lib[len('-Wl,-rpath,'):] 535 if lib.startswith('-'): return '' 536 return os.path.dirname(lib) 537 def cleanlib(lib): 538 'Returns a library name if that is what this item provides, else "" which will be cleaned out later' 539 if not isinstance(lib,str): return '' 540 if lib.startswith('-l'): return lib[2:] 541 if lib.startswith('-Wl') or lib.startswith('-L'): return '' 542 lib = os.path.splitext(os.path.basename(lib))[0] 543 if lib.startswith('lib'): return lib[3:] 544 return lib 545 def nub(lst): 546 'Return a list containing the first occurrence of each unique element' 547 unique = [] 548 for elem in lst: 549 if elem not in unique and elem != '': 550 unique.append(elem) 551 return unique 552 try: reversed # reversed was added in Python-2.4 553 except NameError: 554 def reversed(lst): return lst[::-1] 555 def nublast(lst): 556 'Return a list containing the last occurrence of each unique entry in a list' 557 return reversed(nub(reversed(lst))) 558 def cmakeexpand(varname): 559 return r'"${' + varname + r'}"' 560 def uniqextend(lst,new): 561 for x in ensurelist(new): 562 if x not in lst: 563 lst.append(x) 564 def notstandardinclude(path): 565 return path not in '/usr/include'.split() # /usr/local/include is not automatically included on FreeBSD 566 def writeMacroDefinitions(fd): 567 if self.mpi.usingMPIUni: 568 cmakeset(fd,'PETSC_HAVE_MPIUNI') 569 for pkg in self.framework.packages: 570 if pkg.useddirectly: 571 cmakeset(fd,'PETSC_HAVE_' + pkg.PACKAGE.replace('-','_')) 572 for pair in pkg.defines.items(): 573 if pair[0].startswith('HAVE_') and pair[1]: 574 cmakeset(fd, self.framework.getFullDefineName(pkg, pair[0]), pair[1]) 575 for name,val in self.functions.defines.items(): 576 cmakeset(fd,'PETSC_'+name,val) 577 for dct in [self.defines, self.libraryoptions.defines]: 578 for k,v in dct.items(): 579 if k.startswith('USE_'): 580 cmakeset(fd,'PETSC_' + k, v) 581 cmakeset(fd,'PETSC_USE_COMPLEX', self.scalartypes.scalartype == 'complex') 582 cmakeset(fd,'PETSC_USE_REAL_' + self.scalartypes.precision.upper()) 583 cmakeset(fd,'PETSC_CLANGUAGE_'+self.languages.clanguage) 584 if hasattr(self.compilers, 'FC'): 585 cmakeset(fd,'PETSC_HAVE_FORTRAN') 586 if self.compilers.fortranIsF90: 587 cmakeset(fd,'PETSC_USING_F90') 588 if self.compilers.fortranIsF2003: 589 cmakeset(fd,'PETSC_USING_F2003') 590 if hasattr(self.compilers, 'CXX'): 591 cmakeset(fd,'PETSC_HAVE_CXX') 592 if self.sharedlibraries.useShared: 593 cmakeset(fd,'BUILD_SHARED_LIBS') 594 def writeBuildFlags(fd): 595 def extendby(lib): 596 libs = ensurelist(lib) 597 lib_paths.extend(map(libpath,libs)) 598 lib_libs.extend(map(cleanlib,libs)) 599 lib_paths = [] 600 lib_libs = [] 601 includes = [] 602 libvars = [] 603 for pkg in self.framework.packages: 604 if pkg.linkedbypetsc: 605 extendby(pkg.lib) 606 uniqextend(includes,pkg.include) 607 extendby(self.libraries.math) 608 extendby(self.libraries.rt) 609 extendby(self.compilers.flibs) 610 extendby(self.compilers.cxxlibs) 611 extendby(self.compilers.LIBS.split()) 612 for libname in nublast(lib_libs): 613 libvar = 'PETSC_' + libname.upper() + '_LIB' 614 addpath = '' 615 for lpath in nublast(lib_paths): 616 addpath += '"' + str(lpath) + '" ' 617 fd.write('find_library (' + libvar + ' ' + libname + ' HINTS ' + addpath + ')\n') 618 libvars.append(libvar) 619 fd.write('mark_as_advanced (' + ' '.join(libvars) + ')\n') 620 fd.write('set (PETSC_PACKAGE_LIBS ' + ' '.join(map(cmakeexpand,libvars)) + ')\n') 621 includes = filter(notstandardinclude,includes) 622 fd.write('set (PETSC_PACKAGE_INCLUDES ' + ' '.join(map(lambda i: '"'+i+'"',includes)) + ')\n') 623 fd = open(os.path.join(self.arch.arch,'lib','petsc','conf','PETScBuildInternal.cmake'), 'w') 624 writeMacroDefinitions(fd) 625 writeBuildFlags(fd) 626 fd.close() 627 return 628 629 def dumpCMakeLists(self): 630 import sys 631 if sys.version_info >= (2,4): 632 import cmakegen 633 try: 634 cmakegen.main(self.petscdir.dir, log=self.framework.log) 635 except (OSError), e: 636 self.framework.logPrint('Generating CMakeLists.txt failed:\n' + str(e)) 637 else: 638 self.framework.logPrint('Skipping cmakegen due to old python version: ' +str(sys.version_info) ) 639 640 def cmakeBoot(self): 641 import sys 642 self.cmakeboot_success = False 643 if sys.version_info >= (2,4) and hasattr(self.cmake,'cmake'): 644 oldRead = self.argDB.readonly 645 self.argDB.readonly = True 646 try: 647 import cmakeboot 648 self.cmakeboot_success = cmakeboot.main(petscdir=self.petscdir.dir,petscarch=self.arch.arch,argDB=self.argDB,framework=self.framework,log=self.framework.log) 649 except (OSError), e: 650 self.framework.logPrint('Booting CMake in PETSC_ARCH failed:\n' + str(e)) 651 except (ImportError, KeyError), e: 652 self.framework.logPrint('Importing cmakeboot failed:\n' + str(e)) 653 self.argDB.readonly = oldRead 654 if self.cmakeboot_success: 655 if hasattr(self.compilers, 'FC') and self.compilers.fortranIsF90 and not self.setCompilers.fortranModuleOutputFlag: 656 self.framework.logPrint('CMake configured successfully, but could not be used by default because of missing fortranModuleOutputFlag\n') 657 else: 658 self.framework.logPrint('CMake configured successfully, using as default build\n') 659 self.addMakeMacro('PETSC_BUILD_USING_CMAKE',1) 660 else: 661 self.framework.logPrint('CMake configuration was unsuccessful\n') 662 else: 663 self.framework.logPrint('Skipping cmakeboot due to old python version: ' +str(sys.version_info) ) 664 return 665 666 def configurePrefetch(self): 667 '''Sees if there are any prefetch functions supported''' 668 if config.setCompilers.Configure.isSolaris(self.log) or self.framework.argDB['with-ios'] or not self.framework.argDB['with-prefetch']: 669 self.addDefine('Prefetch(a,b,c)', ' ') 670 return 671 self.pushLanguage(self.languages.clanguage) 672 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 673 # The Intel Intrinsics manual [1] specifies the prototype 674 # 675 # void _mm_prefetch(char const *a, int sel); 676 # 677 # but other vendors seem to insist on using subtly different 678 # prototypes, including void* for the pointer, and an enum for 679 # sel. These are both reasonable changes, but negatively impact 680 # portability. 681 # 682 # [1] http://software.intel.com/file/6373 683 self.addDefine('HAVE_XMMINTRIN_H', 1) 684 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 685 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 686 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 687 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 688 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 689 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 690 self.addDefine('HAVE_XMMINTRIN_H', 1) 691 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 692 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 693 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 694 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 695 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 696 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 697 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 698 # 699 # The value of rw is a compile-time constant one or zero; one 700 # means that the prefetch is preparing for a write to the memory 701 # address and zero, the default, means that the prefetch is 702 # preparing for a read. The value locality must be a compile-time 703 # constant integer between zero and three. A value of zero means 704 # that the data has no temporal locality, so it need not be left 705 # in the cache after the access. A value of three means that the 706 # data has a high degree of temporal locality and should be left 707 # in all levels of cache possible. Values of one and two mean, 708 # respectively, a low or moderate degree of temporal locality. 709 # 710 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 711 # hints. Using macros for these values in necessary since some 712 # compilers require an enum. 713 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 714 self.addDefine('PREFETCH_HINT_NTA', '0') 715 self.addDefine('PREFETCH_HINT_T0', '3') 716 self.addDefine('PREFETCH_HINT_T1', '2') 717 self.addDefine('PREFETCH_HINT_T2', '1') 718 else: 719 self.addDefine('Prefetch(a,b,c)', ' ') 720 self.popLanguage() 721 722 def configureAtoll(self): 723 '''Checks if atoll exists''' 724 if self.checkLink('#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>','long v = atoll("25")') or self.checkLink ('#include <stdlib.h>','long v = atoll("25")'): 725 self.addDefine('HAVE_ATOLL', '1') 726 727 def configureUnused(self): 728 '''Sees if __attribute((unused)) is supported''' 729 if self.framework.argDB['with-ios']: 730 self.addDefine('UNUSED', ' ') 731 return 732 self.pushLanguage(self.languages.clanguage) 733 if self.checkLink('__attribute((unused)) static int myfunc(__attribute((unused)) void *name){ return 1;}', 'int i = 0;\nint j = myfunc(&i);\ntypedef void* atype;\n__attribute((unused)) atype a;\n'): 734 self.addDefine('UNUSED', '__attribute((unused))') 735 else: 736 self.addDefine('UNUSED', ' ') 737 self.popLanguage() 738 739 def configureIsatty(self): 740 '''Check if the Unix C function isatty() works correctly 741 Actually just assumes it does not work correctly on batch systems''' 742 if not self.framework.argDB['with-batch']: 743 self.addDefine('USE_ISATTY',1) 744 745 def configureDeprecated(self): 746 '''Check if __attribute((deprecated)) is supported''' 747 self.pushLanguage(self.languages.clanguage) 748 ## Recent versions of gcc and clang support __attribute((deprecated("string argument"))), which is very useful, but 749 ## Intel has conspired to make a supremely environment-sensitive compiler. The Intel compiler looks at the gcc 750 ## executable in the environment to determine the language compatibility that it should attempt to emulate. Some 751 ## important Cray installations have built PETSc using the Intel compiler, but with a newer gcc module loaded (e.g., 752 ## 4.7). Thus at PETSc configure time, the Intel compiler decides to support the string argument, but the gcc 753 ## found in the default user environment is older and does not support the argument. If GCC and Intel were cool 754 ## like Clang and supported __has_attribute, we could avoid configure tests entirely, but they don't. And that is 755 ## why we can't have nice things. 756 # 757 # if self.checkCompile("""__attribute((deprecated("Why you shouldn't use myfunc"))) static int myfunc(void) { return 1;}""", ''): 758 # self.addDefine('DEPRECATED(why)', '__attribute((deprecated(why)))') 759 if self.checkCompile("""__attribute((deprecated)) static int myfunc(void) { return 1;}""", ''): 760 self.addDefine('DEPRECATED(why)', '__attribute((deprecated))') 761 else: 762 self.addDefine('DEPRECATED(why)', ' ') 763 self.popLanguage() 764 765 def configureAlign(self): 766 '''Check if __attribute(align) is supported''' 767 filename = 'conftestalign' 768 includes = ''' 769#include <sys/types.h> 770#if STDC_HEADERS 771#include <stdlib.h> 772#include <stdio.h> 773#include <stddef.h> 774#endif\n''' 775 body = ''' 776struct mystruct {int myint;} __attribute((aligned(16))); 777FILE *f = fopen("'''+filename+'''", "w"); 778if (!f) exit(1); 779fprintf(f, "%lu\\n", (unsigned long)sizeof(struct mystruct)); 780''' 781 if 'known-has-attribute-aligned' in self.argDB: 782 if self.argDB['known-has-attribute-aligned']: 783 size = 16 784 else: 785 size = -3 786 elif not self.argDB['with-batch']: 787 self.pushLanguage(self.languages.clanguage) 788 try: 789 if self.checkRun(includes, body) and os.path.exists(filename): 790 f = file(filename) 791 size = int(f.read()) 792 f.close() 793 os.remove(filename) 794 else: 795 size = -4 796 except: 797 size = -1 798 self.framework.logPrint('Error checking attribute(aligned)') 799 self.popLanguage() 800 else: 801 self.framework.addBatchInclude(['#include <stdlib.h>', '#include <stdio.h>', '#include <sys/types.h>','struct mystruct {int myint;} __attribute((aligned(16)));']) 802 self.framework.addBatchBody('fprintf(output, " \'--known-has-attribute-aligned=%d\',\\n", sizeof(struct mystruct)==16);') 803 size = -2 804 if size == 16: 805 self.addDefine('ATTRIBUTEALIGNED(size)', '__attribute((aligned (size)))') 806 self.addDefine('HAVE_ATTRIBUTEALIGNED', 1) 807 else: 808 self.framework.logPrint('incorrect alignment. Found alignment:'+ str(size)) 809 self.addDefine('ATTRIBUTEALIGNED(size)', ' ') 810 return 811 812 def configureExpect(self): 813 '''Sees if the __builtin_expect directive is supported''' 814 self.pushLanguage(self.languages.clanguage) 815 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 816 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 817 self.popLanguage() 818 819 def configureFunctionName(self): 820 '''Sees if the compiler supports __func__ or a variant.''' 821 def getFunctionName(lang): 822 name = '"unknown"' 823 self.pushLanguage(lang) 824 for fname in ['__func__','__FUNCTION__']: 825 code = "if ("+fname+"[0] != 'm') return 1;" 826 if self.checkCompile('',code) and self.checkLink('',code): 827 name = fname 828 break 829 self.popLanguage() 830 return name 831 langs = [] 832 833 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 834 if hasattr(self.compilers, 'CXX'): 835 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 836 837 def configureIntptrt(self): 838 '''Determine what to use for uintptr_t''' 839 def staticAssertSizeMatchesVoidStar(inc,typename): 840 # The declaration is an error if either array size is negative. 841 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 842 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 843 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 844 self.pushLanguage(self.languages.clanguage) 845 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 846 self.addDefine('UINTPTR_T', 'uintptr_t') 847 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 848 self.addDefine('UINTPTR_T', 'unsigned long long') 849 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 850 self.addDefine('UINTPTR_T', 'size_t') 851 elif staticAssertSizeMatchesVoidStar('','unsigned long'): 852 self.addDefine('UINTPTR_T', 'unsigned long') 853 elif staticAssertSizeMatchesVoidStar('','unsigned'): 854 self.addDefine('UINTPTR_T', 'unsigned') 855 else: 856 raise RuntimeError('Could not find any unsigned integer type matching void*') 857 self.popLanguage() 858 859 def configureRTLDDefault(self): 860 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 861 self.addDefine('RTLD_DEFAULT','1') 862 return 863 864 def configureSolaris(self): 865 '''Solaris specific stuff''' 866 if os.path.isdir(os.path.join('/usr','ucblib')): 867 try: 868 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 869 except AttributeError: 870 flag = None 871 if flag is None: 872 self.compilers.LIBS += ' -L/usr/ucblib' 873 else: 874 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 875 return 876 877 def configureLinux(self): 878 '''Linux specific stuff''' 879 # TODO: Test for this by mallocing an odd number of floats and checking the address 880 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 881 return 882 883 def configureWin32(self): 884 '''Win32 non-cygwin specific stuff''' 885 kernel32=0 886 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 887 self.addDefine('HAVE_WINDOWS_H',1) 888 self.addDefine('HAVE_GETCOMPUTERNAME',1) 889 kernel32=1 890 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 891 self.addDefine('HAVE_WINDOWS_H',1) 892 self.addDefine('HAVE_GETCOMPUTERNAME',1) 893 kernel32=1 894 if kernel32: 895 if self.framework.argDB['with-windows-graphics']: 896 self.addDefine('USE_WINDOWS_GRAPHICS',1) 897 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 898 self.addDefine('HAVE_LOADLIBRARY',1) 899 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 900 self.addDefine('HAVE_GETPROCADDRESS',1) 901 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 902 self.addDefine('HAVE_FREELIBRARY',1) 903 if self.checkLink('#include <Windows.h>','GetLastError()'): 904 self.addDefine('HAVE_GETLASTERROR',1) 905 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 906 self.addDefine('HAVE_SETLASTERROR',1) 907 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 908 self.addDefine('USE_MICROSOFT_TIME',1) 909 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 910 self.addDefine('HAVE_GET_USER_NAME',1) 911 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 912 self.addDefine('HAVE_GET_USER_NAME',1) 913 914 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 915 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 916 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 917 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 918 919 self.types.check('int32_t', 'int') 920 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 921 self.addTypedef('int', 'uid_t') 922 self.addTypedef('int', 'gid_t') 923 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 924 self.framework.addDefine('R_OK', '04') 925 self.framework.addDefine('W_OK', '02') 926 self.framework.addDefine('X_OK', '01') 927 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 928 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 929 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 930 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 931 self.addDefine('HAVE_LARGE_INTEGER_U',1) 932 933 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 934 if self.checkCompile('#include <Windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'): 935 self.addDefine('HAVE_O_BINARY',1) 936 937 if self.compilers.CC.find('win32fe') >= 0: 938 self.addDefine('HAVE_WINDOWS_COMPILERS',1) 939 self.addDefine('PATH_SEPARATOR','\';\'') 940 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 941 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 942 self.addDefine('CANNOT_START_DEBUGGER',1) 943 (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.installdir.petscDir, log = self.log) 944 self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"') 945 (petscdir,error,status) = self.executeShellCommand('cygpath -m '+self.installdir.petscDir, log = self.log) 946 self.addMakeMacro('wPETSC_DIR',petscdir) 947 else: 948 self.addDefine('PATH_SEPARATOR','\':\'') 949 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 950 self.addDefine('DIR_SEPARATOR','\'/\'') 951 self.addDefine('DIR','"'+self.installdir.petscDir+'"') 952 self.addMakeMacro('wPETSC_DIR',self.installdir.petscDir) 953 self.addDefine('ARCH','"'+self.installdir.petscArch+'"') 954 return 955 956#----------------------------------------------------------------------------------------------------- 957 def configureCygwinBrokenPipe(self): 958 '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make 959 http://cygwin.com/ml/cygwin/2013-05/msg00340.html ''' 960 if config.setCompilers.Configure.isCygwin(self.log): 961 import platform 962 import re 963 r=re.compile("([0-9]+).([0-9]+).([0-9]+)") 964 m=r.match(platform.release()) 965 major=int(m.group(1)) 966 minor=int(m.group(2)) 967 subminor=int(m.group(3)) 968 if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)): 969 self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1') 970 return 971 972#----------------------------------------------------------------------------------------------------- 973 def configureDefaultArch(self): 974 conffile = os.path.join('lib','petsc','conf', 'petscvariables') 975 if self.framework.argDB['with-default-arch']: 976 fd = file(conffile, 'w') 977 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 978 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 979 fd.write('include '+os.path.join('$(PETSC_DIR)','$(PETSC_ARCH)','lib','petsc','conf','petscvariables')+'\n') 980 fd.close() 981 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 982 elif os.path.isfile(conffile): 983 try: 984 os.unlink(conffile) 985 except: 986 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 987 return 988 989#----------------------------------------------------------------------------------------------------- 990 def configureScript(self): 991 '''Output a script in the conf directory which will reproduce the configuration''' 992 import nargs 993 import sys 994 scriptName = os.path.join(self.arch.arch,'lib','petsc','conf', 'reconfigure-'+self.arch.arch+'.py') 995 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 996 if 'with-clean' in args: 997 del args['with-clean'] 998 if 'configModules' in args: 999 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 1000 del args['configModules'] 1001 if 'optionsModule' in args: 1002 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions': 1003 del args['optionsModule'] 1004 if not 'PETSC_ARCH' in args: 1005 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 1006 f = file(scriptName, 'w') 1007 f.write('#!'+sys.executable+'\n') 1008 f.write('if __name__ == \'__main__\':\n') 1009 f.write(' import sys\n') 1010 f.write(' import os\n') 1011 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 1012 f.write(' import configure\n') 1013 # pretty print repr(args.values()) 1014 f.write(' configure_options = [\n') 1015 for itm in sorted(args.values()): 1016 f.write(' \''+str(itm)+'\',\n') 1017 f.write(' ]\n') 1018 f.write(' configure.petsc_configure(configure_options)\n') 1019 f.close() 1020 try: 1021 os.chmod(scriptName, 0775) 1022 except OSError, e: 1023 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 1024 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 1025 return 1026 1027 def configureInstall(self): 1028 '''Setup the directories for installation''' 1029 if self.framework.argDB['prefix']: 1030 self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\ 1031 '-@echo "'+self.installdir.installSudo+'make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 1032 '-@echo "========================================="']) 1033 else: 1034 self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\ 1035 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\ 1036 '-@echo "========================================="']) 1037 return 1038 1039 def configureGCOV(self): 1040 if self.framework.argDB['with-gcov']: 1041 self.addDefine('USE_GCOV','1') 1042 return 1043 1044 def configureFortranFlush(self): 1045 if hasattr(self.compilers, 'FC'): 1046 for baseName in ['flush','flush_']: 1047 if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1): 1048 self.addDefine('HAVE_'+baseName.upper(), 1) 1049 return 1050 1051 def configureViewFromOptions(self): 1052 if not self.framework.argDB['with-viewfromoptions']: 1053 self.addDefine('SKIP_VIEWFROMOPTIONS',1) 1054 1055 def postProcessPackages(self): 1056 postPackages=[] 1057 for i in self.framework.packages: 1058 if hasattr(i,'postProcess'): postPackages.append(i) 1059 if postPackages: 1060 # ctetgen needs petsc conf files. so attempt to create them early 1061 self.framework.dumpConfFiles() 1062 # tacky fix for dependency of Aluimia on Pflotran; requested via petsc-dev Matt provide a correct fix 1063 for i in postPackages: 1064 if i.name.upper() in ['PFLOTRAN']: 1065 i.postProcess() 1066 postPackages.remove(i) 1067 for i in postPackages: i.postProcess() 1068 for i in postPackages: 1069 if i.installedpetsc: 1070 self.installed = 1 1071 break 1072 return 1073 1074 def configure(self): 1075 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 1076 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 1077 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 1078 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 1079 if self.framework.argDB['prefix'] and self.framework.argDB['prefix'].find(' ') > -1: 1080 raise RuntimeError('Your --prefix '+self.framework.argDB['prefix']+' has spaces in it; this is not allowed.\n Use a --prefix that does not have spaces in it') 1081 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],os.path.join(self.petscdir.dir,self.arch.arch)): 1082 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 1083 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 1084 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 1085 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscvariables') 1086 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscrules') 1087 if self.libraries.math is None: 1088 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 1089 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 1090 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 1091 self.executeTest(self.configureRTLDDefault) 1092 self.executeTest(self.configurePrefetch) 1093 self.executeTest(self.configureUnused) 1094 self.executeTest(self.configureDeprecated) 1095 self.executeTest(self.configureIsatty) 1096 self.executeTest(self.configureExpect); 1097 self.executeTest(self.configureAlign); 1098 self.executeTest(self.configureFunctionName); 1099 self.executeTest(self.configureIntptrt); 1100 self.executeTest(self.configureSolaris) 1101 self.executeTest(self.configureLinux) 1102 self.executeTest(self.configureWin32) 1103 self.executeTest(self.configureCygwinBrokenPipe) 1104 self.executeTest(self.configureDefaultArch) 1105 self.executeTest(self.configureScript) 1106 self.executeTest(self.configureInstall) 1107 self.executeTest(self.configureGCOV) 1108 self.executeTest(self.configureFortranFlush) 1109 self.executeTest(self.configureAtoll) 1110 self.executeTest(self.configureViewFromOptions) 1111 1112 self.Dump() 1113 self.dumpConfigInfo() 1114 self.dumpMachineInfo() 1115 self.dumpCMakeConfig() 1116 self.dumpCMakeLists() 1117 # need to save the current state of BuildSystem so that postProcess() packages can read it in and perhaps run make install 1118 self.framework.storeSubstitutions(self.framework.argDB) 1119 self.framework.argDB['configureCache'] = cPickle.dumps(self.framework) 1120 self.framework.argDB.save(force = True) 1121 self.cmakeBoot() 1122 self.DumpPkgconfig() 1123 self.DumpModule() 1124 self.postProcessPackages() 1125 self.framework.log.write('================================================================================\n') 1126 self.logClear() 1127 return 1128