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