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.toStringNoDupes(includes,includes)) 235 else: 236 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(includes)) 237 238 self.addMakeMacro('DESTDIR',self.installdir) 239 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir,'lib')+'"') 240 241 if self.framework.argDB['with-single-library']: 242 # overrides the values set in conf/variables 243 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 244 self.addMakeMacro('PETSC_SYS_LIB_BASIC','-lpetsc') 245 self.addMakeMacro('PETSC_VEC_LIB_BASIC','-lpetsc') 246 self.addMakeMacro('PETSC_MAT_LIB_BASIC','-lpetsc') 247 self.addMakeMacro('PETSC_DM_LIB_BASIC','-lpetsc') 248 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 249 self.addMakeMacro('PETSC_SNES_LIB_BASIC','-lpetsc') 250 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 251 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 252 self.addMakeMacro('PETSC_CONTRIB_BASIC','-lpetsc') 253 self.addMakeMacro('SHLIBS','libpetsc') 254 self.addDefine('USE_SINGLE_LIBRARY', '1') 255 256 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 257 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 258 259 # add a makefile entry for configure options 260 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 261 return 262 263 def dumpConfigInfo(self): 264 import time 265 fd = file(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 266 fd.write('static const char *petscconfigureruntime = "'+time.ctime(time.time())+'";\n') 267 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')+'";\n') 268 fd.close() 269 return 270 271 def dumpMachineInfo(self): 272 import platform 273 import time 274 import script 275 fd = file(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 276 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 277 fd.write('\"-----------------------------------------\\n\"\n') 278 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (time.ctime(time.time()), platform.node())) 279 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 280 fd.write('\"Using PETSc directory: %s\\n\"\n' % (self.petscdir.dir)) 281 fd.write('\"Using PETSc arch: %s\\n\"\n' % (self.arch.arch)) 282 fd.write('\"-----------------------------------------\\n\";\n') 283 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 284 self.setCompilers.pushLanguage(self.languages.clanguage) 285 fd.write('\"Using C compiler: %s %s ${COPTFLAGS} ${CFLAGS}\\n\"\n' % (self.setCompilers.getCompiler(), self.setCompilers.getCompilerFlags())) 286 self.setCompilers.popLanguage() 287 if hasattr(self.compilers, 'FC'): 288 self.setCompilers.pushLanguage('FC') 289 fd.write('\"Using Fortran compiler: %s %s ${FOPTFLAGS} ${FFLAGS} %s\\n\"\n' % (self.setCompilers.getCompiler(), self.setCompilers.getCompilerFlags(), self.setCompilers.CPPFLAGS)) 290 self.setCompilers.popLanguage() 291 fd.write('\"-----------------------------------------\\n\";\n') 292 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 293 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)) 294 fd.write('\"-----------------------------------------\\n\";\n') 295 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 296 self.setCompilers.pushLanguage(self.languages.clanguage) 297 fd.write('\"Using C linker: %s\\n\"\n' % (self.setCompilers.getLinker())) 298 self.setCompilers.popLanguage() 299 if hasattr(self.compilers, 'FC'): 300 self.setCompilers.pushLanguage('FC') 301 fd.write('\"Using Fortran linker: %s\\n\"\n' % (self.setCompilers.getLinker())) 302 self.setCompilers.popLanguage() 303 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)) 304 fd.write('\"-----------------------------------------\\n\";\n') 305 fd.close() 306 return 307 308 def dumpCMakeConfig(self): 309 ''' 310 Writes configuration-specific values to ${PETSC_ARCH}/conf/PETScConfig.cmake. 311 This file is private to PETSc and should not be included by third parties 312 (a suitable file can be produced later by CMake, but this is not it). 313 ''' 314 def cmakeset(fd,key,val=True): 315 if val == True: val = 'YES' 316 if val == False: val = 'NO' 317 fd.write('set (' + key + ' ' + val + ')\n') 318 def ensurelist(a): 319 if isinstance(a,list): 320 return a 321 else: 322 return [a] 323 def libpath(lib): 324 'Returns a search path if that is what this item provides, else "" which will be cleaned out later' 325 if lib.startswith('-L'): return lib[2:] 326 if lib.startswith('-R'): return lib[2:] 327 if lib.startswith('-Wl,-rpath,'): 328 # This case occurs when an external package needs a specific system library that is normally provided by the compiler. 329 # In other words, the -L path is builtin to the wrapper or compiler, here we provide it so that CMake can locate the 330 # corresponding library. 331 return lib[len('-Wl,-rpath,'):] 332 if lib.startswith('-'): return '' 333 return os.path.dirname(lib) 334 def cleanlib(lib): 335 'Returns a library name if that is what this item provides, else "" which will be cleaned out later' 336 if lib.startswith('-l'): return lib[2:] 337 if lib.startswith('-Wl') or lib.startswith('-L'): return '' 338 lib = os.path.splitext(os.path.basename(lib))[0] 339 if lib.startswith('lib'): return lib[3:] 340 return lib 341 def nub(lst): 342 unique = [] 343 for elem in lst: 344 if elem not in unique and elem != '': 345 unique.append(elem) 346 return unique 347 def cmakeexpand(varname): 348 return r'"${' + varname + r'}"' 349 def uniqextend(list,new): 350 for x in ensurelist(new): 351 if x not in list: 352 list.append(x) 353 def notstandardinclude(path): 354 return path not in '/usr/include /usr/local/include'.split() 355 def writeMacroDefinitions(fd): 356 if self.mpi.usingMPIUni: 357 cmakeset(fd,'PETSC_HAVE_MPIUNI') 358 for pkg in self.framework.packages: 359 if pkg.useddirectly: 360 cmakeset(fd,'PETSC_HAVE_' + pkg.PACKAGE) 361 for name,val in self.functions.defines.items(): 362 cmakeset(fd,'PETSC_'+name,val) 363 for dct in [self.defines, self.libraryoptions.defines]: 364 for k,v in dct.items(): 365 if k.startswith('USE_'): 366 cmakeset(fd,'PETSC_' + k, v) 367 cmakeset(fd,'PETSC_USE_COMPLEX', self.scalartypes.scalartype == 'complex') 368 cmakeset(fd,'PETSC_USE_SCALAR_' + self.scalartypes.precision.upper()) 369 cmakeset(fd,'PETSC_CLANGUAGE_'+self.languages.clanguage) 370 if hasattr(self.compilers, 'FC'): 371 cmakeset(fd,'PETSC_HAVE_FORTRAN') 372 if self.compilers.fortranIsF90: 373 cmakeset(fd,'PETSC_USING_F90') 374 if self.sharedlibraries.useShared: 375 cmakeset(fd,'BUILD_SHARED_LIBS') 376 def writeBuildFlags(fd): 377 lib_paths = [] 378 lib_libs = [] 379 includes = [] 380 libvars = [] 381 for pkg in self.framework.packages: 382 libs = ensurelist(pkg.lib) 383 lib_paths.extend(map(libpath,libs)) 384 lib_libs.extend(map(cleanlib,libs)) 385 uniqextend(includes,pkg.include) 386 if self.libraries.math: lib_libs.extend(map(cleanlib,self.libraries.math)) 387 if self.libraries.rt: lib_libs.extend(map(cleanlib,self.libraries.rt)) 388 for libname in nub(lib_libs): 389 libvar = 'PETSC_' + libname.upper() + '_LIB' 390 addpath = '' 391 for lpath in nub(lib_paths): 392 addpath += '"' + str(lpath) + '" ' 393 fd.write('find_library (' + libvar + ' ' + libname + ' HINTS ' + addpath + ')\n') 394 libvars.append(libvar) 395 fd.write('mark_as_advanced (' + ' '.join(libvars) + ')\n') 396 fd.write('set (PETSC_PACKAGE_LIBS ' + ' '.join(map(cmakeexpand,libvars)) + ')\n') 397 fd.write('set (PETSC_PACKAGE_INCLUDES ' + ' '.join(map(lambda i: '"'+i+'"',filter(notstandardinclude,includes))) + ')\n') 398 fd = open(os.path.join(self.arch.arch,'conf','PETScConfig.cmake'), 'w') 399 writeMacroDefinitions(fd) 400 writeBuildFlags(fd) 401 fd.close() 402 return 403 404 def dumpCMakeLists(self): 405 import sys 406 if sys.version_info >= (2,5): 407 import cmakegen 408 try: 409 cmakegen.main(self.petscdir.dir) 410 except (OSError), e: 411 self.framework.logPrint('Generating CMakeLists.txt failed:\n' + str(e)) 412 413 def cmakeBoot(self): 414 import sys 415 if sys.version_info >= (2,5) and hasattr(self.cmake,'cmake'): 416 try: 417 import cmakeboot 418 cmakeboot.main(petscdir=self.petscdir.dir,petscarch=self.arch.arch,argDB=self.argDB,framework=self.framework,logPrint=self.framework.logPrint) 419 except (OSError), e: 420 self.framework.logPrint('Booting CMake in PETSC_ARCH failed:\n' + str(e)) 421 except (ImportError, KeyError), e: 422 self.framework.logPrint('Importing cmakeboot failed:\n' + str(e)) 423 return 424 425 def configurePrefetch(self): 426 '''Sees if there are any prefetch functions supported''' 427 if config.setCompilers.Configure.isSolaris() or self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 428 self.addDefine('Prefetch(a,b,c)', ' ') 429 return 430 self.pushLanguage(self.languages.clanguage) 431 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 432 # The Intel Intrinsics manual [1] specifies the prototype 433 # 434 # void _mm_prefetch(char const *a, int sel); 435 # 436 # but other vendors seem to insist on using subtly different 437 # prototypes, including void* for the pointer, and an enum for 438 # sel. These are both reasonable changes, but negatively impact 439 # portability. 440 # 441 # [1] http://software.intel.com/file/6373 442 self.addDefine('HAVE_XMMINTRIN_H', 1) 443 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 444 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 445 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 446 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 447 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 448 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 449 self.addDefine('HAVE_XMMINTRIN_H', 1) 450 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 451 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 452 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 453 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 454 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 455 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 456 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 457 # 458 # The value of rw is a compile-time constant one or zero; one 459 # means that the prefetch is preparing for a write to the memory 460 # address and zero, the default, means that the prefetch is 461 # preparing for a read. The value locality must be a compile-time 462 # constant integer between zero and three. A value of zero means 463 # that the data has no temporal locality, so it need not be left 464 # in the cache after the access. A value of three means that the 465 # data has a high degree of temporal locality and should be left 466 # in all levels of cache possible. Values of one and two mean, 467 # respectively, a low or moderate degree of temporal locality. 468 # 469 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 470 # hints. Using macros for these values in necessary since some 471 # compilers require an enum. 472 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 473 self.addDefine('PREFETCH_HINT_NTA', '0') 474 self.addDefine('PREFETCH_HINT_T0', '3') 475 self.addDefine('PREFETCH_HINT_T1', '2') 476 self.addDefine('PREFETCH_HINT_T2', '1') 477 else: 478 self.addDefine('Prefetch(a,b,c)', ' ') 479 self.popLanguage() 480 481 def configureUnused(self): 482 '''Sees if __attribute((unused)) is supported''' 483 if self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 484 self.addDefine('UNUSED', ' ') 485 return 486 self.pushLanguage(self.languages.clanguage) 487 if self.checkLink('__attribute((unused)) static int myfunc(void){ return 1;}', 'int i = myfunc();\n'): 488 self.addDefine('UNUSED', '__attribute((unused))') 489 else: 490 self.addDefine('UNUSED', ' ') 491 self.popLanguage() 492 493 def configureExpect(self): 494 '''Sees if the __builtin_expect directive is supported''' 495 self.pushLanguage(self.languages.clanguage) 496 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 497 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 498 self.popLanguage() 499 500 def configureFunctionName(self): 501 '''Sees if the compiler supports __FUNCTION__ or a variant''' 502 self.pushLanguage(self.languages.clanguage) 503 if self.checkLink('', "if (__func__[0] != 'm') return 1;"): 504 self.addDefine('FUNCTION_NAME', '__func__') 505 elif self.checkLink('', "if (__FUNCTION__[0] != 'm') return 1;"): 506 self.addDefine('FUNCTION_NAME', '__FUNCTION__') 507 else: 508 self.addDefine('FUNCTION_NAME', '__FUNCT__') 509 510 def configureIntptrt(self): 511 '''Determine what to use for uintptr_t''' 512 def staticAssertSizeMatchesVoidStar(inc,typename): 513 # The declaration is an error if either array size is negative. 514 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 515 return self.checkCompile(inc, '#define SZ (sizeof(void*)-sizeof(%s))\nint type_is_too_large[SZ],type_is_too_small[-SZ];'%typename) 516 self.pushLanguage(self.languages.clanguage) 517 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 518 self.addDefine('UINTPTR_T', 'uintptr_t') 519 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 520 self.addDefine('UINTPTR_T', 'unsigned long long') 521 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 522 self.addDefine('UINTPTR_T', 'size_t') 523 elif staticAssertSizeMatchesVoidStar('','unsigned'): 524 self.addDefine('UINTPTR_T', 'unsigned') 525 self.popLanguage() 526 527 def configureInline(self): 528 '''Get a generic inline keyword, depending on the language''' 529 if self.languages.clanguage == 'C': 530 self.addDefine('STATIC_INLINE', self.compilers.cStaticInlineKeyword) 531 self.addDefine('RESTRICT', self.compilers.cRestrict) 532 elif self.languages.clanguage == 'Cxx': 533 self.addDefine('STATIC_INLINE', self.compilers.cxxStaticInlineKeyword) 534 self.addDefine('RESTRICT', self.compilers.cxxRestrict) 535 return 536 537 def configureSolaris(self): 538 '''Solaris specific stuff''' 539 if self.arch.hostOsBase.startswith('solaris'): 540 if os.path.isdir(os.path.join('/usr','ucblib')): 541 try: 542 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 543 except AttributeError: 544 flag = None 545 if flag is None: 546 self.compilers.LIBS += ' -L/usr/ucblib' 547 else: 548 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 549 return 550 551 def configureLinux(self): 552 '''Linux specific stuff''' 553 if self.arch.hostOsBase == 'linux': 554 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 555 return 556 557 def configureWin32(self): 558 '''Win32 non-cygwin specific stuff''' 559 kernel32=0 560 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 561 self.addDefine('HAVE_WINDOWS_H',1) 562 self.addDefine('HAVE_GETCOMPUTERNAME',1) 563 kernel32=1 564 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 565 self.addDefine('HAVE_WINDOWS_H',1) 566 self.addDefine('HAVE_GETCOMPUTERNAME',1) 567 kernel32=1 568 if kernel32: 569 if self.framework.argDB['with-windows-graphics']: 570 self.addDefine('USE_WINDOWS_GRAPHICS',1) 571 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 572 self.addDefine('HAVE_LOADLIBRARY',1) 573 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 574 self.addDefine('HAVE_GETPROCADDRESS',1) 575 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 576 self.addDefine('HAVE_FREELIBRARY',1) 577 if self.checkLink('#include <Windows.h>','GetLastError()'): 578 self.addDefine('HAVE_GETLASTERROR',1) 579 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 580 self.addDefine('HAVE_SETLASTERROR',1) 581 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 582 self.addDefine('USE_NT_TIME',1) 583 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 584 self.addDefine('HAVE_GET_USER_NAME',1) 585 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 586 self.addDefine('HAVE_GET_USER_NAME',1) 587 588 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 589 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 590 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 591 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 592 593 self.types.check('int32_t', 'int') 594 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 595 self.addTypedef('int', 'uid_t') 596 self.addTypedef('int', 'gid_t') 597 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 598 self.framework.addDefine('R_OK', '04') 599 self.framework.addDefine('W_OK', '02') 600 self.framework.addDefine('X_OK', '01') 601 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 602 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 603 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 604 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 605 self.addDefine('HAVE_LARGE_INTEGER_U',1) 606 607 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 608 if self.checkCompile('#include <Windows.h>\n',''): 609 self.addDefine('HAVE_O_BINARY',1) 610 611 if self.compilers.CC.find('win32fe') >= 0: 612 self.addDefine('PATH_SEPARATOR','\';\'') 613 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 614 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 615 self.addDefine('CANNOT_START_DEBUGGER',1) 616 else: 617 self.addDefine('PATH_SEPARATOR','\':\'') 618 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 619 self.addDefine('DIR_SEPARATOR','\'/\'') 620 return 621 622#----------------------------------------------------------------------------------------------------- 623 def configureDefaultArch(self): 624 conffile = os.path.join('conf', 'petscvariables') 625 if self.framework.argDB['with-default-arch']: 626 fd = file(conffile, 'w') 627 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 628 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 629 fd.write('include ${PETSC_DIR}/${PETSC_ARCH}/conf/petscvariables\n') 630 fd.close() 631 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 632 elif os.path.isfile(conffile): 633 try: 634 os.unlink(conffile) 635 except: 636 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 637 return 638 639#----------------------------------------------------------------------------------------------------- 640 def configureScript(self): 641 '''Output a script in the conf directory which will reproduce the configuration''' 642 import nargs 643 import sys 644 scriptName = os.path.join(self.arch.arch,'conf', 'reconfigure-'+self.arch.arch+'.py') 645 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 646 if 'configModules' in args: 647 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 648 del args['configModules'] 649 if 'optionsModule' in args: 650 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'PETSc.compilerOptions': 651 del args['optionsModule'] 652 if not 'PETSC_ARCH' in args: 653 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 654 f = file(scriptName, 'w') 655 f.write('#!'+sys.executable+'\n') 656 f.write('if __name__ == \'__main__\':\n') 657 f.write(' import sys\n') 658 f.write(' import os\n') 659 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 660 f.write(' import configure\n') 661 # pretty print repr(args.values()) 662 f.write(' configure_options = [\n') 663 for itm in args.values(): 664 f.write(' \''+str(itm)+'\',\n') 665 f.write(' ]\n') 666 f.write(' configure.petsc_configure(configure_options)\n') 667 f.close() 668 try: 669 os.chmod(scriptName, 0775) 670 except OSError, e: 671 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 672 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 673 return 674 675 def configureInstall(self): 676 '''Setup the directories for installation''' 677 if self.framework.argDB['prefix']: 678 self.installdir = self.framework.argDB['prefix'] 679 self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\ 680 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 681 '-@echo "========================================="']) 682 else: 683 self.installdir = os.path.join(self.petscdir.dir,self.arch.arch) 684 self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\ 685 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\ 686 '-@echo "========================================="']) 687 return 688 689 def configureGCOV(self): 690 if self.framework.argDB['with-gcov']: 691 self.addDefine('USE_GCOV','1') 692 return 693 694 def configureFortranFlush(self): 695 if hasattr(self.compilers, 'FC'): 696 for baseName in ['flush','flush_']: 697 if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1): 698 self.addDefine('HAVE_'+baseName.upper(), 1) 699 return 700 701 702 def configure(self): 703 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 704 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 705 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 706 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 707 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 708 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 709 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'conf','petscvariables') 710 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'conf','petscrules') 711 if self.libraries.math is None: 712 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 713 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 714 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 715 self.executeTest(self.configureInline) 716 self.executeTest(self.configurePrefetch) 717 self.executeTest(self.configureUnused) 718 self.executeTest(self.configureExpect); 719 self.executeTest(self.configureFunctionName); 720 self.executeTest(self.configureIntptrt); 721 self.executeTest(self.configureSolaris) 722 self.executeTest(self.configureLinux) 723 self.executeTest(self.configureWin32) 724 self.executeTest(self.configureDefaultArch) 725 self.executeTest(self.configureScript) 726 self.executeTest(self.configureInstall) 727 self.executeTest(self.configureGCOV) 728 self.executeTest(self.configureFortranFlush) 729 # dummy rules, always needed except for remote builds 730 self.addMakeRule('remote','') 731 self.addMakeRule('remoteclean','') 732 733 self.Dump() 734 self.dumpConfigInfo() 735 self.dumpMachineInfo() 736 self.dumpCMakeConfig() 737 self.dumpCMakeLists() 738 self.cmakeBoot() 739 self.framework.log.write('================================================================================\n') 740 self.logClear() 741 return 742