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