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