1import config.base 2 3import os 4import re 5 6class Configure(config.base.Configure): 7 def __init__(self, framework): 8 config.base.Configure.__init__(self, framework) 9 self.headerPrefix = 'PETSC' 10 self.substPrefix = 'PETSC' 11 self.defineAutoconfMacros() 12 return 13 14 def __str2__(self): 15 desc = [] 16 desc.append('xxx=========================================================================xxx') 17 desc.append(' Configure stage complete. Now build PETSc libraries with:') 18 desc.append(' make PETSC_DIR='+self.petscdir.dir+' PETSC_ARCH='+self.arch.arch+' all') 19 desc.append('xxx=========================================================================xxx') 20 return '\n'.join(desc)+'\n' 21 22 def setupHelp(self, help): 23 import nargs 24 help.addArgument('PETSc', '-prefix=<dir>', nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)')) 25 help.addArgument('Windows','-with-windows-graphics=<bool>', nargs.ArgBool(None, 1,'Enable check for Windows Graphics')) 26 help.addArgument('PETSc', '-with-default-arch=<bool>', nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH')) 27 help.addArgument('PETSc','-with-single-library=<bool>', nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library')) 28 help.addArgument('PETSc', '-with-iphone=<bool>', nargs.ArgBool(None, 0, 'Build an iPhone version of PETSc')) 29 return 30 31 def setupDependencies(self, framework): 32 config.base.Configure.setupDependencies(self, framework) 33 self.setCompilers = framework.require('config.setCompilers', self) 34 self.arch = framework.require('PETSc.utilities.arch', self.setCompilers) 35 self.petscdir = framework.require('PETSc.utilities.petscdir', self.setCompilers) 36 self.languages = framework.require('PETSc.utilities.languages',self.setCompilers) 37 self.debugging = framework.require('PETSc.utilities.debugging',self.setCompilers) 38 self.make = framework.require('PETSc.utilities.Make', self) 39 self.CHUD = framework.require('PETSc.utilities.CHUD', self) 40 self.compilers = framework.require('config.compilers', self) 41 self.types = framework.require('config.types', self) 42 self.headers = framework.require('config.headers', self) 43 self.functions = framework.require('config.functions', self) 44 self.libraries = framework.require('config.libraries', self) 45 if os.path.isdir(os.path.join('config', 'PETSc')): 46 for d in ['utilities', 'packages']: 47 for utility in os.listdir(os.path.join('config', 'PETSc', d)): 48 (utilityName, ext) = os.path.splitext(utility) 49 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 50 utilityObj = self.framework.require('PETSc.'+d+'.'+utilityName, self) 51 utilityObj.headerPrefix = self.headerPrefix 52 utilityObj.archProvider = self.arch 53 utilityObj.languageProvider = self.languages 54 utilityObj.installDirProvider = self.petscdir 55 setattr(self, utilityName.lower(), utilityObj) 56 self.qd = framework.require('PETSc.packages.qd', self) 57 self.qd.archProvider = self.arch 58 self.qd.precisionProvider = self.scalartypes 59 self.qd.installDirProvider= self.petscdir 60 61 for package in config.packages.all: 62 if not package == 'PETSc': 63 packageObj = framework.require('config.packages.'+package, self) 64 packageObj.archProvider = self.arch 65 packageObj.languageProvider = self.languages 66 packageObj.installDirProvider = self.petscdir 67 setattr(self, package.lower(), packageObj) 68 # Force blaslapack to depend on scalarType so precision is set before BlasLapack is built 69 framework.require('PETSc.utilities.scalarTypes', self.blaslapack) 70 self.blaslapack.precisionProvider = self.scalartypes 71 72 self.compilers.headerPrefix = self.headerPrefix 73 self.types.headerPrefix = self.headerPrefix 74 self.headers.headerPrefix = self.headerPrefix 75 self.functions.headerPrefix = self.headerPrefix 76 self.libraries.headerPrefix = self.headerPrefix 77 self.blaslapack.headerPrefix = self.headerPrefix 78 self.mpi.headerPrefix = self.headerPrefix 79 headersC = map(lambda name: name+'.h', ['dos', 'endian', 'fcntl', 'float', 'io', 'limits', 'malloc', 'pwd', 'search', 'strings', 80 'unistd', 'machine/endian', 'sys/param', 'sys/procfs', 'sys/resource', 81 'sys/systeminfo', 'sys/times', 'sys/utsname','string', 'stdlib','memory', 82 'sys/socket','sys/wait','netinet/in','netdb','Direct','time','Ws2tcpip','sys/types', 83 'WindowsX', 'cxxabi','float','ieeefp','stdint','fenv']) 84 functions = ['access', '_access', 'clock', 'drand48', 'getcwd', '_getcwd', 'getdomainname', 'gethostname', 'getpwuid', 85 'gettimeofday', 'getwd', 'memalign', 'memmove', 'mkstemp', 'popen', 'PXFGETARG', 'rand', 'getpagesize', 86 'readlink', 'realpath', 'sigaction', 'signal', 'sigset', 'nanosleep', 'usleep', 'sleep', '_sleep', 'socket', 87 'times', 'gethostbyname', 'uname','snprintf','_snprintf','_fullpath','lseek','_lseek','time','fork','stricmp', 88 'strcasecmp', 'bzero', 'dlopen', 'dlsym', 'dlclose', 'dlerror', 89 '_intel_fast_memcpy','_intel_fast_memset'] 90 libraries1 = [(['socket', 'nsl'], 'socket'), (['fpe'], 'handle_sigfpes')] 91 self.headers.headers.extend(headersC) 92 self.functions.functions.extend(functions) 93 self.libraries.libraries.extend(libraries1) 94 return 95 96 def defineAutoconfMacros(self): 97 self.hostMacro = 'dnl Version: 2.13\ndnl Variable: host_cpu\ndnl Variable: host_vendor\ndnl Variable: host_os\nAC_CANONICAL_HOST' 98 return 99 100 def Dump(self): 101 ''' Actually put the values into the configuration files ''' 102 # eventually everything between -- should be gone 103#----------------------------------------------------------------------------------------------------- 104 105 # Sometimes we need C compiler, even if built with C++ 106 self.setCompilers.pushLanguage('C') 107 self.addMakeMacro('CC_FLAGS',self.setCompilers.getCompilerFlags()) 108 self.setCompilers.popLanguage() 109 110 # C preprocessor values 111 self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS+self.CHUD.CPPFLAGS) 112 113 # compiler values 114 self.setCompilers.pushLanguage(self.languages.clanguage) 115 self.addMakeMacro('PCC',self.setCompilers.getCompiler()) 116 self.addMakeMacro('PCC_FLAGS',self.setCompilers.getCompilerFlags()) 117 self.setCompilers.popLanguage() 118 # .o or .obj 119 self.addMakeMacro('CC_SUFFIX','o') 120 121 # executable linker values 122 self.setCompilers.pushLanguage(self.languages.clanguage) 123 pcc_linker = self.setCompilers.getLinker() 124 self.addMakeMacro('PCC_LINKER',pcc_linker) 125 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 126 self.setCompilers.popLanguage() 127 # '' for Unix, .exe for Windows 128 self.addMakeMacro('CC_LINKER_SUFFIX','') 129 130 if hasattr(self.compilers, 'FC'): 131 self.setCompilers.pushLanguage('FC') 132 # need FPPFLAGS in config/setCompilers 133 self.addDefine('HAVE_FORTRAN','1') 134 self.addMakeMacro('FPP_FLAGS',self.setCompilers.CPPFLAGS) 135 136 # compiler values 137 self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags()) 138 self.setCompilers.popLanguage() 139 # .o or .obj 140 self.addMakeMacro('FC_SUFFIX','o') 141 142 # executable linker values 143 self.setCompilers.pushLanguage('FC') 144 # Cannot have NAG f90 as the linker - so use pcc_linker as fc_linker 145 fc_linker = self.setCompilers.getLinker() 146 if config.setCompilers.Configure.isNAG(fc_linker): 147 self.addMakeMacro('FC_LINKER',pcc_linker) 148 else: 149 self.addMakeMacro('FC_LINKER',fc_linker) 150 self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 151 # apple requires this shared library linker flag on SOME versions of the os 152 if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1: 153 self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ') 154 self.setCompilers.popLanguage() 155 156 # F90 Modules 157 if self.setCompilers.fortranModuleIncludeFlag: 158 self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag) 159 else: # for non-f90 compilers like g77 160 self.addMakeMacro('FC_MODULE_FLAG', '-I') 161 if self.setCompilers.fortranModuleIncludeFlag: 162 self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag) 163 else: 164 self.addMakeMacro('FC','') 165 166 if hasattr(self.compilers, 'CUDAC'): 167 self.setCompilers.pushLanguage('CUDA') 168 self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags()) 169 self.setCompilers.popLanguage() 170 171 # shared library linker values 172 self.setCompilers.pushLanguage(self.languages.clanguage) 173 # need to fix BuildSystem to collect these separately 174 self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker()) 175 self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}') 176 self.setCompilers.popLanguage() 177 # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture 178 # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX 179 if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX: 180 self.addMakeMacro('SL_LINKER_SUFFIX', '') 181 self.addDefine('SLSUFFIX','""') 182 else: 183 self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt) 184 self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"') 185 186 self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}') 187 188#----------------------------------------------------------------------------------------------------- 189 190 # CONLY or CPP. We should change the PETSc makefiles to do this better 191 if self.languages.clanguage == 'C': lang = 'CONLY' 192 else: lang = 'CXXONLY' 193 self.addMakeMacro('PETSC_LANGUAGE',lang) 194 195 # real or complex 196 self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype) 197 # double or float 198 self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision) 199 200 if self.framework.argDB['with-batch']: 201 self.addMakeMacro('PETSC_WITH_BATCH','1') 202 203 # Test for compiler-specific macros that need to be defined. 204 if self.setCompilers.isCray('CC'): 205 self.addDefine('HAVE_CRAYC','1') 206 207#----------------------------------------------------------------------------------------------------- 208 if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket'): 209 self.addDefine('USE_SOCKET_VIEWER','1') 210 211#----------------------------------------------------------------------------------------------------- 212 # print include and lib for makefiles 213 self.framework.packages.reverse() 214 includes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')] 215 libs = [] 216 for i in self.framework.packages: 217 if i.useddirectly: 218 self.addDefine('HAVE_'+i.PACKAGE, 1) # ONLY list package if it is used directly by PETSc (and not only by another package) 219 if not isinstance(i.lib, list): 220 i.lib = [i.lib] 221 libs.extend(i.lib) 222 self.addMakeMacro(i.PACKAGE+'_LIB', self.libraries.toStringNoDupes(i.lib)) 223 if hasattr(i,'include'): 224 if not isinstance(i.include,list): 225 i.include = [i.include] 226 includes.extend(i.include) 227 self.addMakeMacro(i.PACKAGE+'_INCLUDE',self.headers.toStringNoDupes(i.include)) 228 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) 229 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 230 self.addMakeMacro('PETSC_CC_INCLUDES',self.headers.toStringNoDupes(includes)) 231 self.PETSC_CC_INCLUDES = self.headers.toStringNoDupes(includes) 232 if hasattr(self.compilers, 'FC'): 233 if self.compilers.fortranIsF90: 234 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringModulesNoDupes(includes)) 235 236 self.addMakeMacro('DESTDIR',self.installdir) 237 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir,'lib')+'"') 238 239 if self.framework.argDB['with-single-library']: 240 # overrides the values set in conf/variables 241 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 242 self.addMakeMacro('PETSC_SYS_LIB_BASIC','-lpetsc') 243 self.addMakeMacro('PETSC_VEC_LIB_BASIC','-lpetsc') 244 self.addMakeMacro('PETSC_MAT_LIB_BASIC','-lpetsc') 245 self.addMakeMacro('PETSC_DM_LIB_BASIC','-lpetsc') 246 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 247 self.addMakeMacro('PETSC_SNES_LIB_BASIC','-lpetsc') 248 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 249 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 250 self.addMakeMacro('PETSC_CONTRIB_BASIC','-lpetsc') 251 self.addMakeMacro('SHLIBS','libpetsc') 252 self.addDefine('USE_SINGLE_LIBRARY', '1') 253 254 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 255 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 256 257 # add a makefile entry for configure options 258 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 259 return 260 261 def dumpConfigInfo(self): 262 import time 263 fd = file(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 264 fd.write('static const char *petscconfigureruntime = "'+time.ctime(time.time())+'";\n') 265 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')+'";\n') 266 fd.close() 267 return 268 269 def dumpMachineInfo(self): 270 import platform 271 import time 272 import script 273 fd = file(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 274 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 275 fd.write('\"-----------------------------------------\\n\"\n') 276 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (time.ctime(time.time()), platform.node())) 277 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 278 fd.write('\"Using PETSc directory: %s\\n\"\n' % (self.petscdir.dir)) 279 fd.write('\"Using PETSc arch: %s\\n\"\n' % (self.arch.arch)) 280 fd.write('\"-----------------------------------------\\n\";\n') 281 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 282 self.setCompilers.pushLanguage(self.languages.clanguage) 283 fd.write('\"Using C compiler: %s %s ${COPTFLAGS} ${CFLAGS}\\n\"\n' % (self.setCompilers.getCompiler(), self.setCompilers.getCompilerFlags())) 284 self.setCompilers.popLanguage() 285 if hasattr(self.compilers, 'FC'): 286 self.setCompilers.pushLanguage('FC') 287 fd.write('\"Using Fortran compiler: %s %s ${FOPTFLAGS} ${FFLAGS} %s\\n\"\n' % (self.setCompilers.getCompiler(), self.setCompilers.getCompilerFlags(), self.setCompilers.CPPFLAGS)) 288 self.setCompilers.popLanguage() 289 fd.write('\"-----------------------------------------\\n\";\n') 290 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 291 fd.write('\"Using include paths: %s %s %s\\n\"\n' % ('-I'+os.path.join(self.petscdir.dir, self.arch.arch, 'include'), '-I'+os.path.join(self.petscdir.dir, 'include'), self.PETSC_CC_INCLUDES)) 292 fd.write('\"-----------------------------------------\\n\";\n') 293 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 294 self.setCompilers.pushLanguage(self.languages.clanguage) 295 fd.write('\"Using C linker: %s\\n\"\n' % (self.setCompilers.getLinker())) 296 self.setCompilers.popLanguage() 297 if hasattr(self.compilers, 'FC'): 298 self.setCompilers.pushLanguage('FC') 299 fd.write('\"Using Fortran linker: %s\\n\"\n' % (self.setCompilers.getLinker())) 300 self.setCompilers.popLanguage() 301 fd.write('\"Using libraries: %s%s -L%s %s %s\\n\"\n' % (self.setCompilers.CSharedLinkerFlag, os.path.join(self.petscdir.dir, self.arch.arch, 'lib'), os.path.join(self.petscdir.dir, self.arch.arch, 'lib'), '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys', self.PETSC_EXTERNAL_LIB_BASIC)) 302 fd.write('\"-----------------------------------------\\n\";\n') 303 fd.close() 304 return 305 306 def dumpCMakeConfig(self): 307 ''' 308 Writes configuration-specific values to ${PETSC_ARCH}/conf/PETScConfig.cmake. 309 This file is private to PETSc and should not be included by third parties 310 (a suitable file can be produced later by CMake, but this is not it). 311 ''' 312 def cmakeset(fd,key,val=True): 313 if val == True: val = 'YES' 314 if val == False: val = 'NO' 315 fd.write('set (' + key + ' ' + val + ')\n') 316 def ensurelist(a): 317 if isinstance(a,list): 318 return a 319 else: 320 return [a] 321 def libpath(lib): 322 'Returns a search path if that is what this item provides, else "" which will be cleaned out later' 323 if lib.startswith('-L'): return lib[2:] 324 if lib.startswith('-R'): return lib[2:] 325 if lib.startswith('-Wl,-rpath,'): 326 # This case occurs when an external package needs a specific system library that is normally provided by the compiler. 327 # In other words, the -L path is builtin to the wrapper or compiler, here we provide it so that CMake can locate the 328 # corresponding library. 329 return lib[len('-Wl,-rpath,'):] 330 if lib.startswith('-'): return '' 331 return os.path.dirname(lib) 332 def cleanlib(lib): 333 'Returns a library name if that is what this item provides, else "" which will be cleaned out later' 334 if lib.startswith('-l'): return lib[2:] 335 if lib.startswith('-Wl') or lib.startswith('-L'): return '' 336 lib = os.path.splitext(os.path.basename(lib))[0] 337 if lib.startswith('lib'): return lib[3:] 338 return lib 339 def nub(lst): 340 unique = [] 341 for elem in lst: 342 if elem not in unique and elem != '': 343 unique.append(elem) 344 return unique 345 def cmakeexpand(varname): 346 return r'"${' + varname + r'}"' 347 def uniqextend(list,new): 348 for x in ensurelist(new): 349 if x not in list: 350 list.append(x) 351 def notstandardinclude(path): 352 return path not in '/usr/include /usr/local/include'.split() 353 def writeMacroDefinitions(fd): 354 if self.mpi.usingMPIUni: 355 cmakeset(fd,'PETSC_HAVE_MPIUNI') 356 for pkg in self.framework.packages: 357 if pkg.useddirectly: 358 cmakeset(fd,'PETSC_HAVE_' + pkg.PACKAGE) 359 for name,val in self.functions.defines.items(): 360 cmakeset(fd,'PETSC_'+name,val) 361 for dct in [self.defines, self.libraryoptions.defines]: 362 for k,v in dct.items(): 363 if k.startswith('USE_'): 364 cmakeset(fd,'PETSC_' + k, v) 365 cmakeset(fd,'PETSC_USE_COMPLEX', self.scalartypes.scalartype == 'complex') 366 cmakeset(fd,'PETSC_USE_SCALAR_' + self.scalartypes.precision.upper()) 367 cmakeset(fd,'PETSC_CLANGUAGE_'+self.languages.clanguage) 368 if hasattr(self.compilers, 'FC'): 369 cmakeset(fd,'PETSC_HAVE_FORTRAN') 370 if self.compilers.fortranIsF90: 371 cmakeset(fd,'PETSC_USING_F90') 372 if self.sharedlibraries.useShared: 373 cmakeset(fd,'BUILD_SHARED_LIBS') 374 def writeBuildFlags(fd): 375 lib_paths = [] 376 lib_libs = [] 377 includes = [] 378 libvars = [] 379 for pkg in self.framework.packages: 380 libs = ensurelist(pkg.lib) 381 lib_paths.extend(map(libpath,libs)) 382 lib_libs.extend(map(cleanlib,libs)) 383 uniqextend(includes,pkg.include) 384 if self.libraries.math: lib_libs.extend(map(cleanlib,self.libraries.math)) 385 if self.libraries.rt: lib_libs.extend(map(cleanlib,self.libraries.rt)) 386 for libname in nub(lib_libs): 387 libvar = 'PETSC_' + libname.upper() + '_LIB' 388 addpath = '' 389 for lpath in nub(lib_paths): 390 addpath += '"' + str(lpath) + '" ' 391 fd.write('find_library (' + libvar + ' ' + libname + ' HINTS ' + addpath + ')\n') 392 libvars.append(libvar) 393 fd.write('mark_as_advanced (' + ' '.join(libvars) + ')\n') 394 fd.write('set (PETSC_PACKAGE_LIBS ' + ' '.join(map(cmakeexpand,libvars)) + ')\n') 395 fd.write('set (PETSC_PACKAGE_INCLUDES ' + ' '.join(map(lambda i: '"'+i+'"',filter(notstandardinclude,includes))) + ')\n') 396 fd = open(os.path.join(self.arch.arch,'conf','PETScConfig.cmake'), 'w') 397 writeMacroDefinitions(fd) 398 writeBuildFlags(fd) 399 fd.close() 400 return 401 402 def dumpCMakeLists(self): 403 import sys 404 if sys.version_info >= (2,5): 405 import cmakegen 406 try: 407 cmakegen.main(self.petscdir.dir) 408 except (OSError), e: 409 self.framework.logPrint('Generating CMakeLists.txt failed:\n' + str(e)) 410 411 def cmakeBoot(self): 412 import sys 413 if sys.version_info >= (2,5) and hasattr(self.cmake,'cmake'): 414 try: 415 import cmakeboot 416 cmakeboot.main(petscdir=self.petscdir.dir,petscarch=self.arch.arch,argDB=self.argDB,framework=self.framework,logPrint=self.framework.logPrint) 417 except (OSError), e: 418 self.framework.logPrint('Booting CMake in PETSC_ARCH failed:\n' + str(e)) 419 except (ImportError, KeyError), e: 420 self.framework.logPrint('Importing cmakeboot failed:\n' + str(e)) 421 return 422 423 def configurePrefetch(self): 424 '''Sees if there are any prefetch functions supported''' 425 if config.setCompilers.Configure.isSolaris() or self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 426 self.addDefine('Prefetch(a,b,c)', ' ') 427 return 428 self.pushLanguage(self.languages.clanguage) 429 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 430 # The Intel Intrinsics manual [1] specifies the prototype 431 # 432 # void _mm_prefetch(char const *a, int sel); 433 # 434 # but other vendors seem to insist on using subtly different 435 # prototypes, including void* for the pointer, and an enum for 436 # sel. These are both reasonable changes, but negatively impact 437 # portability. 438 # 439 # [1] http://software.intel.com/file/6373 440 self.addDefine('HAVE_XMMINTRIN_H', 1) 441 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 442 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 443 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 444 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 445 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 446 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 447 self.addDefine('HAVE_XMMINTRIN_H', 1) 448 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 449 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 450 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 451 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 452 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 453 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 454 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 455 # 456 # The value of rw is a compile-time constant one or zero; one 457 # means that the prefetch is preparing for a write to the memory 458 # address and zero, the default, means that the prefetch is 459 # preparing for a read. The value locality must be a compile-time 460 # constant integer between zero and three. A value of zero means 461 # that the data has no temporal locality, so it need not be left 462 # in the cache after the access. A value of three means that the 463 # data has a high degree of temporal locality and should be left 464 # in all levels of cache possible. Values of one and two mean, 465 # respectively, a low or moderate degree of temporal locality. 466 # 467 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 468 # hints. Using macros for these values in necessary since some 469 # compilers require an enum. 470 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 471 self.addDefine('PREFETCH_HINT_NTA', '0') 472 self.addDefine('PREFETCH_HINT_T0', '3') 473 self.addDefine('PREFETCH_HINT_T1', '2') 474 self.addDefine('PREFETCH_HINT_T2', '1') 475 else: 476 self.addDefine('Prefetch(a,b,c)', ' ') 477 self.popLanguage() 478 479 def configureUnused(self): 480 '''Sees if __attribute((unused)) is supported''' 481 if self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 482 self.addDefine('UNUSED', ' ') 483 return 484 self.pushLanguage(self.languages.clanguage) 485 if self.checkLink('__attribute((unused)) static int myfunc(void){ return 1;}', 'int i = myfunc();\n'): 486 self.addDefine('UNUSED', '__attribute((unused))') 487 else: 488 self.addDefine('UNUSED', ' ') 489 self.popLanguage() 490 491 def configureExpect(self): 492 '''Sees if the __builtin_expect directive is supported''' 493 self.pushLanguage(self.languages.clanguage) 494 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 495 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 496 self.popLanguage() 497 498 def configureFunctionName(self): 499 '''Sees if the compiler supports __FUNCTION__ or a variant''' 500 self.pushLanguage(self.languages.clanguage) 501 if self.checkLink('', "if (__func__[0] != 'm') return 1;"): 502 self.addDefine('FUNCTION_NAME', '__func__') 503 elif self.checkLink('', "if (__FUNCTION__[0] != 'm') return 1;"): 504 self.addDefine('FUNCTION_NAME', '__FUNCTION__') 505 else: 506 self.addDefine('FUNCTION_NAME', '__FUNCT__') 507 508 def configureIntptrt(self): 509 '''Determine what to use for uintptr_t''' 510 def staticAssertSizeMatchesVoidStar(inc,typename): 511 # The declaration is an error if either array size is negative. 512 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 513 return self.checkCompile(inc, '#define SZ (sizeof(void*)-sizeof(%s))\nint type_is_too_large[SZ],type_is_too_small[-SZ];'%typename) 514 self.pushLanguage(self.languages.clanguage) 515 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 516 self.addDefine('UINTPTR_T', 'uintptr_t') 517 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 518 self.addDefine('UINTPTR_T', 'unsigned long long') 519 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 520 self.addDefine('UINTPTR_T', 'size_t') 521 elif staticAssertSizeMatchesVoidStar('','unsigned'): 522 self.addDefine('UINTPTR_T', 'unsigned') 523 self.popLanguage() 524 525 def configureInline(self): 526 '''Get a generic inline keyword, depending on the language''' 527 if self.languages.clanguage == 'C': 528 self.addDefine('STATIC_INLINE', self.compilers.cStaticInlineKeyword) 529 self.addDefine('RESTRICT', self.compilers.cRestrict) 530 elif self.languages.clanguage == 'Cxx': 531 self.addDefine('STATIC_INLINE', self.compilers.cxxStaticInlineKeyword) 532 self.addDefine('RESTRICT', self.compilers.cxxRestrict) 533 return 534 535 def configureSolaris(self): 536 '''Solaris specific stuff''' 537 if self.arch.hostOsBase.startswith('solaris'): 538 if os.path.isdir(os.path.join('/usr','ucblib')): 539 try: 540 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 541 except AttributeError: 542 flag = None 543 if flag is None: 544 self.compilers.LIBS += ' -L/usr/ucblib' 545 else: 546 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 547 return 548 549 def configureLinux(self): 550 '''Linux specific stuff''' 551 if self.arch.hostOsBase == 'linux': 552 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 553 return 554 555 def configureWin32(self): 556 '''Win32 non-cygwin specific stuff''' 557 kernel32=0 558 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 559 self.addDefine('HAVE_WINDOWS_H',1) 560 self.addDefine('HAVE_GETCOMPUTERNAME',1) 561 kernel32=1 562 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 563 self.addDefine('HAVE_WINDOWS_H',1) 564 self.addDefine('HAVE_GETCOMPUTERNAME',1) 565 kernel32=1 566 if kernel32: 567 if self.framework.argDB['with-windows-graphics']: 568 self.addDefine('USE_WINDOWS_GRAPHICS',1) 569 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 570 self.addDefine('HAVE_LOADLIBRARY',1) 571 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 572 self.addDefine('HAVE_GETPROCADDRESS',1) 573 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 574 self.addDefine('HAVE_FREELIBRARY',1) 575 if self.checkLink('#include <Windows.h>','GetLastError()'): 576 self.addDefine('HAVE_GETLASTERROR',1) 577 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 578 self.addDefine('HAVE_SETLASTERROR',1) 579 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 580 self.addDefine('USE_NT_TIME',1) 581 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 582 self.addDefine('HAVE_GET_USER_NAME',1) 583 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 584 self.addDefine('HAVE_GET_USER_NAME',1) 585 586 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 587 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 588 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 589 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 590 591 self.types.check('int32_t', 'int') 592 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 593 self.addTypedef('int', 'uid_t') 594 self.addTypedef('int', 'gid_t') 595 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 596 self.framework.addDefine('R_OK', '04') 597 self.framework.addDefine('W_OK', '02') 598 self.framework.addDefine('X_OK', '01') 599 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 600 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 601 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 602 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 603 self.addDefine('HAVE_LARGE_INTEGER_U',1) 604 605 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 606 if self.checkCompile('#include <Windows.h>\n',''): 607 self.addDefine('HAVE_O_BINARY',1) 608 609 if self.compilers.CC.find('win32fe') >= 0: 610 self.addDefine('PATH_SEPARATOR','\';\'') 611 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 612 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 613 self.addDefine('CANNOT_START_DEBUGGER',1) 614 else: 615 self.addDefine('PATH_SEPARATOR','\':\'') 616 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 617 self.addDefine('DIR_SEPARATOR','\'/\'') 618 return 619 620#----------------------------------------------------------------------------------------------------- 621 def configureDefaultArch(self): 622 conffile = os.path.join('conf', 'petscvariables') 623 if self.framework.argDB['with-default-arch']: 624 fd = file(conffile, 'w') 625 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 626 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 627 fd.write('include ${PETSC_DIR}/${PETSC_ARCH}/conf/petscvariables\n') 628 fd.close() 629 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 630 elif os.path.isfile(conffile): 631 try: 632 os.unlink(conffile) 633 except: 634 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 635 return 636 637#----------------------------------------------------------------------------------------------------- 638 def configureScript(self): 639 '''Output a script in the conf directory which will reproduce the configuration''' 640 import nargs 641 import sys 642 scriptName = os.path.join(self.arch.arch,'conf', 'reconfigure-'+self.arch.arch+'.py') 643 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 644 if 'configModules' in args: 645 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 646 del args['configModules'] 647 if 'optionsModule' in args: 648 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'PETSc.compilerOptions': 649 del args['optionsModule'] 650 if not 'PETSC_ARCH' in args: 651 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 652 f = file(scriptName, 'w') 653 f.write('#!'+sys.executable+'\n') 654 f.write('if __name__ == \'__main__\':\n') 655 f.write(' import sys\n') 656 f.write(' import os\n') 657 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 658 f.write(' import configure\n') 659 # pretty print repr(args.values()) 660 f.write(' configure_options = [\n') 661 for itm in args.values(): 662 f.write(' \''+str(itm)+'\',\n') 663 f.write(' ]\n') 664 f.write(' configure.petsc_configure(configure_options)\n') 665 f.close() 666 try: 667 os.chmod(scriptName, 0775) 668 except OSError, e: 669 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 670 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 671 return 672 673 def configureInstall(self): 674 '''Setup the directories for installation''' 675 if self.framework.argDB['prefix']: 676 self.installdir = self.framework.argDB['prefix'] 677 self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\ 678 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 679 '-@echo "========================================="']) 680 else: 681 self.installdir = os.path.join(self.petscdir.dir,self.arch.arch) 682 self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\ 683 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\ 684 '-@echo "========================================="']) 685 return 686 687 def configureGCOV(self): 688 if self.framework.argDB['with-gcov']: 689 self.addDefine('USE_GCOV','1') 690 return 691 692 def configureFortranFlush(self): 693 if hasattr(self.compilers, 'FC'): 694 for baseName in ['flush','flush_']: 695 if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1): 696 self.addDefine('HAVE_'+baseName.upper(), 1) 697 return 698 699 700 def configure(self): 701 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 702 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 703 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 704 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 705 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 706 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 707 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'conf','petscvariables') 708 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'conf','petscrules') 709 if self.libraries.math is None: 710 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 711 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 712 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 713 self.executeTest(self.configureInline) 714 self.executeTest(self.configurePrefetch) 715 self.executeTest(self.configureUnused) 716 self.executeTest(self.configureExpect); 717 self.executeTest(self.configureFunctionName); 718 self.executeTest(self.configureIntptrt); 719 self.executeTest(self.configureSolaris) 720 self.executeTest(self.configureLinux) 721 self.executeTest(self.configureWin32) 722 self.executeTest(self.configureDefaultArch) 723 self.executeTest(self.configureScript) 724 self.executeTest(self.configureInstall) 725 self.executeTest(self.configureGCOV) 726 self.executeTest(self.configureFortranFlush) 727 # dummy rules, always needed except for remote builds 728 self.addMakeRule('remote','') 729 self.addMakeRule('remoteclean','') 730 731 self.Dump() 732 self.dumpConfigInfo() 733 self.dumpMachineInfo() 734 self.dumpCMakeConfig() 735 self.dumpCMakeLists() 736 self.cmakeBoot() 737 self.framework.log.write('================================================================================\n') 738 self.logClear() 739 return 740