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