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 448 def cmakeBoot(self): 449 import sys 450 self.cmakeboot_success = False 451 if sys.version_info >= (2,5) and hasattr(self.cmake,'cmake'): 452 try: 453 import cmakeboot 454 self.cmakeboot_success = cmakeboot.main(petscdir=self.petscdir.dir,petscarch=self.arch.arch,argDB=self.argDB,framework=self.framework,log=self.framework.log) 455 except (OSError), e: 456 self.framework.logPrint('Booting CMake in PETSC_ARCH failed:\n' + str(e)) 457 except (ImportError, KeyError), e: 458 self.framework.logPrint('Importing cmakeboot failed:\n' + str(e)) 459 if self.cmakeboot_success and not hasattr(self.compilers, 'CUDAC'): # Our CMake build does not support CUDA at this time 460 self.addMakeMacro('PETSC_BUILD_USING_CMAKE',1) 461 return 462 463 def configurePrefetch(self): 464 '''Sees if there are any prefetch functions supported''' 465 if config.setCompilers.Configure.isSolaris() or self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 466 self.addDefine('Prefetch(a,b,c)', ' ') 467 return 468 self.pushLanguage(self.languages.clanguage) 469 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 470 # The Intel Intrinsics manual [1] specifies the prototype 471 # 472 # void _mm_prefetch(char const *a, int sel); 473 # 474 # but other vendors seem to insist on using subtly different 475 # prototypes, including void* for the pointer, and an enum for 476 # sel. These are both reasonable changes, but negatively impact 477 # portability. 478 # 479 # [1] http://software.intel.com/file/6373 480 self.addDefine('HAVE_XMMINTRIN_H', 1) 481 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 482 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 483 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 484 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 485 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 486 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 487 self.addDefine('HAVE_XMMINTRIN_H', 1) 488 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 489 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 490 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 491 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 492 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 493 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 494 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 495 # 496 # The value of rw is a compile-time constant one or zero; one 497 # means that the prefetch is preparing for a write to the memory 498 # address and zero, the default, means that the prefetch is 499 # preparing for a read. The value locality must be a compile-time 500 # constant integer between zero and three. A value of zero means 501 # that the data has no temporal locality, so it need not be left 502 # in the cache after the access. A value of three means that the 503 # data has a high degree of temporal locality and should be left 504 # in all levels of cache possible. Values of one and two mean, 505 # respectively, a low or moderate degree of temporal locality. 506 # 507 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 508 # hints. Using macros for these values in necessary since some 509 # compilers require an enum. 510 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 511 self.addDefine('PREFETCH_HINT_NTA', '0') 512 self.addDefine('PREFETCH_HINT_T0', '3') 513 self.addDefine('PREFETCH_HINT_T1', '2') 514 self.addDefine('PREFETCH_HINT_T2', '1') 515 else: 516 self.addDefine('Prefetch(a,b,c)', ' ') 517 self.popLanguage() 518 519 def configureUnused(self): 520 '''Sees if __attribute((unused)) is supported''' 521 if self.framework.argDB['with-iphone'] or self.framework.argDB['with-cuda']: 522 self.addDefine('UNUSED', ' ') 523 return 524 self.pushLanguage(self.languages.clanguage) 525 if self.checkLink('__attribute((unused)) static int myfunc(void){ return 1;}', 'int i = myfunc();\n'): 526 self.addDefine('UNUSED', '__attribute((unused))') 527 else: 528 self.addDefine('UNUSED', ' ') 529 self.popLanguage() 530 531 def configureExpect(self): 532 '''Sees if the __builtin_expect directive is supported''' 533 self.pushLanguage(self.languages.clanguage) 534 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 535 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 536 self.popLanguage() 537 538 def configureFunctionName(self): 539 '''Sees if the compiler supports __func__ or a variant. Falls back 540 on __FUNCT__ which PETSc source defines, but most users do not, thus 541 stack traces through user code are better when the compiler's 542 variant is used.''' 543 def getFunctionName(lang): 544 name = '__FUNCT__' 545 self.pushLanguage(lang) 546 if self.checkLink('', "if (__func__[0] != 'm') return 1;"): 547 name = '__func__' 548 elif self.checkLink('', "if (__FUNCTION__[0] != 'm') return 1;"): 549 name = '__FUNCTION__' 550 self.popLanguage() 551 return name 552 langs = [] 553 554 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 555 if hasattr(self.compilers, 'CXX'): 556 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 557 else: 558 self.addDefine('FUNCTION_NAME_CXX', '__FUNCT__') 559 560 def configureIntptrt(self): 561 '''Determine what to use for uintptr_t''' 562 def staticAssertSizeMatchesVoidStar(inc,typename): 563 # The declaration is an error if either array size is negative. 564 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 565 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 566 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 567 self.pushLanguage(self.languages.clanguage) 568 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 569 self.addDefine('UINTPTR_T', 'uintptr_t') 570 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 571 self.addDefine('UINTPTR_T', 'unsigned long long') 572 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 573 self.addDefine('UINTPTR_T', 'size_t') 574 elif staticAssertSizeMatchesVoidStar('','unsigned long'): 575 self.addDefine('UINTPTR_T', 'unsigned long') 576 elif staticAssertSizeMatchesVoidStar('','unsigned'): 577 self.addDefine('UINTPTR_T', 'unsigned') 578 else: 579 raise RuntimeError('Could not find any unsigned integer type matching void*') 580 self.popLanguage() 581 582 def configureInline(self): 583 '''Get a generic inline keyword, depending on the language''' 584 if self.languages.clanguage == 'C': 585 self.addDefine('STATIC_INLINE', self.compilers.cStaticInlineKeyword) 586 self.addDefine('RESTRICT', self.compilers.cRestrict) 587 elif self.languages.clanguage == 'Cxx': 588 self.addDefine('STATIC_INLINE', self.compilers.cxxStaticInlineKeyword) 589 self.addDefine('RESTRICT', self.compilers.cxxRestrict) 590 591 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 592 self.addDefine('RTLD_DEFAULT','1') 593 return 594 595 def configureSolaris(self): 596 '''Solaris specific stuff''' 597 if os.path.isdir(os.path.join('/usr','ucblib')): 598 try: 599 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 600 except AttributeError: 601 flag = None 602 if flag is None: 603 self.compilers.LIBS += ' -L/usr/ucblib' 604 else: 605 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 606 return 607 608 def configureLinux(self): 609 '''Linux specific stuff''' 610 # TODO: Test for this by mallocing an odd number of floats and checking the address 611 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 612 return 613 614 def configureWin32(self): 615 '''Win32 non-cygwin specific stuff''' 616 kernel32=0 617 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 618 self.addDefine('HAVE_WINDOWS_H',1) 619 self.addDefine('HAVE_GETCOMPUTERNAME',1) 620 kernel32=1 621 elif self.libraries.add('kernel32','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 if kernel32: 626 if self.framework.argDB['with-windows-graphics']: 627 self.addDefine('USE_WINDOWS_GRAPHICS',1) 628 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 629 self.addDefine('HAVE_LOADLIBRARY',1) 630 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 631 self.addDefine('HAVE_GETPROCADDRESS',1) 632 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 633 self.addDefine('HAVE_FREELIBRARY',1) 634 if self.checkLink('#include <Windows.h>','GetLastError()'): 635 self.addDefine('HAVE_GETLASTERROR',1) 636 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 637 self.addDefine('HAVE_SETLASTERROR',1) 638 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 639 self.addDefine('USE_NT_TIME',1) 640 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 641 self.addDefine('HAVE_GET_USER_NAME',1) 642 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 643 self.addDefine('HAVE_GET_USER_NAME',1) 644 645 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 646 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 647 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 648 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 649 650 self.types.check('int32_t', 'int') 651 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 652 self.addTypedef('int', 'uid_t') 653 self.addTypedef('int', 'gid_t') 654 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 655 self.framework.addDefine('R_OK', '04') 656 self.framework.addDefine('W_OK', '02') 657 self.framework.addDefine('X_OK', '01') 658 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 659 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 660 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 661 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 662 self.addDefine('HAVE_LARGE_INTEGER_U',1) 663 664 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 665 if self.checkCompile('#include <Windows.h>\n', 'int flags = O_BINARY;'): 666 self.addDefine('HAVE_O_BINARY',1) 667 668 if self.compilers.CC.find('win32fe') >= 0: 669 self.addDefine('PATH_SEPARATOR','\';\'') 670 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 671 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 672 self.addDefine('CANNOT_START_DEBUGGER',1) 673 else: 674 self.addDefine('PATH_SEPARATOR','\':\'') 675 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 676 self.addDefine('DIR_SEPARATOR','\'/\'') 677 678 return 679 680#----------------------------------------------------------------------------------------------------- 681 def configureDefaultArch(self): 682 conffile = os.path.join('conf', 'petscvariables') 683 if self.framework.argDB['with-default-arch']: 684 fd = file(conffile, 'w') 685 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 686 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 687 fd.write('include ${PETSC_DIR}/${PETSC_ARCH}/conf/petscvariables\n') 688 fd.close() 689 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 690 elif os.path.isfile(conffile): 691 try: 692 os.unlink(conffile) 693 except: 694 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 695 return 696 697#----------------------------------------------------------------------------------------------------- 698 def configureScript(self): 699 '''Output a script in the conf directory which will reproduce the configuration''' 700 import nargs 701 import sys 702 scriptName = os.path.join(self.arch.arch,'conf', 'reconfigure-'+self.arch.arch+'.py') 703 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 704 if 'configModules' in args: 705 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 706 del args['configModules'] 707 if 'optionsModule' in args: 708 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'PETSc.compilerOptions': 709 del args['optionsModule'] 710 if not 'PETSC_ARCH' in args: 711 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 712 f = file(scriptName, 'w') 713 f.write('#!'+sys.executable+'\n') 714 f.write('if __name__ == \'__main__\':\n') 715 f.write(' import sys\n') 716 f.write(' import os\n') 717 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 718 f.write(' import configure\n') 719 # pretty print repr(args.values()) 720 f.write(' configure_options = [\n') 721 for itm in sorted(args.values()): 722 f.write(' \''+str(itm)+'\',\n') 723 f.write(' ]\n') 724 f.write(' configure.petsc_configure(configure_options)\n') 725 f.close() 726 try: 727 os.chmod(scriptName, 0775) 728 except OSError, e: 729 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 730 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 731 return 732 733 def configureInstall(self): 734 '''Setup the directories for installation''' 735 if self.framework.argDB['prefix']: 736 self.installdir = self.framework.argDB['prefix'] 737 self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\ 738 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 739 '-@echo "========================================="']) 740 else: 741 self.installdir = os.path.join(self.petscdir.dir,self.arch.arch) 742 self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\ 743 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\ 744 '-@echo "========================================="']) 745 return 746 747 def configureGCOV(self): 748 if self.framework.argDB['with-gcov']: 749 self.addDefine('USE_GCOV','1') 750 return 751 752 def configureFortranFlush(self): 753 if hasattr(self.compilers, 'FC'): 754 for baseName in ['flush','flush_']: 755 if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1): 756 self.addDefine('HAVE_'+baseName.upper(), 1) 757 return 758 759 760 def configure(self): 761 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 762 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 763 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 764 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 765 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)): 766 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 767 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 768 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 769 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'conf','petscvariables') 770 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'conf','petscrules') 771 if self.libraries.math is None: 772 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 773 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 774 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 775 self.executeTest(self.configureInline) 776 self.executeTest(self.configurePrefetch) 777 self.executeTest(self.configureUnused) 778 self.executeTest(self.configureExpect); 779 self.executeTest(self.configureFunctionName); 780 self.executeTest(self.configureIntptrt); 781 self.executeTest(self.configureSolaris) 782 self.executeTest(self.configureLinux) 783 self.executeTest(self.configureWin32) 784 self.executeTest(self.configureDefaultArch) 785 self.executeTest(self.configureScript) 786 self.executeTest(self.configureInstall) 787 self.executeTest(self.configureGCOV) 788 self.executeTest(self.configureFortranFlush) 789 # dummy rules, always needed except for remote builds 790 self.addMakeRule('remote','') 791 self.addMakeRule('remoteclean','') 792 793 self.Dump() 794 self.dumpConfigInfo() 795 self.dumpMachineInfo() 796 self.dumpCMakeConfig() 797 self.dumpCMakeLists() 798 self.cmakeBoot() 799 self.framework.log.write('================================================================================\n') 800 self.logClear() 801 return 802