1import config.base 2 3import os 4import sys 5import re 6import pickle 7 8class Configure(config.base.Configure): 9 def __init__(self, framework): 10 config.base.Configure.__init__(self, framework) 11 self.headerPrefix = 'PETSC' 12 self.substPrefix = 'PETSC' 13 self.installed = 0 # 1 indicates that Configure itself has already compiled and installed PETSc 14 self.found = 1 15 return 16 17 def __str2__(self): 18 desc = [' Using GNU make: ' + self.make.make] 19 if self.defines.get('USE_COVERAGE'): 20 desc.extend([ 21 ' Code coverage: yes', 22 ' Using code coverage executable: {}'.format(self.getMakeMacro('PETSC_COVERAGE_EXEC')) 23 ]) 24 if not self.installed: 25 desc.append('xxx=========================================================================xxx') 26 desc.append(' Configure stage complete. Now build PETSc libraries with:') 27 desc.append(' %s PETSC_DIR=%s PETSC_ARCH=%s all' % (self.make.make_user, self.petscdir.dir, self.arch.arch)) 28 desc.append('xxx=========================================================================xxx') 29 else: 30 desc.append('xxx=========================================================================xxx') 31 desc.append(' Installation complete. You do not need to run make to compile or install the software') 32 desc.append('xxx=========================================================================xxx') 33 desc.append('') 34 return '\n'.join(desc) 35 36 def setupHelp(self, help): 37 import nargs 38 help.addArgument('PETSc', '-prefix=<dir>', nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)')) 39 help.addArgument('PETSc', '-with-prefetch=<bool>', nargs.ArgBool(None, 1,'Enable checking for prefetch instructions')) 40 help.addArgument('Windows','-with-windows-graphics=<bool>', nargs.ArgBool(None, 1,'Enable check for Windows Graphics')) 41 help.addArgument('PETSc', '-with-default-arch=<bool>', nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH')) 42 help.addArgument('PETSc','-with-single-library=<bool>', nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library')) 43 help.addArgument('PETSc','-with-fortran-bindings=<bool>', nargs.ArgBool(None, 1,'Build PETSc fortran bindings in the library and corresponding module files')) 44 help.addArgument('PETSc', '-with-ios=<bool>', nargs.ArgBool(None, 0, 'Build an iPhone/iPad version of PETSc library')) 45 help.addArgument('PETSc', '-with-display=<x11display>', nargs.Arg(None, '', 'Specifiy DISPLAY env variable for use with matlab test)')) 46 help.addArgument('PETSc', '-with-package-scripts=<pyscripts>', nargs.ArgFileList(None,None,'Specify configure package scripts for user provided packages')) 47 help.addArgument('PETSc', '-with-coverage=<bool>', nargs.ArgFuzzyBool(None, value=0, help='Enable or disable code-coverage collection')) 48 help.addArgument('PETSc', '-with-coverage-exec=<executable>', nargs.ArgExecutable(None, value='default-auto', mustExist=0, help='Name of executable to use for post-processing coverage data, e.g. \'gcov\' or \'llvm-cov\'. Pass \'auto\' to let configure infer from compiler')) 49 help.addArgument('PETSc', '-with-tau-perfstubs=<bool>', nargs.ArgBool(None, 1,'Enable TAU profiler stubs')) 50 help.addArgument('PETSc', '-with-strict-petscerrorcode=<bool>', nargs.ArgFuzzyBool(None, value=0, help='Enable strict PetscErrorCode mode, which enables additional compile-time checking for misuse of PetscErrorCode and error handling')) 51 return 52 53 def registerPythonFile(self,filename,directory): 54 ''' Add a python file to the framework and registers its headerprefix, ... externalpackagedir 55 directory is the directory where the file relative to the BuildSystem or config path in python notation with . ''' 56 (utilityName, ext) = os.path.splitext(filename) 57 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 58 if directory: directory = directory+'.' 59 utilityObj = self.framework.require(directory+utilityName, self) 60 utilityObj.headerPrefix = self.headerPrefix 61 utilityObj.archProvider = self.arch 62 utilityObj.languageProvider = self.languages 63 utilityObj.installDirProvider = self.installdir 64 utilityObj.externalPackagesDirProvider = self.externalpackagesdir 65 utilityObj.precisionProvider = self.scalartypes 66 utilityObj.indexProvider = self.indexTypes 67 setattr(self, utilityName.lower(), utilityObj) 68 return utilityObj 69 return None 70 71 def setupDependencies(self, framework): 72 config.base.Configure.setupDependencies(self, framework) 73 self.programs = framework.require('config.programs', self) 74 self.setCompilers = framework.require('config.setCompilers', self) 75 self.compilerFlags = framework.require('config.compilerFlags', self) 76 self.compilers = framework.require('config.compilers', self) 77 self.arch = framework.require('PETSc.options.arch', self.setCompilers) 78 self.petscdir = framework.require('PETSc.options.petscdir', self.arch) 79 self.installdir = framework.require('PETSc.options.installDir', self) 80 self.dataFilesPath = framework.require('PETSc.options.dataFilesPath',self) 81 self.scalartypes = framework.require('PETSc.options.scalarTypes', self) 82 self.indexTypes = framework.require('PETSc.options.indexTypes', self) 83 self.languages = framework.require('PETSc.options.languages', self.setCompilers) 84 self.indexTypes = framework.require('PETSc.options.indexTypes', self.compilers) 85 self.types = framework.require('config.types', self) 86 self.headers = framework.require('config.headers', self) 87 self.functions = framework.require('config.functions', self) 88 self.libraries = framework.require('config.libraries', self) 89 self.atomics = framework.require('config.atomics', self) 90 self.make = framework.require('config.packages.make', self) 91 self.blasLapack = framework.require('config.packages.BlasLapack',self) 92 self.mpi = framework.require('config.packages.MPI', self) 93 self.fortran = framework.require('config.compilersFortran', self) 94 self.externalpackagesdir = framework.require('PETSc.options.externalpackagesdir',self) 95 96 for utility in sorted(os.listdir(os.path.join('config','PETSc','options'))): 97 self.registerPythonFile(utility,'PETSc.options') 98 99 for utility in sorted(os.listdir(os.path.join('config','BuildSystem','config','utilities'))): 100 self.registerPythonFile(utility,'config.utilities') 101 102 for package in sorted(os.listdir(os.path.join('config', 'BuildSystem', 'config', 'packages'))): 103 obj = self.registerPythonFile(package,'config.packages') 104 if obj: 105 obj.archProvider = self.framework.requireModule(obj.archProvider, obj) 106 obj.languageProvider = self.framework.requireModule(obj.languageProvider, obj) 107 obj.installDirProvider = self.framework.requireModule(obj.installDirProvider, obj) 108 obj.externalPackagesDirProvider = self.framework.requireModule(obj.externalPackagesDirProvider, obj) 109 obj.precisionProvider = self.framework.requireModule(obj.precisionProvider, obj) 110 obj.indexProvider = self.framework.requireModule(obj.indexProvider, obj) 111 112 # Force blaslapack and opencl to depend on scalarType so precision is set before BlasLapack is built 113 framework.require('PETSc.options.scalarTypes', self.f2cblaslapack) 114 framework.require('PETSc.options.scalarTypes', self.fblaslapack) 115 framework.require('PETSc.options.scalarTypes', self.blaslapack) 116 framework.require('PETSc.options.scalarTypes', self.opencl) 117 118 self.programs.headerPrefix = self.headerPrefix 119 self.setCompilers.headerPrefix = self.headerPrefix 120 self.compilers.headerPrefix = self.headerPrefix 121 self.fortran.headerPrefix = self.headerPrefix 122 self.types.headerPrefix = self.headerPrefix 123 self.headers.headerPrefix = self.headerPrefix 124 self.functions.headerPrefix = self.headerPrefix 125 self.libraries.headerPrefix = self.headerPrefix 126 127 # Register user provided package scripts 128 if 'with-package-scripts' in self.framework.argDB: 129 for script in self.framework.argDB['with-package-scripts']: 130 if os.path.splitext(script)[1] != '.py': 131 raise RuntimeError('Only python scripts compatible with configure package script format should be specified! Invalid option -with-package-scripts='+script) 132 self.framework.logPrint('User is registering a new package script: '+script) 133 dname,fname = os.path.split(script) 134 if dname: sys.path.append(dname) 135 self.registerPythonFile(fname,'') 136 137 # test for a variety of basic headers and functions 138 headersC = map(lambda name: name+'.h',['setjmp','dos','fcntl','float','io','malloc','pwd','strings', 139 'unistd','sys/sysinfo','machine/endian','sys/param','sys/procfs','sys/resource', 140 'sys/systeminfo','sys/times','sys/utsname', 141 'sys/socket','sys/wait','netinet/in','netdb','direct','time','Ws2tcpip','sys/types', 142 'WindowsX','float','ieeefp','stdint','inttypes','immintrin']) 143 functions = ['access','_access','clock','drand48','getcwd','_getcwd','getdomainname','gethostname', 144 'getwd','posix_memalign','popen','PXFGETARG','rand','getpagesize', 145 'readlink','realpath','usleep','sleep','_sleep', 146 'uname','snprintf','_snprintf','lseek','_lseek','time','fork','stricmp', 147 'strcasecmp','bzero','dlopen','dlsym','dlclose','dlerror', 148 '_set_output_format','_mkdir','socket','gethostbyname','fpresetsticky', 149 'fpsetsticky','__gcov_dump'] 150 libraries = [(['fpe'],'handle_sigfpes')] 151 librariessock = [(['socket','nsl'],'socket')] 152 self.headers.headers.extend(headersC) 153 self.functions.functions.extend(functions) 154 self.libraries.libraries.extend(libraries) 155 if not hasattr(self,'socket'): 156 self.libraries.libraries.extend(librariessock) 157 return 158 159 def DumpPkgconfig(self, petsc_pc): 160 ''' Create a pkg-config file ''' 161 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')): 162 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')) 163 with open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig',petsc_pc),'w') as fd: 164 cflags_inc = ['-I${includedir}'] 165 if self.framework.argDB['prefix']: 166 fd.write('prefix='+self.installdir.dir+'\n') 167 else: 168 fd.write('prefix='+os.path.join(self.petscdir.dir, self.arch.arch)+'\n') 169 cflags_inc.append('-I' + os.path.join(self.petscdir.dir, 'include')) 170 fd.write('exec_prefix=${prefix}\n') 171 fd.write('includedir=${prefix}/include\n') 172 fd.write('libdir=${prefix}/lib\n') 173 174 with self.setCompilers.Language('C'): 175 fd.write('ccompiler='+self.setCompilers.getCompiler()+'\n') 176 fd.write('cflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 177 fd.write('cflags_dep='+self.compilers.dependenciesGenerationFlag.get('C','')+'\n') 178 fd.write('ldflag_rpath='+self.setCompilers.CSharedLinkerFlag+'\n') 179 if hasattr(self.compilers, 'CXX'): 180 with self.setCompilers.Language('C++'): 181 fd.write('cxxcompiler='+self.setCompilers.getCompiler()+'\n') 182 fd.write('cxxflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 183 if hasattr(self.compilers, 'FC'): 184 with self.setCompilers.Language('FC'): 185 fd.write('fcompiler='+self.setCompilers.getCompiler()+'\n') 186 fd.write('fflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 187 if hasattr(self.compilers, 'CUDAC'): 188 with self.setCompilers.Language('CUDA'): 189 fd.write('cudacompiler='+self.setCompilers.getCompiler()+'\n') 190 fd.write('cudaflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 191 p = self.framework.require('config.packages.cuda') 192 fd.write('cudalib='+self.libraries.toStringNoDupes(p.lib)+'\n') 193 fd.write('cudainclude='+self.headers.toStringNoDupes(p.include)+'\n') 194 if hasattr(self.setCompilers,'CUDA_CXX'): 195 fd.write('cuda_cxx='+self.setCompilers.CUDA_CXX+'\n') 196 fd.write('cuda_cxxflags='+self.setCompilers.CUDA_CXXFLAGS+'\n') 197 198 fd.write('\n') 199 fd.write('Name: PETSc\n') 200 fd.write('Description: Library to solve ODEs and algebraic equations\n') 201 fd.write('Version: %s\n' % self.petscdir.version) 202 fd.write('Cflags: ' + ' '.join([self.setCompilers.CPPFLAGS] + cflags_inc) + '\n') 203 fd.write('Libs: '+self.libraries.toStringNoDupes(['-L${libdir}', self.petsclib], with_rpath=False)+'\n') 204 # Remove RPATH flags from library list. User can add them using 205 # pkg-config --variable=ldflag_rpath and pkg-config --libs-only-L 206 fd.write('Libs.private: '+self.libraries.toStringNoDupes([f for f in self.packagelibs+self.complibs if not f.startswith(self.setCompilers.CSharedLinkerFlag)], with_rpath=False)+'\n') 207 return 208 209 def DumpModule(self): 210 ''' Create a module file ''' 211 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')): 212 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')) 213 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')): 214 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')) 215 if self.framework.argDB['prefix']: 216 installdir = self.installdir.dir 217 installarch = '' 218 installpath = os.path.join(installdir,'bin') 219 else: 220 installdir = self.petscdir.dir 221 installarch = self.arch.arch 222 installpath = os.path.join(installdir,installarch,'bin')+':'+os.path.join(installdir,'bin') 223 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc',self.petscdir.version),'w') 224 fd.write('''\ 225#%%Module 226 227proc ModulesHelp { } { 228 puts stderr "This module sets the path and environment variables for petsc-%s" 229 puts stderr " see https://petsc.org/ for more information " 230 puts stderr "" 231} 232module-whatis "PETSc - Portable, Extensible Toolkit for Scientific Computation" 233 234set petsc_dir "%s" 235set petsc_arch "%s" 236 237setenv PETSC_ARCH "$petsc_arch" 238setenv PETSC_DIR "$petsc_dir" 239prepend-path PATH "%s" 240''' % (self.petscdir.version, installdir, installarch, installpath)) 241 fd.close() 242 return 243 244 def Dump(self): 245 ''' Actually put the values into the configuration files ''' 246 # eventually everything between -- should be gone 247 if self.mpi.usingMPIUni: 248 # 249 # Remove any MPI/MPICH include files that may have been put here by previous runs of ./configure 250 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*'), log = self.log) 251 252 self.logPrintDivider() 253 # Test for compiler-specific macros that need to be defined. 254 if self.setCompilers.isCrayVector('CC', self.log): 255 self.addDefine('HAVE_CRAY_VECTOR','1') 256 257 if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket') and self.headers.haveHeader('netinet/in.h'): 258 self.addDefine('USE_SOCKET_VIEWER','1') 259 if self.checkCompile('#include <sys/socket.h>','setsockopt(0,SOL_SOCKET,SO_REUSEADDR,0,0)'): 260 self.addDefine('HAVE_SO_REUSEADDR','1') 261 262 self.logPrintDivider() 263 self.setCompilers.pushLanguage('C') 264 compiler = self.setCompilers.getCompiler() 265 if [s for s in ['mpicc','mpiicc'] if os.path.basename(compiler).find(s)>=0]: 266 try: 267 output = self.executeShellCommand(compiler + ' -show', log = self.log)[0] 268 compiler = output.split(' ')[0] 269 self.addDefine('MPICC_SHOW','"'+output.strip().replace('\n','\\\\n').replace('"','')+'"') 270 except: 271 self.addDefine('MPICC_SHOW','"Unavailable"') 272 else: 273 self.addDefine('MPICC_SHOW','"Unavailable"') 274 self.setCompilers.popLanguage() 275#----------------------------------------------------------------------------------------------------- 276 277 # Sometimes we need C compiler, even if built with C++ 278 self.setCompilers.pushLanguage('C') 279 # do not use getCompilerFlags() because that automatically includes the CPPFLAGS so one ends up with duplication flags in makefile usage 280 self.addMakeMacro('CC_FLAGS',self.setCompilers.CFLAGS) 281 self.setCompilers.popLanguage() 282 283 # And sometimes we need a C++ compiler even when PETSc is built with C 284 if hasattr(self.compilers, 'CXX'): 285 self.setCompilers.pushLanguage('Cxx') 286 self.addDefine('HAVE_CXX','1') 287 self.addMakeMacro('CXXPP_FLAGS',self.setCompilers.CXXPPFLAGS) 288 # do not use getCompilerFlags() because that automatically includes the CXXPPFLAGS so one ends up with duplication flags in makefile usage 289 self.addMakeMacro('CXX_FLAGS',self.setCompilers.CXXFLAGS+' '+self.setCompilers.CXX_CXXFLAGS) 290 cxx_linker = self.setCompilers.getLinker() 291 self.addMakeMacro('CXX_LINKER',cxx_linker) 292 self.addMakeMacro('CXX_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 293 self.setCompilers.popLanguage() 294 295 # C preprocessor values 296 self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS) 297 298 # compiler values 299 self.setCompilers.pushLanguage(self.languages.clanguage) 300 self.addMakeMacro('PCC',self.setCompilers.getCompiler()) 301 # do not use getCompilerFlags() because that automatically includes the preprocessor flags so one ends up with duplication flags in makefile usage 302 if self.languages.clanguage == 'C': 303 self.addMakeMacro('PCC_FLAGS','$(CC_FLAGS)') 304 else: 305 self.addMakeMacro('PCC_FLAGS','$(CXX_FLAGS)') 306 self.setCompilers.popLanguage() 307 # .o or .obj 308 self.addMakeMacro('CC_SUFFIX','o') 309 310 # executable linker values 311 self.setCompilers.pushLanguage(self.languages.clanguage) 312 pcc_linker = self.setCompilers.getLinker() 313 self.addMakeMacro('PCC_LINKER',pcc_linker) 314 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 315 self.setCompilers.popLanguage() 316 # '' for Unix, .exe for Windows 317 self.addMakeMacro('CC_LINKER_SUFFIX','') 318 319 if hasattr(self.compilers, 'FC'): 320 if self.framework.argDB['with-fortran-bindings']: 321 if not self.fortran.fortranIsF90: 322 raise RuntimeError('Error! Fortran compiler "'+self.compilers.FC+'" does not support F90! PETSc fortran bindings require a F90 compiler') 323 self.addDefine('HAVE_FORTRAN','1') 324 self.setCompilers.pushLanguage('FC') 325 # need FPPFLAGS in config/setCompilers 326 self.addMakeMacro('FPP_FLAGS',self.setCompilers.FPPFLAGS) 327 328 # compiler values 329 self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags()) 330 self.setCompilers.popLanguage() 331 # .o or .obj 332 self.addMakeMacro('FC_SUFFIX','o') 333 334 # executable linker values 335 self.setCompilers.pushLanguage('FC') 336 self.addMakeMacro('FC_LINKER',self.setCompilers.getLinker()) 337 self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 338 # apple requires this shared library linker flag on SOME versions of the os 339 if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1: 340 self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ') 341 self.setCompilers.popLanguage() 342 343 # F90 Modules 344 if self.setCompilers.fortranModuleIncludeFlag: 345 self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag) 346 else: # for non-f90 compilers like g77 347 self.addMakeMacro('FC_MODULE_FLAG', '-I') 348 if self.setCompilers.fortranModuleIncludeFlag: 349 self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag) 350 else: 351 self.addMakeMacro('FC','') 352 353 if hasattr(self.compilers, 'CUDAC'): 354 self.setCompilers.pushLanguage('CUDA') 355 self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags()) 356 self.addMakeMacro('CUDAPP_FLAGS',self.setCompilers.CUDAPPFLAGS) 357 self.setCompilers.popLanguage() 358 359 if hasattr(self.compilers, 'HIPC'): 360 self.setCompilers.pushLanguage('HIP') 361 self.addMakeMacro('HIPC_FLAGS',self.setCompilers.getCompilerFlags()) 362 self.addMakeMacro('HIPPP_FLAGS',self.setCompilers.HIPPPFLAGS) 363 self.setCompilers.popLanguage() 364 365 if hasattr(self.compilers, 'SYCLC'): 366 self.setCompilers.pushLanguage('SYCL') 367 self.addMakeMacro('SYCLC_FLAGS',self.setCompilers.getCompilerFlags()) 368 self.addMakeMacro('SYCLPP_FLAGS',self.setCompilers.SYCLPPFLAGS) 369 self.setCompilers.popLanguage() 370 371 # shared library linker values 372 self.setCompilers.pushLanguage(self.languages.clanguage) 373 # need to fix BuildSystem to collect these separately 374 self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker()) 375 self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}') 376 self.setCompilers.popLanguage() 377 # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture 378 # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX 379 if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX: 380 self.addMakeMacro('SL_LINKER_SUFFIX', '') 381 self.addDefine('SLSUFFIX','""') 382 else: 383 self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt) 384 self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"') 385 386 self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}') 387 388#----------------------------------------------------------------------------------------------------- 389 390 # CONLY or CPP. We should change the PETSc makefiles to do this better 391 if self.languages.clanguage == 'C': lang = 'CONLY' 392 else: lang = 'CXXONLY' 393 self.addMakeMacro('PETSC_LANGUAGE',lang) 394 395 # real or complex 396 self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype) 397 # double or float 398 self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision) 399 400 if self.framework.argDB['with-batch']: 401 self.addMakeMacro('PETSC_WITH_BATCH','1') 402 403#----------------------------------------------------------------------------------------------------- 404 # print include and lib for makefiles 405 self.logPrintDivider() 406 self.framework.packages.reverse() 407 petscincludes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')] 408 petscincludes_install = [os.path.join(self.installdir.dir, 'include')] if self.framework.argDB['prefix'] else petscincludes 409 includes = [] 410 self.packagelibs = [] 411 for i in self.framework.packages: 412 if not i.required: 413 if i.devicePackage: 414 self.addDefine('HAVE_DEVICE',1) 415 self.addDefine('HAVE_'+i.PACKAGE.replace('-','_'), 1) # ONLY list package if it is used directly by PETSc (and not only by another package) 416 if not isinstance(i.lib, list): 417 i.lib = [i.lib] 418 if i.linkedbypetsc: self.packagelibs.extend(i.lib) 419 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_LIB', self.libraries.toStringNoDupes(i.lib)) 420 if hasattr(i,'include'): 421 if not isinstance(i.include,list): 422 i.include = [i.include] 423 includes.extend(i.include) 424 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include)) 425 if self.framework.argDB['with-single-library']: 426 self.petsclib = '-lpetsc' 427 else: 428 self.petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys' 429 self.complibs = self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split() 430 self.PETSC_WITH_EXTERNAL_LIB = self.libraries.toStringNoDupes(['-L${PETSC_DIR}/${PETSC_ARCH}/lib', self.petsclib]+self.packagelibs+self.complibs) 431 self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(self.packagelibs+self.complibs) 432 433 self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',self.PETSC_EXTERNAL_LIB_BASIC) 434 allincludes = petscincludes + includes 435 allincludes_install = petscincludes_install + includes 436 self.PETSC_CC_INCLUDES = self.headers.toStringNoDupes(allincludes) 437 self.PETSC_CC_INCLUDES_INSTALL = self.headers.toStringNoDupes(allincludes_install) 438 self.addMakeMacro('PETSC_CC_INCLUDES',self.PETSC_CC_INCLUDES) 439 self.addMakeMacro('PETSC_CC_INCLUDES_INSTALL', self.PETSC_CC_INCLUDES_INSTALL) 440 if hasattr(self.compilers, 'FC'): 441 def modinc(includes): 442 return includes if self.fortran.fortranIsF90 else [] 443 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(allincludes,modinc(allincludes))) 444 self.addMakeMacro('PETSC_FC_INCLUDES_INSTALL',self.headers.toStringNoDupes(allincludes_install,modinc(allincludes_install))) 445 446 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir.dir,'lib')+'"') 447 448 if self.framework.argDB['with-single-library']: 449 # overrides the values set in conf/variables 450 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 451 self.addMakeMacro('SHLIBS','libpetsc') 452 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 453 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 454 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 455 self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc') 456 self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.PETSC_WITH_EXTERNAL_LIB) 457 self.addDefine('USE_SINGLE_LIBRARY', '1') 458 if self.sharedlibraries.useShared: 459 self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 460 self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 461 self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 462 self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 463 self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 464 self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 465 self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 466 self.addMakeMacro('PETSC_TAO_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 467 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 468 self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 469 self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 470 else: 471 self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 472 self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 473 self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}') 474 self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}') 475 self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}') 476 self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}') 477 self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 478 self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}') 479 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 480 self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 481 self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}') 482 483 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 484 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 485 486# add a makefile endtry for display 487 if self.framework.argDB['with-display']: 488 self.addMakeMacro('DISPLAY',self.framework.argDB['with-display']) 489 490 # add a makefile entry for configure options 491 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 492 493 if self.framework.argDB['with-tau-perfstubs']: 494 self.addDefine('HAVE_TAU_PERFSTUBS',1) 495 return 496 497 def dumpConfigInfo(self): 498 import time 499 fd = open(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 500 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"').replace('\\ ','\\\\ ')+'";\n') 501 fd.close() 502 return 503 504 def dumpMachineInfo(self): 505 import platform 506 import datetime 507 import time 508 import script 509 def escape(s): 510 return s.replace('"',r'\"').replace(r'\ ',r'\\ ') # novermin 511 fd = open(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 512 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 513 fd.write('\"-----------------------------------------\\n\"\n') 514 buildhost = platform.node() 515 if os.environ.get('SOURCE_DATE_EPOCH'): 516 buildhost = "reproducible" 517 buildtime = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) 518 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (buildtime, buildhost)) 519 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 520 fd.write('\"Using PETSc directory: %s\\n\"\n' % (escape(self.installdir.petscDir))) 521 fd.write('\"Using PETSc arch: %s\\n\"\n' % (escape(self.installdir.petscArch))) 522 fd.write('\"-----------------------------------------\\n\";\n') 523 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 524 self.setCompilers.pushLanguage(self.languages.clanguage) 525 fd.write('\"Using C compiler: %s %s \\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()))) 526 self.setCompilers.popLanguage() 527 if hasattr(self.compilers, 'FC'): 528 self.setCompilers.pushLanguage('FC') 529 fd.write('\"Using Fortran compiler: %s %s %s\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()), escape(self.setCompilers.CPPFLAGS))) 530 self.setCompilers.popLanguage() 531 fd.write('\"-----------------------------------------\\n\";\n') 532 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 533 fd.write('\"Using include paths: %s\\n\"\n' % (escape(self.PETSC_CC_INCLUDES_INSTALL.replace('${PETSC_DIR}', self.installdir.petscDir)))) 534 fd.write('\"-----------------------------------------\\n\";\n') 535 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 536 self.setCompilers.pushLanguage(self.languages.clanguage) 537 fd.write('\"Using C linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 538 self.setCompilers.popLanguage() 539 if hasattr(self.compilers, 'FC'): 540 self.setCompilers.pushLanguage('FC') 541 fd.write('\"Using Fortran linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 542 self.setCompilers.popLanguage() 543 fd.write('\"Using libraries: %s%s -L%s %s %s\\n\"\n' % (escape(self.setCompilers.CSharedLinkerFlag), escape(os.path.join(self.installdir.petscDir, self.installdir.petscArch, 'lib')), escape(os.path.join(self.installdir.petscDir, self.installdir.petscArch, 'lib')), escape(self.petsclib), escape(self.PETSC_EXTERNAL_LIB_BASIC))) 544 fd.write('\"-----------------------------------------\\n\";\n') 545 fd.close() 546 return 547 548 def configurePrefetch(self): 549 '''Sees if there are any prefetch functions supported''' 550 if config.setCompilers.Configure.isSolaris(self.log) or self.framework.argDB['with-ios'] or not self.framework.argDB['with-prefetch']: 551 self.addDefine('Prefetch(a,b,c)', ' ') 552 return 553 self.pushLanguage(self.languages.clanguage) 554 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 555 # The Intel Intrinsics manual [1] specifies the prototype 556 # 557 # void _mm_prefetch(char const *a, int sel); 558 # 559 # but other vendors seem to insist on using subtly different 560 # prototypes, including void* for the pointer, and an enum for 561 # sel. These are both reasonable changes, but negatively impact 562 # portability. 563 # 564 # [1] https://software.intel.com/file/6373 565 self.addDefine('HAVE_XMMINTRIN_H', 1) 566 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 567 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 568 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 569 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 570 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 571 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 572 self.addDefine('HAVE_XMMINTRIN_H', 1) 573 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 574 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 575 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 576 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 577 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 578 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 579 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 580 # 581 # The value of rw is a compile-time constant one or zero; one 582 # means that the prefetch is preparing for a write to the memory 583 # address and zero, the default, means that the prefetch is 584 # preparing for a read. The value locality must be a compile-time 585 # constant integer between zero and three. A value of zero means 586 # that the data has no temporal locality, so it need not be left 587 # in the cache after the access. A value of three means that the 588 # data has a high degree of temporal locality and should be left 589 # in all levels of cache possible. Values of one and two mean, 590 # respectively, a low or moderate degree of temporal locality. 591 # 592 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 593 # hints. Using macros for these values in necessary since some 594 # compilers require an enum. 595 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 596 self.addDefine('PREFETCH_HINT_NTA', '0') 597 self.addDefine('PREFETCH_HINT_T0', '3') 598 self.addDefine('PREFETCH_HINT_T1', '2') 599 self.addDefine('PREFETCH_HINT_T2', '1') 600 else: 601 self.addDefine('Prefetch(a,b,c)', ' ') 602 self.popLanguage() 603 604 def delGenFiles(self): 605 '''Delete generated files''' 606 delfile = os.path.join(self.arch.arch,'lib','petsc','conf','files') 607 try: 608 os.unlink(delfile) 609 except: pass 610 611 def configureAtoll(self): 612 '''Checks if atoll exists''' 613 if self.checkLink('#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>','long v = atoll("25");\n(void)v') or self.checkLink ('#include <stdlib.h>','long v = atoll("25");\n(void)v'): 614 self.addDefine('HAVE_ATOLL', '1') 615 616 def configureUnused(self): 617 '''Sees if __attribute((unused)) is supported''' 618 if self.framework.argDB['with-ios']: 619 self.addDefine('UNUSED', ' ') 620 return 621 self.pushLanguage(self.languages.clanguage) 622 if self.checkLink('__attribute((unused)) static int myfunc(__attribute((unused)) void *name){ return 1;}', 'int i = 0;\nint j = myfunc(&i);\n(void)j;\ntypedef void* atype;\n__attribute((unused)) atype a'): 623 self.addDefine('UNUSED', '__attribute((unused))') 624 else: 625 self.addDefine('UNUSED', ' ') 626 self.popLanguage() 627 628 def configureIsatty(self): 629 '''Check if the Unix C function isatty() works correctly 630 Actually just assumes it does not work correctly on batch systems''' 631 if not self.framework.argDB['with-batch']: 632 self.addDefine('USE_ISATTY',1) 633 634 def configureDeprecated(self): 635 '''Check if __attribute((deprecated)) is supported''' 636 def checkDeprecated(macro_base, src, is_intel): 637 ''' 638 run through the various attribute deprecated combinations and define MACRO_BAS(why) to the result 639 it if it compiles. 640 641 If none of the combos work, defines MACRO_BASE(why) as empty 642 ''' 643 full_macro_name = macro_base + '(why)' 644 for prefix in ('__attribute__', '__attribute','__declspec'): 645 if prefix == '__declspec': 646 # declspec does not have an extra set of brackets around the arguments 647 attr_bodies = ('deprecated(why)', 'deprecated') 648 else: 649 attr_bodies = ('(deprecated(why))', '(deprecated)') 650 651 for attr_body in attr_bodies: 652 attr_def = '{}({})'.format(prefix, attr_body) 653 test_src = '\n'.join(( 654 '#define {} {}'.format(full_macro_name, attr_def), 655 src.format(macro_base + '("asdasdadsasd")') 656 )) 657 if self.checkCompile(test_src, ''): 658 self.logPrint('configureDeprecated: \'{}\' appears to work'.format(attr_def)) 659 if is_intel and '(why)' in attr_body: 660 self.logPrint('configureDeprecated: Intel has conspired to make a supremely environment-sensitive compiler. The Intel compiler looks at the gcc executable in the environment to determine the language compatibility that it should attempt to emulate. Some important Cray installations have built PETSc using the Intel compiler, but with a newer gcc module loaded (e.g. 4.7). Thus at PETSc configure time, the Intel compiler decides to support the string argument, but the gcc found in the default user environment is older and does not support the argument.\n'.format(attr_def)) 661 self.logPrint('*** WE WILL THEREFORE REJECT \'{}\' AND CONTINUE TESTING ***'.format(attr_def)) 662 continue 663 self.addDefine(full_macro_name, attr_def) 664 return 665 666 self.addDefine(full_macro_name, ' ') 667 return 668 669 lang = self.languages.clanguage 670 with self.Language(lang): 671 is_intel = self.setCompilers.isIntel(self.getCompiler(lang=lang), self.log) 672 checkDeprecated('DEPRECATED_FUNCTION', '{} int myfunc(void) {{ return 1; }}', is_intel) 673 checkDeprecated('DEPRECATED_TYPEDEF', 'typedef int my_int {};', is_intel) 674 checkDeprecated('DEPRECATED_ENUM', 'enum E {{ oldval {}, newval }};', is_intel) 675 # I was unable to make a CPP macro that takes the old and new values as separate 676 # arguments and builds the message needed by _Pragma hence the deprecation message is 677 # handled as it is 678 if self.checkCompile('#define TEST _Pragma("GCC warning \"Testing _Pragma\"") value'): 679 self.addDefine('DEPRECATED_MACRO(why)', '_Pragma(why)') 680 else: 681 self.addDefine('DEPRECATED_MACRO(why)', ' ') 682 683 def configureAlign(self): 684 '''Check if __attribute(aligned) is supported''' 685 code = '''\ 686struct mystruct {int myint;} __attribute((aligned(16))); 687char assert_aligned[(sizeof(struct mystruct)==16)*2-1]; 688''' 689 self.pushLanguage(self.languages.clanguage) 690 if self.checkCompile(code): 691 self.addDefine('ATTRIBUTEALIGNED(size)', '__attribute((aligned(size)))') 692 self.addDefine('HAVE_ATTRIBUTEALIGNED', 1) 693 else: 694 self.framework.logPrint('Incorrect attribute(aligned)') 695 self.addDefine('ATTRIBUTEALIGNED(size)', ' ') 696 self.popLanguage() 697 return 698 699 def configureExpect(self): 700 '''Sees if the __builtin_expect directive is supported''' 701 self.pushLanguage(self.languages.clanguage) 702 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 703 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 704 self.popLanguage() 705 706 def configureFunctionName(self): 707 '''Sees if the compiler supports __func__ or a variant.''' 708 def getFunctionName(lang): 709 name = '"unknown"' 710 self.pushLanguage(lang) 711 for fname in ['__func__','__FUNCTION__','__extension__ __func__']: 712 code = "if ("+fname+"[0] != 'm') return 1;" 713 if self.checkCompile('',code) and self.checkLink('',code): 714 name = fname 715 break 716 self.popLanguage() 717 return name 718 langs = [] 719 720 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 721 if hasattr(self.compilers, 'CXX'): 722 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 723 724 def configureIntptrt(self): 725 '''Determine what to use for uintptr_t and intptr_t''' 726 def staticAssertSizeMatchesVoidStar(inc,typename): 727 # The declaration is an error if either array size is negative. 728 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 729 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 730 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 731 732 def generate_uintptr_guesses(): 733 for suff in ('max', '64', '32', '16'): 734 yield '#include <stdint.h>', 'uint{}_t'.format(suff), 'PRIx{}'.format(suff.upper()) 735 yield '#include <stdlib.h>\n#include <string.h>', 'size_t', 'zx' 736 yield '', 'unsigned long long', 'llx' 737 yield '', 'unsigned long', 'lx' 738 yield '', 'unsigned', 'x' 739 740 def generate_intptr_guesses(): 741 for suff in ('max', '64', '32', '16'): 742 yield '#include <stdint.h>', 'int{}_t'.format(suff), 'PRIx{}'.format(suff.upper()) 743 yield '', 'long long', 'llx' 744 yield '', 'long', 'lx' 745 yield '', 'int', 'x' 746 747 def check(default_typename, generator): 748 macro_name = default_typename.upper() 749 with self.Language(self.languages.clanguage): 750 if self.checkCompile( 751 '#include <stdint.h>', 752 'int x; {type_name} i = ({type_name})&x; (void)i'.format(type_name=default_typename) 753 ): 754 typename = default_typename 755 print_format = 'PRIxPTR' 756 else: 757 for include, typename, print_format in generator(): 758 if staticAssertSizeMatchesVoidStar(include, typename): 759 break 760 else: 761 raise RuntimeError('Could not find any {} type matching void*'.format(macro_name)) 762 self.addDefine(macro_name , typename) 763 self.addDefine(macro_name + '_FMT', '\"#\" ' + print_format) 764 return 765 766 check('uintptr_t', generate_uintptr_guesses) 767 check('intptr_t', generate_intptr_guesses) 768 return 769 770 def configureRTLDDefault(self): 771 '''Check for dynamic library feature''' 772 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 773 self.addDefine('HAVE_RTLD_DEFAULT','1') 774 return 775 776 def configureSolaris(self): 777 '''Solaris specific stuff''' 778 if os.path.isdir(os.path.join('/usr','ucblib')): 779 try: 780 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 781 except AttributeError: 782 flag = None 783 if flag is None: 784 self.compilers.LIBS += ' -L/usr/ucblib' 785 else: 786 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 787 return 788 789 def configureDarwin(self): 790 '''Log brew configuration for Apple systems''' 791 try: 792 self.executeShellCommand(['brew', 'config'], log = self.log) 793 self.executeShellCommand(['brew', 'info', 'gcc'], log = self.log) 794 except: 795 pass 796 return 797 798 def configureLinux(self): 799 '''Linux specific stuff''' 800 # TODO: Test for this by mallocing an odd number of floats and checking the address 801 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 802 return 803 804 def configureWin32(self): 805 '''Win32 non-cygwin specific stuff''' 806 kernel32=0 807 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'): 808 self.addDefine('HAVE_WINDOWS_H',1) 809 self.addDefine('HAVE_GETCOMPUTERNAME',1) 810 kernel32=1 811 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'): 812 self.addDefine('HAVE_WINDOWS_H',1) 813 self.addDefine('HAVE_GETCOMPUTERNAME',1) 814 kernel32=1 815 if kernel32: 816 if self.framework.argDB['with-windows-graphics']: 817 self.addDefine('USE_WINDOWS_GRAPHICS',1) 818 if self.checkLink('#include <windows.h>','LoadLibrary(0)'): 819 self.addDefine('HAVE_LOADLIBRARY',1) 820 if self.checkLink('#include <windows.h>','GetProcAddress(0,0)'): 821 self.addDefine('HAVE_GETPROCADDRESS',1) 822 if self.checkLink('#include <windows.h>','FreeLibrary(0)'): 823 self.addDefine('HAVE_FREELIBRARY',1) 824 if self.checkLink('#include <windows.h>','GetLastError()'): 825 self.addDefine('HAVE_GETLASTERROR',1) 826 if self.checkLink('#include <windows.h>','SetLastError(0)'): 827 self.addDefine('HAVE_SETLASTERROR',1) 828 if self.checkLink('#include <windows.h>\n','QueryPerformanceCounter(0);\n'): 829 self.addDefine('USE_MICROSOFT_TIME',1) 830 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'): 831 self.addDefine('HAVE_GET_USER_NAME',1) 832 elif self.libraries.add('advapi32','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'): 833 self.addDefine('HAVE_GET_USER_NAME',1) 834 835 if not self.libraries.add('User32.lib','GetDC',prototype='#include <windows.h>',call='GetDC(0);'): 836 self.libraries.add('user32','GetDC',prototype='#include <windows.h>',call='GetDC(0);') 837 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);'): 838 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);') 839 840 self.types.check('int32_t', 'int') 841 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n(void)u'): 842 self.addTypedef('int', 'uid_t') 843 self.addTypedef('int', 'gid_t') 844 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n(void)a'): 845 self.framework.addDefine('R_OK', '04') 846 self.framework.addDefine('W_OK', '02') 847 self.framework.addDefine('X_OK', '01') 848 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 849 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 850 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 851 if self.checkCompile('#include <windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 852 self.addDefine('HAVE_LARGE_INTEGER_U',1) 853 854 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 855 if self.checkCompile('#include <windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'): 856 self.addDefine('HAVE_O_BINARY',1) 857 858 if self.compilers.CC.find('win32fe') >= 0: 859 self.addDefine('HAVE_WINDOWS_COMPILERS',1) 860 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 861 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 862 self.addDefine('CANNOT_START_DEBUGGER',1) 863 (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.installdir.petscDir, log = self.log) 864 self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"') 865 (petscdir,error,status) = self.executeShellCommand('cygpath -m '+self.installdir.petscDir, log = self.log) 866 self.addMakeMacro('wPETSC_DIR',petscdir) 867 if self.dataFilesPath.datafilespath: 868 (datafilespath,error,status) = self.executeShellCommand('cygpath -m '+self.dataFilesPath.datafilespath, log = self.log) 869 self.addMakeMacro('DATAFILESPATH',datafilespath) 870 871 else: 872 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 873 self.addDefine('DIR_SEPARATOR','\'/\'') 874 self.addDefine('DIR','"'+self.installdir.petscDir+'"') 875 self.addMakeMacro('wPETSC_DIR',self.installdir.petscDir) 876 if self.dataFilesPath.datafilespath: 877 self.addMakeMacro('DATAFILESPATH',self.dataFilesPath.datafilespath) 878 self.addDefine('ARCH','"'+self.installdir.petscArch+'"') 879 return 880 881 def configureCoverage(self, lang, extra_coverage_flags=None, extra_debug_flags=None): 882 """ 883 Check that a compiler accepts code-coverage flags. If the compiler does accept code-coverage flags 884 try to set debugging flags equivalent to -Og. 885 886 Arguments: 887 - lang: the language to check the coverage flag for 888 - extra_coverage_flags: a list of extra flags to use when checking the coverage flags 889 - extra_debug_flags: a list of extra flags to try when setting debug flags 890 891 On success: 892 - defines PETSC_USE_COVERAGE to 1 893 """ 894 def log_print(msg, *args, **kwargs): 895 self.logPrint('checkCoverage: '+str(msg), *args, **kwargs) 896 return 897 898 def quoted(string): 899 return string.join(("'", "'")) 900 901 def make_flag_list(default, extra): 902 ret = [default] 903 if extra is not None: 904 assert isinstance(extra, list) 905 ret.extend(extra) 906 return ret 907 908 log_print('Checking coverage flag for language {}'.format(lang)) 909 if not self.argDB['with-coverage']: 910 log_print('coverage was disabled from command line or default') 911 return 912 913 compiler = self.getCompiler(lang=lang) 914 is_gnuish = self.setCompilers.isGNU(compiler, self.log) or self.setCompilers.isClang(compiler, self.log) 915 916 # if not gnuish and we don't have a set of extra flags, bail 917 if not is_gnuish and extra_coverage_flags is None: 918 log_print('Don\'t know how to add coverage for compiler {}. Only know how to add coverage for gnu-like compilers (either gcc or clang). Skipping it!'.format(quoted(compiler))) 919 return 920 921 coverage_flags = make_flag_list('--coverage', extra_coverage_flags) 922 log_print('Checking set of coverage flags: {}'.format(coverage_flags)) 923 924 found = 0 925 with self.Language(lang): 926 with self.setCompilers.Language(lang): 927 for flag in coverage_flags: 928 if self.setCompilers.checkCompilerFlag(flag) and self.checkLink(): 929 # compilerOnly = False, the linker also needs to see the coverage flag 930 self.setCompilers.insertCompilerFlag(flag, False) 931 found = 1 932 break 933 log_print( 934 'Compiler {} did not accept coverage flag {}'.format(quoted(compiler), quoted(flag)) 935 ) 936 937 if not found: 938 log_print('Compiler {} did not accept ANY coverage flags: {}, bailing!'.format(quoted(compiler), coverage_flags)) 939 return 940 941 if not self.functions.haveFunction('__gcov_dump'): 942 self.functions.checkClassify(['__gcov_dump']) 943 944 # now check if we can override the optimization level. It is only kosher to do so if 945 # the user did not explicitly set the optimization flags (via CFLAGS, CXXFLAGS, 946 # CXXOPTFLAGS, etc). If they have done so, we sternly warn them about their lapse in 947 # judgement 948 with self.Language(lang): 949 compiler_flags = self.getCompilerFlags() 950 951 user_set = 0 952 allowed_opt_flags = re.compile(r'|'.join((r'-O[01g]', r'-g[1-9]*'))) 953 for flagsname in [self.getCompilerFlagsName(lang), self.compilerFlags.getOptionalFlagsName(lang)]: 954 if flagsname in self.argDB: 955 opt_flags = [ 956 f for f in self.compilerFlags.findOptFlags(compiler_flags) if not allowed_opt_flags.match(f) 957 ] 958 if opt_flags: 959 self.logPrintWarning('Coverage requested, but optimization flag(s) {} found in {}. Coverage collection will work, but may be less accurate. Suggest removing the flag and/or using -Og (or equivalent) instead'.format(', '.join(map(quoted, opt_flags)), quoted(flagsname))) 960 user_set = 1 961 break 962 963 if not user_set: 964 debug_flags = make_flag_list('-Og', extra_debug_flags) 965 with self.setCompilers.Language(lang): 966 for flag in debug_flags: 967 try: 968 self.setCompilers.addCompilerFlag(flag) 969 except RuntimeError: 970 continue 971 break 972 973 self.addDefine('USE_COVERAGE', 1) 974 return 975 976 def configureCoverageExecutable(self): 977 """ 978 Check that a code-coverage collecting tool exists and is on PATH. 979 980 On success: 981 - Adds PETSC_COVERAGE_EXEC make macro containing the full path to the coverage tool executable. 982 983 Raises RuntimeError if: 984 - User explicitly requests auto-detection of the coverage tool from command line, and this 985 routine fails to guess the suitable tool name. 986 - The routine fails to find the tool, and --with-coverage is true 987 """ 988 def log_print(msg, *args, **kwargs): 989 self.logPrint('checkCoverage: '+str(msg), *args, **kwargs) 990 return 991 992 def quoted(string): 993 return string.join(("'", "'")) 994 995 required = bool(self.argDB['with-coverage']) 996 arg_opt = self.argDB['with-coverage-exec'] 997 use_default_path = True 998 search_path = '' 999 1000 log_print('{} to find an executable'.format('REQUIRED' if required else 'NOT required')) 1001 if arg_opt in {'auto', 'default-auto', '1'}: 1002 # detect it based on the C language compiler, hopefully this does not clash! 1003 compiler = self.getCompiler(lang=self.setCompilers.languages.clanguage) 1004 log_print('User did not explicitly set coverage exec (got {}), trying to auto-detect based on compiler {}'.format(quoted(arg_opt), quoted(compiler))) 1005 if self.setCompilers.isGNU(compiler, self.log): 1006 exec_names = ['gcov'] 1007 elif self.setCompilers.isClang(compiler, self.log): 1008 exec_names = ['llvm-cov'] 1009 if self.setCompilers.isDarwin(self.log): 1010 # macOS masquerades llvm-cov as just 'gcov', so we add this to the list in case 1011 # bare llvm-cov does not work 1012 exec_names.append('gcov') 1013 elif arg_opt == 'default-auto' and not required: 1014 # default-auto implies the user did not set it via command line! 1015 log_print('Could not auto-detect coverage tool for {}, not a gnuish compiler. Bailing since user did not explicitly set exec on the commandline'.format(quoted(compiler))) 1016 return 1017 else: 1018 # implies 'auto' explicitly set by user, or we were required to find 1019 # something. either way we should error 1020 raise RuntimeError('Could not auto-detect coverage tool for {}, please set coverage tool name explicitly'.format(quoted(compiler))) 1021 else: 1022 log_print('User explicitly set coverage exec as {}'.format(quoted(arg_opt))) 1023 par_dir = os.path.dirname(arg_opt) 1024 if os.path.exists(par_dir): 1025 # arg_opt is path-like, we should only search the provided directory when we go 1026 # looking for the tool 1027 use_default_path = False 1028 search_path = par_dir 1029 exec_names = [arg_opt] 1030 1031 make_macro_name = 'PETSC_COVERAGE_EXEC' 1032 log_print('Checking for coverage tool(s):\n{}'.format('\n'.join('- '+t for t in exec_names))) 1033 found_exec = self.getExecutables( 1034 exec_names, 1035 path=search_path, getFullPath=True, useDefaultPath=use_default_path, resultName=make_macro_name 1036 ) 1037 1038 if found_exec is None: 1039 # didn't find the coverage tool 1040 if required: 1041 raise RuntimeError('Coverage tool(s) {} could not be found. Please provide explicit path to coverage tool'.format(exec_names)) 1042 return 1043 1044 found_exec_name = os.path.basename(found_exec) 1045 if 'llvm-cov' in found_exec_name and 'gcov' not in found_exec_name: 1046 # llvm-cov needs to be called as 'llvm-cov gcov' to work 1047 self.addMakeMacro(make_macro_name, found_exec + ' gcov') 1048 return 1049 1050 def configureStrictPetscErrorCode(self): 1051 """ 1052 Enables or disables strict PetscErrorCode checking. 1053 1054 If --with-strict-petscerrorcode = 1: 1055 - defines PETSC_USE_STRICT_PETSCERRORCODE to 1 1056 1057 Else: 1058 - deletes any prior PETSC_USE_STRICT_PETSCERRORCODE definitions (if they exist) 1059 """ 1060 define_name = 'USE_STRICT_PETSCERRORCODE' 1061 if self.argDB['with-strict-petscerrorcode']: 1062 self.addDefine(define_name, 1) 1063 else: 1064 # in case it was somehow added previously 1065 self.delDefine(define_name) 1066 return 1067 1068#----------------------------------------------------------------------------------------------------- 1069 def configureCygwinBrokenPipe(self): 1070 '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make 1071 http://cygwin.com/ml/cygwin/2013-05/msg00340.html ''' 1072 if config.setCompilers.Configure.isCygwin(self.log): 1073 import platform 1074 import re 1075 r=re.compile("([0-9]+).([0-9]+).([0-9]+)") 1076 m=r.match(platform.release()) 1077 major=int(m.group(1)) 1078 minor=int(m.group(2)) 1079 subminor=int(m.group(3)) 1080 if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)): 1081 self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1') 1082 return 1083 1084#----------------------------------------------------------------------------------------------------- 1085 def configureDefaultArch(self): 1086 conffile = os.path.join('lib','petsc','conf', 'petscvariables') 1087 if self.framework.argDB['with-default-arch']: 1088 fd = open(conffile, 'w') 1089 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 1090 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 1091 fd.write('include '+os.path.join('$(PETSC_DIR)','$(PETSC_ARCH)','lib','petsc','conf','petscvariables')+'\n') 1092 fd.close() 1093 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 1094 elif os.path.isfile(conffile): 1095 try: 1096 os.unlink(conffile) 1097 except: 1098 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 1099 return 1100 1101#----------------------------------------------------------------------------------------------------- 1102 def configureScript(self): 1103 '''Output a script in the conf directory which will reproduce the configuration''' 1104 import nargs 1105 import sys 1106 scriptName = os.path.join(self.arch.arch,'lib','petsc','conf', 'reconfigure-'+self.arch.arch+'.py') 1107 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 1108 if 'with-clean' in args: 1109 del args['with-clean'] 1110 if 'force' in args: 1111 del args['force'] 1112 if 'configModules' in args: 1113 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 1114 del args['configModules'] 1115 if 'optionsModule' in args: 1116 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions': 1117 del args['optionsModule'] 1118 if not 'PETSC_ARCH' in args: 1119 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 1120 f = open(scriptName, 'w') 1121 f.write('#!'+sys.executable+'\n') 1122 f.write('if __name__ == \'__main__\':\n') 1123 f.write(' import sys\n') 1124 f.write(' import os\n') 1125 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 1126 f.write(' import configure\n') 1127 # pretty print repr(args.values()) 1128 f.write(' configure_options = [\n') 1129 for itm in sorted(args.values()): 1130 f.write(' \''+str(itm)+'\',\n') 1131 f.write(' ]\n') 1132 f.write(' configure.petsc_configure(configure_options)\n') 1133 f.close() 1134 try: 1135 os.chmod(scriptName, 0o775) 1136 except OSError as e: 1137 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 1138 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 1139 return 1140 1141 def configureInstall(self): 1142 '''Setup the directories for installation''' 1143 if self.framework.argDB['prefix']: 1144 self.addMakeRule('print_mesg_after_build','', 1145 ['-@echo "========================================="', 1146 '-@echo "Now to install the libraries do:"', 1147 '-@echo "%s${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"' % self.installdir.installSudo, 1148 '-@echo "========================================="']) 1149 else: 1150 self.addMakeRule('print_mesg_after_build','', 1151 ['-@echo "========================================="', 1152 '-@echo "Now to check if the libraries are working do:"', 1153 '-@echo "${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} check"', 1154 '-@echo "========================================="']) 1155 return 1156 1157 def postProcessPackages(self): 1158 postPackages=[] 1159 for i in self.framework.packages: 1160 if hasattr(i,'postProcess'): postPackages.append(i) 1161 if postPackages: 1162 # ctetgen needs petsc conf files. so attempt to create them early 1163 self.framework.dumpConfFiles() 1164 # tacky fix for dependency of Aluimia on Pflotran; requested via petsc-dev Matt provide a correct fix 1165 for i in postPackages: 1166 if i.name.upper() in ['PFLOTRAN']: 1167 i.postProcess() 1168 postPackages.remove(i) 1169 for i in postPackages: i.postProcess() 1170 for i in postPackages: 1171 if i.installedpetsc: 1172 self.installed = 1 1173 break 1174 return 1175 1176 def configure(self): 1177 if 'package-prefix-hash' in self.argDB: 1178 # turn off prefix if it was only used to for installing external packages. 1179 self.framework.argDB['prefix'] = '' 1180 self.dir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch)) 1181 self.installdir.dir = self.dir 1182 self.installdir.petscDir = self.petscdir.dir 1183 self.petscDir = self.petscdir.dir 1184 self.petscArch = self.arch.arch 1185 self.addMakeMacro('PREFIXDIR',self.dir) 1186 self.confDir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch)) 1187 1188 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 1189 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 1190 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 1191 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 1192 if self.framework.argDB['prefix'] and self.framework.argDB['prefix'].find(' ') > -1: 1193 raise RuntimeError('Your --prefix '+self.framework.argDB['prefix']+' has spaces in it; this is not allowed.\n Use a --prefix that does not have spaces in it') 1194 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)): 1195 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 1196 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 1197 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 1198 self.framework.poisonheader = os.path.join(self.arch.arch,'include','petscconf_poison.h') 1199 self.framework.pkgheader = os.path.join(self.arch.arch,'include','petscpkg_version.h') 1200 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscvariables') 1201 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscrules') 1202 if self.libraries.math is None: 1203 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 1204 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 1205 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 1206 self.executeTest(self.configureRTLDDefault) 1207 self.executeTest(self.configurePrefetch) 1208 self.executeTest(self.configureUnused) 1209 self.executeTest(self.configureDeprecated) 1210 self.executeTest(self.configureIsatty) 1211 self.executeTest(self.configureExpect) 1212 self.executeTest(self.configureAlign) 1213 self.executeTest(self.configureFunctionName) 1214 self.executeTest(self.configureIntptrt) 1215 self.executeTest(self.configureSolaris) 1216 self.executeTest(self.configureLinux) 1217 self.executeTest(self.configureDarwin) 1218 self.executeTest(self.configureWin32) 1219 self.executeTest(self.configureCygwinBrokenPipe) 1220 self.executeTest(self.configureDefaultArch) 1221 self.executeTest(self.configureScript) 1222 self.executeTest(self.configureInstall) 1223 self.executeTest(self.configureAtoll) 1224 for LANG in ['C', 'Cxx', 'CUDA', 'HIP', 'SYCL', 'FC']: 1225 compilerName = LANG.upper() if LANG in {'Cxx', 'FC'} else LANG+'C' 1226 if hasattr(self.setCompilers, compilerName): 1227 kwargs = {} 1228 if LANG in {'CUDA'}: 1229 # nvcc preprocesses the base file into a bunch of intermediate files, which are 1230 # then compiled by the host compiler. Why is this a problem? Because the 1231 # generated coverage data is based on these preprocessed source files! So gcov 1232 # tries to read it later, but since its in the tmp directory it cannot. Thus we 1233 # need to keep them around (in a place we know about). 1234 nvcc_tmp_dir = os.path.join(self.petscdir.dir, self.arch.arch, 'nvcc_tmp') 1235 try: 1236 os.mkdir(nvcc_tmp_dir) 1237 except FileExistsError: 1238 pass 1239 kwargs['extra_coverage_flags'] = [ 1240 '-Xcompiler --coverage -Xcompiler -fPIC --keep --keep-dir={}'.format(nvcc_tmp_dir) 1241 ] 1242 if self.kokkos.found: 1243 # yet again the kokkos nvcc_wrapper goes out of its way to be as useless as 1244 # possible. Its default arch (sm_35) is actually too low to compile kokkos, 1245 # for whatever reason this works if you dont use the --keep and --keep-dir 1246 # flags above. 1247 kwargs['extra_coverage_flags'].append('-arch=native') 1248 kwargs['extra_debug_flags'] = ['-Xcompiler -Og'] 1249 self.executeTest(self.configureCoverage, args=[LANG], kargs=kwargs) 1250 self.executeTest(self.configureCoverageExecutable) 1251 self.executeTest(self.configureStrictPetscErrorCode) 1252 1253 self.Dump() 1254 self.dumpConfigInfo() 1255 self.dumpMachineInfo() 1256 self.delGenFiles() 1257 # need to save the current state of BuildSystem so that postProcess() packages can read it in and perhaps run make install 1258 self.framework.storeSubstitutions(self.framework.argDB) 1259 self.framework.argDB['configureCache'] = pickle.dumps(self.framework) 1260 self.framework.argDB.save(force = True) 1261 self.DumpPkgconfig('PETSc.pc') 1262 self.DumpPkgconfig('petsc.pc') 1263 self.DumpModule() 1264 self.postProcessPackages() 1265 self.framework.log.write('================================================================================\n') 1266 self.logClear() 1267 return 1268