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