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