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 if self.make.getMakeMacro('MAKE_IS_GNUMAKE'): 24 build_type = 'gnumake build' 25 elif self.getMakeMacro('PETSC_BUILD_USING_CMAKE'): 26 build_type = 'cmake build' 27 else: 28 build_type = 'legacy build' 29 desc.append(' Configure stage complete. Now build PETSc libraries with (%s):' % build_type) 30 desc.append(' make PETSC_DIR='+self.petscdir.dir+' PETSC_ARCH='+self.arch.arch+' all') 31 desc.append('xxx=========================================================================xxx') 32 return '\n'.join(desc)+'\n' 33 34 def setupHelp(self, help): 35 import nargs 36 help.addArgument('PETSc', '-prefix=<dir>', nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)')) 37 help.addArgument('Windows','-with-windows-graphics=<bool>', nargs.ArgBool(None, 1,'Enable check for Windows Graphics')) 38 help.addArgument('PETSc', '-with-default-arch=<bool>', nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH')) 39 help.addArgument('PETSc','-with-single-library=<bool>', nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library')) 40 help.addArgument('PETSc', '-with-ios=<bool>', nargs.ArgBool(None, 0, 'Build an iPhone/iPad version of PETSc library')) 41 return 42 43 def setupDependencies(self, framework): 44 config.base.Configure.setupDependencies(self, framework) 45 self.programs = framework.require('config.programs', self) 46 self.setCompilers = framework.require('config.setCompilers', self) 47 self.arch = framework.require('PETSc.options.arch', self.setCompilers) 48 self.petscdir = framework.require('PETSc.options.petscdir', self.arch) 49 self.installdir = framework.require('PETSc.options.installDir',self) 50 self.languages = framework.require('PETSc.options.languages', self.setCompilers) 51 self.debugging = framework.require('PETSc.options.debugging', self.setCompilers) 52 self.compilers = framework.require('config.compilers', self) 53 self.types = framework.require('config.types', self) 54 self.headers = framework.require('config.headers', self) 55 self.functions = framework.require('config.functions', self) 56 self.libraries = framework.require('config.libraries', self) 57 self.atomics = framework.require('config.atomics', self) 58 self.make = framework.require('config.packages.make', self) 59 self.blasLapack = framework.require('config.packages.BlasLapack',self) 60 self.cmake = framework.require('config.packages.cmake',self) 61 self.externalpackagesdir = framework.require('PETSc.options.externalpackagesdir',self) 62 self.mpi = framework.require('config.packages.MPI',self) 63 64 for utility in os.listdir(os.path.join('config','PETSc','options')): 65 (utilityName, ext) = os.path.splitext(utility) 66 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 67 utilityObj = self.framework.require('PETSc.options.'+utilityName, self) 68 utilityObj.headerPrefix = self.headerPrefix 69 utilityObj.archProvider = self.arch 70 utilityObj.languageProvider = self.languages 71 utilityObj.installDirProvider = self.installdir 72 utilityObj.externalPackagesDirProvider = self.externalpackagesdir 73 setattr(self, utilityName.lower(), utilityObj) 74 75 for utility in os.listdir(os.path.join('config','BuildSystem','config','utilities')): 76 (utilityName, ext) = os.path.splitext(utility) 77 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 78 utilityObj = self.framework.require('config.utilities.'+utilityName, self) 79 utilityObj.headerPrefix = self.headerPrefix 80 utilityObj.archProvider = self.arch 81 utilityObj.languageProvider = self.languages 82 utilityObj.installDirProvider = self.installdir 83 utilityObj.externalPackagesDirProvider = self.externalpackagesdir 84 setattr(self, utilityName.lower(), utilityObj) 85 86 for utility in os.listdir(os.path.join('config','BuildSystem','config','packages')): 87 (utilityName, ext) = os.path.splitext(utility) 88 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 89 utilityObj = self.framework.require('config.packages.'+utilityName, self) 90 utilityObj.headerPrefix = self.headerPrefix 91 utilityObj.archProvider = self.arch 92 utilityObj.languageProvider = self.languages 93 utilityObj.installDirProvider = self.installdir 94 utilityObj.externalPackagesDirProvider = self.externalpackagesdir 95 setattr(self, utilityName.lower(), utilityObj) 96 97 if os.path.isdir(os.path.join('config', 'BuildSystem', 'config', 'packages')): 98 for package in os.listdir(os.path.join('config', 'BuildSystem', 'config', 'packages')): 99 (packageName, ext) = os.path.splitext(package) 100 if not packageName.startswith('.') and not packageName.startswith('#') and ext == '.py' and not packageName == '__init__' and not packageName == 'PETSc': 101 packageObj = framework.require('config.packages.'+packageName, self) 102 packageObj.archProvider = self.arch 103 packageObj.languageProvider = self.languages 104 packageObj.precisionProvider = self.scalartypes 105 packageObj.installDirProvider = self.installdir 106 packageObj.externalPackagesDirProvider = self.externalpackagesdir 107 setattr(self, packageName.lower(), packageObj) 108 # Force blaslapack to depend on scalarType so precision is set before BlasLapack is built 109 framework.require('PETSc.options.scalarTypes', self.f2cblaslapack) 110 framework.require('PETSc.options.scalarTypes', self.fblaslapack) 111 framework.require('PETSc.options.scalarTypes', self.blaslapack) 112 framework.require('PETSc.Regression', self) 113 114 self.programs.headerPrefix = self.headerPrefix 115 self.compilers.headerPrefix = self.headerPrefix 116 self.types.headerPrefix = self.headerPrefix 117 self.headers.headerPrefix = self.headerPrefix 118 self.functions.headerPrefix = self.headerPrefix 119 self.libraries.headerPrefix = self.headerPrefix 120 self.blaslapack.headerPrefix = self.headerPrefix 121 self.mpi.headerPrefix = self.headerPrefix 122 headersC = map(lambda name: name+'.h', ['setjmp','dos', 'endian', 'fcntl', 'float', 'io', 'limits', 'malloc', 'pwd', 'search', 'strings', 123 'unistd', 'sys/sysinfo', 'machine/endian', 'sys/param', 'sys/procfs', 'sys/resource', 124 'sys/systeminfo', 'sys/times', 'sys/utsname','string', 'stdlib', 125 'sys/socket','sys/wait','netinet/in','netdb','Direct','time','Ws2tcpip','sys/types', 126 'WindowsX', 'cxxabi','float','ieeefp','stdint','sched','pthread','mathimf']) 127 functions = ['access', '_access', 'clock', 'drand48', 'getcwd', '_getcwd', 'getdomainname', 'gethostname', 128 'gettimeofday', 'getwd', 'memalign', 'memmove', 'mkstemp', 'popen', 'PXFGETARG', 'rand', 'getpagesize', 129 'readlink', 'realpath', 'sigaction', 'signal', 'sigset', 'usleep', 'sleep', '_sleep', 'socket', 130 'times', 'gethostbyname', 'uname','snprintf','_snprintf','lseek','_lseek','time','fork','stricmp', 131 'strcasecmp', 'bzero', 'dlopen', 'dlsym', 'dlclose', 'dlerror','get_nprocs','sysctlbyname', 132 '_set_output_format'] 133 libraries1 = [(['socket', 'nsl'], 'socket'), (['fpe'], 'handle_sigfpes')] 134 self.headers.headers.extend(headersC) 135 self.functions.functions.extend(functions) 136 self.libraries.libraries.extend(libraries1) 137 138 return 139 140 def DumpPkgconfig(self): 141 ''' Create a pkg-config file ''' 142 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')): 143 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')) 144 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig','PETSc.pc'),'w') 145 if self.framework.argDB['prefix']: 146 installdir = self.framework.argDB['prefix'] 147 fd.write('prefix='+installdir+'\n') 148 fd.write('exec_prefix=${prefix}\n') 149 fd.write('includedir=${prefix}/include\n') 150 fd.write('libdir='+os.path.join(installdir,'lib')+'\n') 151 else: 152 fd.write('prefix='+self.petscdir.dir+'\n') 153 fd.write('exec_prefix=${prefix}\n') 154 fd.write('includedir=${prefix}/include\n') 155 fd.write('libdir='+os.path.join(self.petscdir.dir,self.arch.arch,'lib')+'\n') 156 157 self.setCompilers.pushLanguage('C') 158 fd.write('ccompiler='+self.setCompilers.getCompiler()+'\n') 159 self.setCompilers.popLanguage() 160 if hasattr(self.compilers, 'C++'): 161 self.setCompilers.pushLanguage('C++') 162 fd.write('cxxcompiler='+self.setCompilers.getCompiler()+'\n') 163 self.setCompilers.popLanguage() 164 if hasattr(self.compilers, 'FC'): 165 self.setCompilers.pushLanguage('FC') 166 fd.write('fcompiler='+self.setCompilers.getCompiler()+'\n') 167 self.setCompilers.popLanguage() 168 fd.write('blaslapacklibs='+self.libraries.toStringNoDupes(self.blaslapack.lib)+'\n') 169 170 fd.write('\n') 171 fd.write('Name: PETSc\n') 172 fd.write('Description: Library to solve ODEs and algebraic equations\n') 173 fd.write('Version: %s\n' % self.petscdir.version) 174 175 fd.write('Cflags: '+self.allincludes+'\n') 176 177 plibs = self.libraries.toStringNoDupes(['-L'+os.path.join(self.petscdir.dir,self.arch.arch,'lib'),' -lpetsc']) 178 if self.framework.argDB['prefix']: 179 fd.write('Libs: '+plibs.replace(os.path.join(self.petscdir.dir,self.arch.arch),self.framework.argDB['prefix'])+'\n') 180 else: 181 fd.write('Libs: '+plibs+'\n') 182 fd.write('Libs.private: '+' '.join(self.packagelibs+self.libraries.math+self.compilers.flibs+self.compilers.cxxlibs)+' '+self.compilers.LIBS) 183 184 fd.close() 185 return 186 187 def DumpModule(self): 188 ''' Create a module file ''' 189 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','modules')): 190 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','modules')) 191 if self.framework.argDB['prefix']: 192 installdir = self.framework.argDB['prefix'] 193 installarch = '' 194 installpath = os.path.join(installdir,'bin') 195 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','modules',self.petscdir.version),'w') 196 else: 197 installdir = self.petscdir.dir 198 installarch = self.arch.arch 199 installpath = os.path.join(installdir,installarch,'bin')+':'+os.path.join(installdir,'bin') 200 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','modules',self.petscdir.version+'-'+self.arch.arch),'w') 201 fd.write('''\ 202#%%Module 203 204proc ModulesHelp { } { 205 puts stderr "This module sets the path and environment variables for petsc-%s" 206 puts stderr " see http://www.mcs.anl.gov/petsc/ for more information " 207 puts stderr "" 208} 209module-whatis "PETSc - Portable, Extensible Toolkit for Scientific Computation" 210 211set petsc_dir %s 212set petsc_arch %s 213 214setenv PETSC_ARCH $petsc_arch 215setenv PETSC_DIR $petsc_dir 216prepend-path PATH %s 217''' % (self.petscdir.version, installdir, installarch, installpath)) 218 fd.close() 219 return 220 221 def Dump(self): 222 ''' Actually put the values into the configuration files ''' 223 # eventually everything between -- should be gone 224 if self.mpi.usingMPIUni: 225 # 226 # Remove any MPI/MPICH include files that may have been put here by previous runs of ./configure 227 self.executeShellCommand('rm -rf '+os.path.join(self.petscdir.dir,self.arch.arch,'include','mpi*')+' '+os.path.join(self.petscdir.dir,self.arch.arch,'include','opa*')) 228 229#----------------------------------------------------------------------------------------------------- 230 231 # Sometimes we need C compiler, even if built with C++ 232 self.setCompilers.pushLanguage('C') 233 self.addMakeMacro('CC_FLAGS',self.setCompilers.getCompilerFlags()) 234 self.setCompilers.popLanguage() 235 236 # And sometimes we need a C++ compiler even when PETSc is built with C 237 if hasattr(self.compilers, 'CXX'): 238 self.setCompilers.pushLanguage('Cxx') 239 self.addMakeMacro('CXX_FLAGS',self.setCompilers.getCompilerFlags()) 240 self.setCompilers.popLanguage() 241 242 # C preprocessor values 243 self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS) 244 245 # compiler values 246 self.setCompilers.pushLanguage(self.languages.clanguage) 247 self.addMakeMacro('PCC',self.setCompilers.getCompiler()) 248 self.addMakeMacro('PCC_FLAGS',self.setCompilers.getCompilerFlags()) 249 self.setCompilers.popLanguage() 250 # .o or .obj 251 self.addMakeMacro('CC_SUFFIX','o') 252 253 # executable linker values 254 self.setCompilers.pushLanguage(self.languages.clanguage) 255 pcc_linker = self.setCompilers.getLinker() 256 self.addMakeMacro('PCC_LINKER',pcc_linker) 257 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 258 self.setCompilers.popLanguage() 259 # '' for Unix, .exe for Windows 260 self.addMakeMacro('CC_LINKER_SUFFIX','') 261 262 if hasattr(self.compilers, 'FC'): 263 self.setCompilers.pushLanguage('FC') 264 # need FPPFLAGS in config/setCompilers 265 self.addDefine('HAVE_FORTRAN','1') 266 self.addMakeMacro('FPP_FLAGS',self.setCompilers.CPPFLAGS) 267 268 # compiler values 269 self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags()) 270 self.setCompilers.popLanguage() 271 # .o or .obj 272 self.addMakeMacro('FC_SUFFIX','o') 273 274 # executable linker values 275 self.setCompilers.pushLanguage('FC') 276 # Cannot have NAG f90 as the linker - so use pcc_linker as fc_linker 277 fc_linker = self.setCompilers.getLinker() 278 if config.setCompilers.Configure.isNAG(fc_linker): 279 self.addMakeMacro('FC_LINKER',pcc_linker) 280 else: 281 self.addMakeMacro('FC_LINKER',fc_linker) 282 self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 283 # apple requires this shared library linker flag on SOME versions of the os 284 if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1: 285 self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ') 286 self.setCompilers.popLanguage() 287 288 # F90 Modules 289 if self.setCompilers.fortranModuleIncludeFlag: 290 self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag) 291 else: # for non-f90 compilers like g77 292 self.addMakeMacro('FC_MODULE_FLAG', '-I') 293 if self.setCompilers.fortranModuleIncludeFlag: 294 self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag) 295 else: 296 self.addMakeMacro('FC','') 297 298 if hasattr(self.compilers, 'CUDAC'): 299 self.setCompilers.pushLanguage('CUDA') 300 self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags()) 301 self.setCompilers.popLanguage() 302 303 # shared library linker values 304 self.setCompilers.pushLanguage(self.languages.clanguage) 305 # need to fix BuildSystem to collect these separately 306 self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker()) 307 self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}') 308 self.setCompilers.popLanguage() 309 # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture 310 # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX 311 if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX: 312 self.addMakeMacro('SL_LINKER_SUFFIX', '') 313 self.addDefine('SLSUFFIX','""') 314 else: 315 self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt) 316 self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"') 317 318 self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}') 319 320#----------------------------------------------------------------------------------------------------- 321 322 # CONLY or CPP. We should change the PETSc makefiles to do this better 323 if self.languages.clanguage == 'C': lang = 'CONLY' 324 else: lang = 'CXXONLY' 325 self.addMakeMacro('PETSC_LANGUAGE',lang) 326 327 # real or complex 328 self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype) 329 # double or float 330 self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision) 331 332 if self.framework.argDB['with-batch']: 333 self.addMakeMacro('PETSC_WITH_BATCH','1') 334 335 # Test for compiler-specific macros that need to be defined. 336 if self.setCompilers.isCrayVector('CC'): 337 self.addDefine('HAVE_CRAY_VECTOR','1') 338 339#----------------------------------------------------------------------------------------------------- 340 if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket') and self.headers.haveHeader('netinet/in.h'): 341 self.addDefine('USE_SOCKET_VIEWER','1') 342 if self.checkCompile('#include <sys/socket.h>','setsockopt(0,SOL_SOCKET,SO_REUSEADDR,0,0)'): 343 self.addDefine('HAVE_SO_REUSEADDR','1') 344 345#----------------------------------------------------------------------------------------------------- 346 # print include and lib for makefiles 347 self.framework.packages.reverse() 348 includes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')] 349 libs = [] 350 for i in self.framework.packages: 351 if i.useddirectly: 352 self.addDefine('HAVE_'+i.PACKAGE.replace('-','_'), 1) # ONLY list package if it is used directly by PETSc (and not only by another package) 353 if not isinstance(i.lib, list): 354 i.lib = [i.lib] 355 libs.extend(i.lib) 356 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_LIB', self.libraries.toStringNoDupes(i.lib)) 357 if hasattr(i,'include'): 358 if not isinstance(i.include,list): 359 i.include = [i.include] 360 includes.extend(i.include) 361 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include)) 362 self.packagelibs = libs 363 if self.framework.argDB['with-single-library']: 364 self.alllibs = 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 365 self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.alllibs) 366 else: 367 self.alllibs = self.libraries.toStringNoDupes(['-L'+os.path.join(self.petscdir.dir,self.arch.arch,'lib'),'-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys']+libs+self.libraries.math+self.compilers.flibs+self.compilers.cxxlibs)+' '+self.compilers.LIBS 368 self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(libs+self.libraries.math+self.compilers.flibs+self.compilers.cxxlibs)+' '+self.compilers.LIBS 369 if self.framework.argDB['prefix'] and self.setCompilers.CSharedLinkerFlag not in ['-L']: 370 installdir = self.framework.argDB['prefix'] 371 lib_basic = self.PETSC_EXTERNAL_LIB_BASIC.replace(self.setCompilers.CSharedLinkerFlag+os.path.join(self.petscdir.dir,self.arch.arch,'lib'),self.setCompilers.CSharedLinkerFlag+os.path.join(installdir,'lib')) 372 else: 373 lib_basic = self.PETSC_EXTERNAL_LIB_BASIC 374 self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',lib_basic) 375 self.allincludes = self.headers.toStringNoDupes(includes) 376 self.addMakeMacro('PETSC_CC_INCLUDES',self.allincludes) 377 self.PETSC_CC_INCLUDES = self.allincludes 378 if hasattr(self.compilers, 'FC'): 379 if self.compilers.fortranIsF90: 380 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(includes,includes)) 381 else: 382 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(includes)) 383 384 self.addMakeMacro('DESTDIR',self.installdir) 385 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir,'lib')+'"') 386 387 if self.framework.argDB['with-single-library']: 388 # overrides the values set in conf/variables 389 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 390 self.addMakeMacro('SHLIBS','libpetsc') 391 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 392 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 393 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 394 self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc') 395 self.addDefine('USE_SINGLE_LIBRARY', '1') 396 if self.sharedlibraries.useShared: 397 self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 398 self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 399 self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 400 self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 401 self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 402 self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 403 self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 404 self.addMakeMacro('PETSC_TAO_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 405 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 406 self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 407 self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 408 else: 409 self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 410 self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 411 self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}') 412 self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}') 413 self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}') 414 self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}') 415 self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 416 self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}') 417 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 418 self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 419 self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}') 420 421 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 422 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 423 424 # add a makefile entry for configure options 425 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 426 return 427 428 def dumpConfigInfo(self): 429 import time 430 fd = file(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 431 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')+'";\n') 432 fd.close() 433 return 434 435 def dumpMachineInfo(self): 436 import platform 437 import time 438 import script 439 def escape(s): 440 return s.replace('"',r'\"').replace(r'\ ',r'\\ ') 441 fd = file(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 442 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 443 fd.write('\"-----------------------------------------\\n\"\n') 444 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (time.ctime(time.time()), platform.node())) 445 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 446 fd.write('\"Using PETSc directory: %s\\n\"\n' % (escape(self.petscdir.dir))) 447 fd.write('\"Using PETSc arch: %s\\n\"\n' % (escape(self.arch.arch))) 448 fd.write('\"-----------------------------------------\\n\";\n') 449 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 450 self.setCompilers.pushLanguage(self.languages.clanguage) 451 fd.write('\"Using C compiler: %s %s ${COPTFLAGS} ${CFLAGS}\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()))) 452 self.setCompilers.popLanguage() 453 if hasattr(self.compilers, 'FC'): 454 self.setCompilers.pushLanguage('FC') 455 fd.write('\"Using Fortran compiler: %s %s ${FOPTFLAGS} ${FFLAGS} %s\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()), escape(self.setCompilers.CPPFLAGS))) 456 self.setCompilers.popLanguage() 457 fd.write('\"-----------------------------------------\\n\";\n') 458 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 459 fd.write('\"Using include paths: %s %s %s\\n\"\n' % ('-I'+escape(os.path.join(self.petscdir.dir, self.arch.arch, 'include')), '-I'+escape(os.path.join(self.petscdir.dir, 'include')), escape(self.PETSC_CC_INCLUDES))) 460 fd.write('\"-----------------------------------------\\n\";\n') 461 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 462 self.setCompilers.pushLanguage(self.languages.clanguage) 463 fd.write('\"Using C linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 464 self.setCompilers.popLanguage() 465 if hasattr(self.compilers, 'FC'): 466 self.setCompilers.pushLanguage('FC') 467 fd.write('\"Using Fortran linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 468 self.setCompilers.popLanguage() 469 if self.framework.argDB['with-single-library']: 470 petsclib = '-lpetsc' 471 else: 472 petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys' 473 fd.write('\"Using libraries: %s%s -L%s %s %s\\n\"\n' % (escape(self.setCompilers.CSharedLinkerFlag), escape(os.path.join(self.petscdir.dir, self.arch.arch, 'lib')), escape(os.path.join(self.petscdir.dir, self.arch.arch, 'lib')), escape(petsclib), escape(self.PETSC_EXTERNAL_LIB_BASIC))) 474 fd.write('\"-----------------------------------------\\n\";\n') 475 fd.close() 476 return 477 478 def dumpCMakeConfig(self): 479 ''' 480 Writes configuration-specific values to ${PETSC_ARCH}/conf/PETScConfig.cmake. 481 This file is private to PETSc and should not be included by third parties 482 (a suitable file can be produced later by CMake, but this is not it). 483 ''' 484 def cmakeset(fd,key,val=True): 485 if val == True: val = 'YES' 486 if val == False: val = 'NO' 487 fd.write('set (' + key + ' ' + val + ')\n') 488 def ensurelist(a): 489 if isinstance(a,list): 490 return a 491 else: 492 return [a] 493 def libpath(lib): 494 'Returns a search path if that is what this item provides, else "" which will be cleaned out later' 495 if not isinstance(lib,str): return '' 496 if lib.startswith('-L'): return lib[2:] 497 if lib.startswith('-R'): return lib[2:] 498 if lib.startswith('-Wl,-rpath,'): 499 # This case occurs when an external package needs a specific system library that is normally provided by the compiler. 500 # In other words, the -L path is builtin to the wrapper or compiler, here we provide it so that CMake can locate the 501 # corresponding library. 502 return lib[len('-Wl,-rpath,'):] 503 if lib.startswith('-'): return '' 504 return os.path.dirname(lib) 505 def cleanlib(lib): 506 'Returns a library name if that is what this item provides, else "" which will be cleaned out later' 507 if not isinstance(lib,str): return '' 508 if lib.startswith('-l'): return lib[2:] 509 if lib.startswith('-Wl') or lib.startswith('-L'): return '' 510 lib = os.path.splitext(os.path.basename(lib))[0] 511 if lib.startswith('lib'): return lib[3:] 512 return lib 513 def nub(lst): 514 'Return a list containing the first occurrence of each unique element' 515 unique = [] 516 for elem in lst: 517 if elem not in unique and elem != '': 518 unique.append(elem) 519 return unique 520 try: reversed # reversed was added in Python-2.4 521 except NameError: 522 def reversed(lst): return lst[::-1] 523 def nublast(lst): 524 'Return a list containing the last occurrence of each unique entry in a list' 525 return reversed(nub(reversed(lst))) 526 def cmakeexpand(varname): 527 return r'"${' + varname + r'}"' 528 def uniqextend(lst,new): 529 for x in ensurelist(new): 530 if x not in lst: 531 lst.append(x) 532 def notstandardinclude(path): 533 return path not in '/usr/include'.split() # /usr/local/include is not automatically included on FreeBSD 534 def writeMacroDefinitions(fd): 535 if self.mpi.usingMPIUni: 536 cmakeset(fd,'PETSC_HAVE_MPIUNI') 537 for pkg in self.framework.packages: 538 if pkg.useddirectly: 539 cmakeset(fd,'PETSC_HAVE_' + pkg.PACKAGE.replace('-','_')) 540 for pair in pkg.defines.items(): 541 if pair[0].startswith('HAVE_') and pair[1]: 542 cmakeset(fd, self.framework.getFullDefineName(pkg, pair[0]), pair[1]) 543 for name,val in self.functions.defines.items(): 544 cmakeset(fd,'PETSC_'+name,val) 545 for dct in [self.defines, self.libraryoptions.defines]: 546 for k,v in dct.items(): 547 if k.startswith('USE_'): 548 cmakeset(fd,'PETSC_' + k, v) 549 cmakeset(fd,'PETSC_USE_COMPLEX', self.scalartypes.scalartype == 'complex') 550 cmakeset(fd,'PETSC_USE_REAL_' + self.scalartypes.precision.upper()) 551 cmakeset(fd,'PETSC_CLANGUAGE_'+self.languages.clanguage) 552 if hasattr(self.compilers, 'FC'): 553 cmakeset(fd,'PETSC_HAVE_FORTRAN') 554 if self.compilers.fortranIsF90: 555 cmakeset(fd,'PETSC_USING_F90') 556 if self.compilers.fortranIsF2003: 557 cmakeset(fd,'PETSC_USING_F2003') 558 if hasattr(self.compilers, 'CXX'): 559 cmakeset(fd,'PETSC_HAVE_CXX') 560 if self.sharedlibraries.useShared: 561 cmakeset(fd,'BUILD_SHARED_LIBS') 562 def writeBuildFlags(fd): 563 def extendby(lib): 564 libs = ensurelist(lib) 565 lib_paths.extend(map(libpath,libs)) 566 lib_libs.extend(map(cleanlib,libs)) 567 lib_paths = [] 568 lib_libs = [] 569 includes = [] 570 libvars = [] 571 for pkg in self.framework.packages: 572 extendby(pkg.lib) 573 uniqextend(includes,pkg.include) 574 extendby(self.libraries.math) 575 extendby(self.libraries.rt) 576 extendby(self.compilers.flibs) 577 extendby(self.compilers.cxxlibs) 578 extendby(self.compilers.LIBS.split()) 579 for libname in nublast(lib_libs): 580 libvar = 'PETSC_' + libname.upper() + '_LIB' 581 addpath = '' 582 for lpath in nublast(lib_paths): 583 addpath += '"' + str(lpath) + '" ' 584 fd.write('find_library (' + libvar + ' ' + libname + ' HINTS ' + addpath + ')\n') 585 libvars.append(libvar) 586 fd.write('mark_as_advanced (' + ' '.join(libvars) + ')\n') 587 fd.write('set (PETSC_PACKAGE_LIBS ' + ' '.join(map(cmakeexpand,libvars)) + ')\n') 588 includes = filter(notstandardinclude,includes) 589 fd.write('set (PETSC_PACKAGE_INCLUDES ' + ' '.join(map(lambda i: '"'+i+'"',includes)) + ')\n') 590 fd = open(os.path.join(self.arch.arch,'conf','PETScConfig.cmake'), 'w') 591 writeMacroDefinitions(fd) 592 writeBuildFlags(fd) 593 fd.close() 594 return 595 596 def dumpCMakeLists(self): 597 import sys 598 if sys.version_info >= (2,4): 599 import cmakegen 600 try: 601 cmakegen.main(self.petscdir.dir, log=self.framework.log) 602 except (OSError), e: 603 self.framework.logPrint('Generating CMakeLists.txt failed:\n' + str(e)) 604 else: 605 self.framework.logPrint('Skipping cmakegen due to old python version: ' +str(sys.version_info) ) 606 607 def cmakeBoot(self): 608 import sys 609 self.cmakeboot_success = False 610 if sys.version_info >= (2,4) and hasattr(self.cmake,'cmake'): 611 try: 612 import cmakeboot 613 self.cmakeboot_success = cmakeboot.main(petscdir=self.petscdir.dir,petscarch=self.arch.arch,argDB=self.argDB,framework=self.framework,log=self.framework.log) 614 except (OSError), e: 615 self.framework.logPrint('Booting CMake in PETSC_ARCH failed:\n' + str(e)) 616 except (ImportError, KeyError), e: 617 self.framework.logPrint('Importing cmakeboot failed:\n' + str(e)) 618 if self.cmakeboot_success: 619 if hasattr(self.compilers, 'FC') and self.compilers.fortranIsF90 and not self.setCompilers.fortranModuleOutputFlag: 620 self.framework.logPrint('CMake configured successfully, but could not be used by default because of missing fortranModuleOutputFlag\n') 621 else: 622 self.framework.logPrint('CMake configured successfully, using as default build\n') 623 self.addMakeMacro('PETSC_BUILD_USING_CMAKE',1) 624 else: 625 self.framework.logPrint('CMake configuration was unsuccessful\n') 626 else: 627 self.framework.logPrint('Skipping cmakeboot due to old python version: ' +str(sys.version_info) ) 628 return 629 630 def configurePrefetch(self): 631 '''Sees if there are any prefetch functions supported''' 632 if config.setCompilers.Configure.isSolaris() or self.framework.argDB['with-ios']: 633 self.addDefine('Prefetch(a,b,c)', ' ') 634 return 635 self.pushLanguage(self.languages.clanguage) 636 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 637 # The Intel Intrinsics manual [1] specifies the prototype 638 # 639 # void _mm_prefetch(char const *a, int sel); 640 # 641 # but other vendors seem to insist on using subtly different 642 # prototypes, including void* for the pointer, and an enum for 643 # sel. These are both reasonable changes, but negatively impact 644 # portability. 645 # 646 # [1] http://software.intel.com/file/6373 647 self.addDefine('HAVE_XMMINTRIN_H', 1) 648 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 649 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 650 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 651 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 652 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 653 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 654 self.addDefine('HAVE_XMMINTRIN_H', 1) 655 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 656 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 657 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 658 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 659 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 660 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 661 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 662 # 663 # The value of rw is a compile-time constant one or zero; one 664 # means that the prefetch is preparing for a write to the memory 665 # address and zero, the default, means that the prefetch is 666 # preparing for a read. The value locality must be a compile-time 667 # constant integer between zero and three. A value of zero means 668 # that the data has no temporal locality, so it need not be left 669 # in the cache after the access. A value of three means that the 670 # data has a high degree of temporal locality and should be left 671 # in all levels of cache possible. Values of one and two mean, 672 # respectively, a low or moderate degree of temporal locality. 673 # 674 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 675 # hints. Using macros for these values in necessary since some 676 # compilers require an enum. 677 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 678 self.addDefine('PREFETCH_HINT_NTA', '0') 679 self.addDefine('PREFETCH_HINT_T0', '3') 680 self.addDefine('PREFETCH_HINT_T1', '2') 681 self.addDefine('PREFETCH_HINT_T2', '1') 682 else: 683 self.addDefine('Prefetch(a,b,c)', ' ') 684 self.popLanguage() 685 686 def configureAtoll(self): 687 '''Checks if atoll exists''' 688 if self.checkLink('#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>','long v = atoll("25")') or self.checkLink ('#include <stdlib.h>','long v = atoll("25")'): 689 self.addDefine('HAVE_ATOLL', '1') 690 691 def configureUnused(self): 692 '''Sees if __attribute((unused)) is supported''' 693 if self.framework.argDB['with-ios']: 694 self.addDefine('UNUSED', ' ') 695 return 696 self.pushLanguage(self.languages.clanguage) 697 if self.checkLink('__attribute((unused)) static int myfunc(__attribute((unused)) void *name){ return 1;}', 'int i = 0;\nint j = myfunc(&i);\ntypedef void* atype;\n__attribute((unused)) atype a;\n'): 698 self.addDefine('UNUSED', '__attribute((unused))') 699 else: 700 self.addDefine('UNUSED', ' ') 701 self.popLanguage() 702 703 def configureIsatty(self): 704 '''Check if the Unix C function isatty() works correctly 705 Actually just assumes it does not work correctly on batch systems''' 706 if not self.framework.argDB['with-batch']: 707 self.addDefine('USE_ISATTY',1) 708 709 def configureDeprecated(self): 710 '''Check if __attribute((deprecated)) is supported''' 711 self.pushLanguage(self.languages.clanguage) 712 ## Recent versions of gcc and clang support __attribute((deprecated("string argument"))), which is very useful, but 713 ## Intel has conspired to make a supremely environment-sensitive compiler. The Intel compiler looks at the gcc 714 ## executable in the environment to determine the language compatibility that it should attempt to emulate. Some 715 ## important Cray installations have built PETSc using the Intel compiler, but with a newer gcc module loaded (e.g., 716 ## 4.7). Thus at PETSc configure time, the Intel compiler decides to support the string argument, but the gcc 717 ## found in the default user environment is older and does not support the argument. If GCC and Intel were cool 718 ## like Clang and supported __has_attribute, we could avoid configure tests entirely, but they don't. And that is 719 ## why we can't have nice things. 720 # 721 # if self.checkCompile("""__attribute((deprecated("Why you shouldn't use myfunc"))) static int myfunc(void) { return 1;}""", ''): 722 # self.addDefine('DEPRECATED(why)', '__attribute((deprecated(why)))') 723 if self.checkCompile("""__attribute((deprecated)) static int myfunc(void) { return 1;}""", ''): 724 self.addDefine('DEPRECATED(why)', '__attribute((deprecated))') 725 else: 726 self.addDefine('DEPRECATED(why)', ' ') 727 self.popLanguage() 728 729 def configureExpect(self): 730 '''Sees if the __builtin_expect directive is supported''' 731 self.pushLanguage(self.languages.clanguage) 732 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 733 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 734 self.popLanguage() 735 736 def configureFunctionName(self): 737 '''Sees if the compiler supports __func__ or a variant. Falls back 738 on __FUNCT__ which PETSc source defines, but most users do not, thus 739 stack traces through user code are better when the compiler's 740 variant is used.''' 741 def getFunctionName(lang): 742 name = '__FUNCT__' 743 self.pushLanguage(lang) 744 if self.checkLink('', "if (__func__[0] != 'm') return 1;"): 745 name = '__func__' 746 elif self.checkLink('', "if (__FUNCTION__[0] != 'm') return 1;"): 747 name = '__FUNCTION__' 748 self.popLanguage() 749 return name 750 langs = [] 751 752 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 753 if hasattr(self.compilers, 'CXX'): 754 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 755 else: 756 self.addDefine('FUNCTION_NAME_CXX', '__FUNCT__') 757 758 def configureIntptrt(self): 759 '''Determine what to use for uintptr_t''' 760 def staticAssertSizeMatchesVoidStar(inc,typename): 761 # The declaration is an error if either array size is negative. 762 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 763 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 764 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 765 self.pushLanguage(self.languages.clanguage) 766 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 767 self.addDefine('UINTPTR_T', 'uintptr_t') 768 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 769 self.addDefine('UINTPTR_T', 'unsigned long long') 770 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 771 self.addDefine('UINTPTR_T', 'size_t') 772 elif staticAssertSizeMatchesVoidStar('','unsigned long'): 773 self.addDefine('UINTPTR_T', 'unsigned long') 774 elif staticAssertSizeMatchesVoidStar('','unsigned'): 775 self.addDefine('UINTPTR_T', 'unsigned') 776 else: 777 raise RuntimeError('Could not find any unsigned integer type matching void*') 778 self.popLanguage() 779 780 def configureRTLDDefault(self): 781 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 782 self.addDefine('RTLD_DEFAULT','1') 783 return 784 785 def configureSolaris(self): 786 '''Solaris specific stuff''' 787 if os.path.isdir(os.path.join('/usr','ucblib')): 788 try: 789 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 790 except AttributeError: 791 flag = None 792 if flag is None: 793 self.compilers.LIBS += ' -L/usr/ucblib' 794 else: 795 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 796 return 797 798 def configureLinux(self): 799 '''Linux specific stuff''' 800 # TODO: Test for this by mallocing an odd number of floats and checking the address 801 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 802 return 803 804 def configureWin32(self): 805 '''Win32 non-cygwin specific stuff''' 806 kernel32=0 807 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 808 self.addDefine('HAVE_WINDOWS_H',1) 809 self.addDefine('HAVE_GETCOMPUTERNAME',1) 810 kernel32=1 811 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 812 self.addDefine('HAVE_WINDOWS_H',1) 813 self.addDefine('HAVE_GETCOMPUTERNAME',1) 814 kernel32=1 815 if kernel32: 816 if self.framework.argDB['with-windows-graphics']: 817 self.addDefine('USE_WINDOWS_GRAPHICS',1) 818 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 819 self.addDefine('HAVE_LOADLIBRARY',1) 820 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 821 self.addDefine('HAVE_GETPROCADDRESS',1) 822 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 823 self.addDefine('HAVE_FREELIBRARY',1) 824 if self.checkLink('#include <Windows.h>','GetLastError()'): 825 self.addDefine('HAVE_GETLASTERROR',1) 826 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 827 self.addDefine('HAVE_SETLASTERROR',1) 828 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 829 self.addDefine('USE_MICROSOFT_TIME',1) 830 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 831 self.addDefine('HAVE_GET_USER_NAME',1) 832 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 833 self.addDefine('HAVE_GET_USER_NAME',1) 834 835 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 836 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 837 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 838 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 839 840 self.types.check('int32_t', 'int') 841 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 842 self.addTypedef('int', 'uid_t') 843 self.addTypedef('int', 'gid_t') 844 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 845 self.framework.addDefine('R_OK', '04') 846 self.framework.addDefine('W_OK', '02') 847 self.framework.addDefine('X_OK', '01') 848 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 849 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 850 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 851 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 852 self.addDefine('HAVE_LARGE_INTEGER_U',1) 853 854 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 855 if self.checkCompile('#include <Windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'): 856 self.addDefine('HAVE_O_BINARY',1) 857 858 if self.compilers.CC.find('win32fe') >= 0: 859 self.addDefine('PATH_SEPARATOR','\';\'') 860 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 861 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 862 self.addDefine('CANNOT_START_DEBUGGER',1) 863 (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.petscdir.dir) 864 self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"') 865 else: 866 self.addDefine('PATH_SEPARATOR','\':\'') 867 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 868 self.addDefine('DIR_SEPARATOR','\'/\'') 869 self.addDefine('DIR', '"'+self.petscdir.dir+'"') 870 871 return 872 873#----------------------------------------------------------------------------------------------------- 874 def configureCygwinBrokenPipe(self): 875 '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make 876 http://cygwin.com/ml/cygwin/2013-05/msg00340.html ''' 877 if config.setCompilers.Configure.isCygwin(): 878 import platform 879 import re 880 r=re.compile("([0-9]+).([0-9]+).([0-9]+)") 881 m=r.match(platform.release()) 882 major=int(m.group(1)) 883 minor=int(m.group(2)) 884 subminor=int(m.group(3)) 885 if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)): 886 self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1') 887 return 888 889#----------------------------------------------------------------------------------------------------- 890 def configureDefaultArch(self): 891 conffile = os.path.join('conf', 'petscvariables') 892 if self.framework.argDB['with-default-arch']: 893 fd = file(conffile, 'w') 894 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 895 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 896 fd.write('include '+os.path.join(self.petscdir.dir,self.arch.arch,'conf','petscvariables')+'\n') 897 fd.close() 898 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 899 elif os.path.isfile(conffile): 900 try: 901 os.unlink(conffile) 902 except: 903 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 904 return 905 906#----------------------------------------------------------------------------------------------------- 907 def configureScript(self): 908 '''Output a script in the conf directory which will reproduce the configuration''' 909 import nargs 910 import sys 911 scriptName = os.path.join(self.arch.arch,'conf', 'reconfigure-'+self.arch.arch+'.py') 912 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 913 if 'with-clean' in args: 914 del args['with-clean'] 915 if 'configModules' in args: 916 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 917 del args['configModules'] 918 if 'optionsModule' in args: 919 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions': 920 del args['optionsModule'] 921 if not 'PETSC_ARCH' in args: 922 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 923 f = file(scriptName, 'w') 924 f.write('#!'+sys.executable+'\n') 925 f.write('if __name__ == \'__main__\':\n') 926 f.write(' import sys\n') 927 f.write(' import os\n') 928 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 929 f.write(' import configure\n') 930 # pretty print repr(args.values()) 931 f.write(' configure_options = [\n') 932 for itm in sorted(args.values()): 933 f.write(' \''+str(itm)+'\',\n') 934 f.write(' ]\n') 935 f.write(' configure.petsc_configure(configure_options)\n') 936 f.close() 937 try: 938 os.chmod(scriptName, 0775) 939 except OSError, e: 940 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 941 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 942 return 943 944 def configureInstall(self): 945 '''Setup the directories for installation''' 946 if self.framework.argDB['prefix']: 947 self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\ 948 '-@echo "'+self.installdir.installSudo+'make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 949 '-@echo "========================================="']) 950 self.installdir = self.framework.argDB['prefix'] 951 else: 952 self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\ 953 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} test"',\ 954 '-@echo "========================================="']) 955 self.installdir = os.path.join(self.petscdir.dir,self.arch.arch) 956 return 957 958 def configureGCOV(self): 959 if self.framework.argDB['with-gcov']: 960 self.addDefine('USE_GCOV','1') 961 return 962 963 def configureFortranFlush(self): 964 if hasattr(self.compilers, 'FC'): 965 for baseName in ['flush','flush_']: 966 if self.libraries.check('', baseName, otherLibs = self.compilers.flibs, fortranMangle = 1): 967 self.addDefine('HAVE_'+baseName.upper(), 1) 968 return 969 970 def postProcessPackages(self): 971 postPackages=[] 972 for i in self.framework.packages: 973 if hasattr(i,'postProcess'): postPackages.append(i) 974 if postPackages: 975 # ctetgen needs petsc conf files. so attempt to create them early 976 self.framework.dumpConfFiles() 977 for i in postPackages: i.postProcess() 978 return 979 980 def configure(self): 981 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 982 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 983 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 984 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 985 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)): 986 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 987 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 988 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 989 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'conf','petscvariables') 990 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'conf','petscrules') 991 if self.libraries.math is None: 992 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 993 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 994 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 995 self.executeTest(self.configureRTLDDefault) 996 self.executeTest(self.configurePrefetch) 997 self.executeTest(self.configureUnused) 998 self.executeTest(self.configureDeprecated) 999 self.executeTest(self.configureIsatty) 1000 self.executeTest(self.configureExpect); 1001 self.executeTest(self.configureFunctionName); 1002 self.executeTest(self.configureIntptrt); 1003 self.executeTest(self.configureSolaris) 1004 self.executeTest(self.configureLinux) 1005 self.executeTest(self.configureWin32) 1006 self.executeTest(self.configureCygwinBrokenPipe) 1007 self.executeTest(self.configureDefaultArch) 1008 self.executeTest(self.configureScript) 1009 self.executeTest(self.configureInstall) 1010 self.executeTest(self.configureGCOV) 1011 self.executeTest(self.configureFortranFlush) 1012 self.executeTest(self.configureAtoll) 1013 # dummy rules, always needed except for remote builds 1014 self.addMakeRule('remote','') 1015 self.addMakeRule('remoteclean','') 1016 1017 self.Dump() 1018 self.dumpConfigInfo() 1019 self.dumpMachineInfo() 1020 self.postProcessPackages() 1021 self.dumpCMakeConfig() 1022 self.dumpCMakeLists() 1023 self.cmakeBoot() 1024 self.DumpPkgconfig() 1025 self.DumpModule() 1026 self.framework.log.write('================================================================================\n') 1027 self.logClear() 1028 return 1029