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