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