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