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','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 '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 else: 295 self.addMakeMacro('CXX','') 296 297 # C preprocessor values 298 self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS) 299 300 # compiler values 301 self.setCompilers.pushLanguage(self.languages.clanguage) 302 self.addMakeMacro('PCC',self.setCompilers.getCompiler()) 303 # do not use getCompilerFlags() because that automatically includes the preprocessor flags so one ends up with duplication flags in makefile usage 304 if self.languages.clanguage == 'C': 305 self.addMakeMacro('PCC_FLAGS','$(CC_FLAGS)') 306 else: 307 self.addMakeMacro('PCC_FLAGS','$(CXX_FLAGS)') 308 self.setCompilers.popLanguage() 309 # .o or .obj 310 self.addMakeMacro('CC_SUFFIX','o') 311 312 # executable linker values 313 self.setCompilers.pushLanguage(self.languages.clanguage) 314 pcc_linker = self.setCompilers.getLinker() 315 self.addMakeMacro('PCC_LINKER',pcc_linker) 316 # We need to add sycl flags when linking petsc. See more in sycl.py. 317 if hasattr(self.compilers, 'SYCLC'): 318 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()+' '+self.setCompilers.SYCLFLAGS+' '+self.setCompilers.SYCLC_LINKER_FLAGS) 319 else: 320 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 321 self.setCompilers.popLanguage() 322 # '' for Unix, .exe for Windows 323 self.addMakeMacro('CC_LINKER_SUFFIX','') 324 325 if hasattr(self.compilers, 'FC'): 326 if self.framework.argDB['with-fortran-bindings']: 327 if not self.fortran.fortranIsF90: 328 raise RuntimeError('Error! Fortran compiler "'+self.compilers.FC+'" does not support F90! PETSc fortran bindings require a F90 compiler') 329 self.addDefine('HAVE_FORTRAN','1') 330 self.setCompilers.pushLanguage('FC') 331 # need FPPFLAGS in config/setCompilers 332 self.addMakeMacro('FPP_FLAGS',self.setCompilers.FPPFLAGS) 333 334 # compiler values 335 self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags()) 336 self.setCompilers.popLanguage() 337 # .o or .obj 338 self.addMakeMacro('FC_SUFFIX','o') 339 340 # executable linker values 341 self.setCompilers.pushLanguage('FC') 342 self.addMakeMacro('FC_LINKER',self.setCompilers.getLinker()) 343 self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 344 self.setCompilers.popLanguage() 345 346 # F90 Modules 347 if self.setCompilers.fortranModuleIncludeFlag: 348 self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag) 349 else: # for non-f90 compilers like g77 350 self.addMakeMacro('FC_MODULE_FLAG', '-I') 351 if self.setCompilers.fortranModuleIncludeFlag: 352 self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag) 353 else: 354 self.addMakeMacro('FC','') 355 356 if hasattr(self.compilers, 'CUDAC'): 357 self.setCompilers.pushLanguage('CUDA') 358 self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags()) 359 self.addMakeMacro('CUDAPP_FLAGS',self.setCompilers.CUDAPPFLAGS) 360 self.setCompilers.popLanguage() 361 362 if hasattr(self.compilers, 'HIPC'): 363 self.setCompilers.pushLanguage('HIP') 364 self.addMakeMacro('HIPC_FLAGS',self.setCompilers.getCompilerFlags()) 365 self.addMakeMacro('HIPPP_FLAGS',self.setCompilers.HIPPPFLAGS) 366 self.setCompilers.popLanguage() 367 368 if hasattr(self.compilers, 'SYCLC'): 369 self.setCompilers.pushLanguage('SYCL') 370 self.addMakeMacro('SYCLC_FLAGS',self.setCompilers.getCompilerFlags()) 371 self.addMakeMacro('SYCLC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 372 self.addMakeMacro('SYCLPP_FLAGS',self.setCompilers.SYCLPPFLAGS) 373 self.setCompilers.popLanguage() 374 375 # shared library linker values 376 self.setCompilers.pushLanguage(self.languages.clanguage) 377 # need to fix BuildSystem to collect these separately 378 self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker()) 379 self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}') 380 self.setCompilers.popLanguage() 381 # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture 382 # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX 383 if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX: 384 self.addMakeMacro('SL_LINKER_SUFFIX', '') 385 self.addDefine('SLSUFFIX','""') 386 else: 387 self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt) 388 self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"') 389 390 self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}') 391 392#----------------------------------------------------------------------------------------------------- 393 394 # CONLY or CPP. We should change the PETSc makefiles to do this better 395 if self.languages.clanguage == 'C': lang = 'CONLY' 396 else: lang = 'CXXONLY' 397 self.addMakeMacro('PETSC_LANGUAGE',lang) 398 399 # real or complex 400 self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype) 401 # double or float 402 self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision) 403 404 if self.framework.argDB['with-batch']: 405 self.addMakeMacro('PETSC_WITH_BATCH','1') 406 407#----------------------------------------------------------------------------------------------------- 408 # print include and lib for makefiles 409 self.logPrintDivider() 410 self.framework.packages.reverse() 411 petscincludes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')] 412 petscincludes_install = [os.path.join(self.installdir.dir, 'include')] if self.framework.argDB['prefix'] else petscincludes 413 includes = [] 414 self.packagelibs = [] 415 for i in self.framework.packages: 416 if not i.required: 417 if i.devicePackage: 418 self.addDefine('HAVE_DEVICE',1) 419 self.addDefine('HAVE_'+i.PACKAGE.replace('-','_'), 1) # ONLY list package if it is used directly by PETSc (and not only by another package) 420 if not isinstance(i.lib, list): 421 i.lib = [i.lib] 422 if i.linkedbypetsc: self.packagelibs.extend(i.lib) 423 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_LIB', self.libraries.toStringNoDupes(i.lib)) 424 if hasattr(i,'include'): 425 if not isinstance(i.include,list): 426 i.include = [i.include] 427 includes.extend(i.include) 428 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include)) 429 if self.framework.argDB['with-single-library']: 430 self.petsclib = '-lpetsc' 431 else: 432 self.petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys' 433 self.complibs = self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split() 434 self.PETSC_WITH_EXTERNAL_LIB = self.libraries.toStringNoDupes(['-L${PETSC_DIR}/${PETSC_ARCH}/lib', self.petsclib]+self.packagelibs+self.complibs) 435 self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(self.packagelibs+self.complibs) 436 437 self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',self.PETSC_EXTERNAL_LIB_BASIC) 438 allincludes = petscincludes + includes 439 allincludes_install = petscincludes_install + includes 440 self.PETSC_CC_INCLUDES = self.headers.toStringNoDupes(allincludes) 441 self.PETSC_CC_INCLUDES_INSTALL = self.headers.toStringNoDupes(allincludes_install) 442 self.addMakeMacro('PETSC_CC_INCLUDES',self.PETSC_CC_INCLUDES) 443 self.addMakeMacro('PETSC_CC_INCLUDES_INSTALL', self.PETSC_CC_INCLUDES_INSTALL) 444 if hasattr(self.compilers, 'FC'): 445 def modinc(includes): 446 return includes if self.fortran.fortranIsF90 else [] 447 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(allincludes,modinc(allincludes))) 448 self.addMakeMacro('PETSC_FC_INCLUDES_INSTALL',self.headers.toStringNoDupes(allincludes_install,modinc(allincludes_install))) 449 450 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir.dir,'lib')+'"') 451 452 if self.framework.argDB['with-single-library']: 453 # overrides the values set in conf/variables 454 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 455 self.addMakeMacro('SHLIBS','libpetsc') 456 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 457 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 458 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 459 self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc') 460 self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.PETSC_WITH_EXTERNAL_LIB) 461 self.addDefine('USE_SINGLE_LIBRARY', '1') 462 if self.sharedlibraries.useShared: 463 self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 464 self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 465 self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 466 self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 467 self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 468 self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 469 self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 470 self.addMakeMacro('PETSC_TAO_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 471 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 472 self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 473 self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 474 else: 475 self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 476 self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 477 self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}') 478 self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}') 479 self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}') 480 self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}') 481 self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 482 self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}') 483 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 484 self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 485 self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}') 486 487 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 488 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 489 490# add a makefile endtry for display 491 if self.framework.argDB['with-display']: 492 self.addMakeMacro('DISPLAY',self.framework.argDB['with-display']) 493 494 # add a makefile entry for configure options 495 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 496 497 if self.framework.argDB['with-tau-perfstubs']: 498 self.addDefine('HAVE_TAU_PERFSTUBS',1) 499 return 500 501 def dumpConfigInfo(self): 502 import time 503 fd = open(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 504 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"').replace('\\ ','\\\\ ')+'";\n') 505 fd.close() 506 return 507 508 def dumpMachineInfo(self): 509 import platform 510 import datetime 511 import time 512 import script 513 def escape(s): 514 return s.replace('"',r'\"').replace(r'\ ',r'\\ ') # novermin 515 fd = open(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 516 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 517 fd.write('\"-----------------------------------------\\n\"\n') 518 buildhost = platform.node() 519 if os.environ.get('SOURCE_DATE_EPOCH'): 520 buildhost = "reproducible" 521 buildtime = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) 522 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (buildtime, buildhost)) 523 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 524 fd.write('\"Using PETSc directory: %s\\n\"\n' % (escape(self.installdir.petscDir))) 525 fd.write('\"Using PETSc arch: %s\\n\"\n' % (escape(self.installdir.petscArch))) 526 fd.write('\"-----------------------------------------\\n\";\n') 527 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 528 self.setCompilers.pushLanguage(self.languages.clanguage) 529 fd.write('\"Using C compiler: %s %s \\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()))) 530 self.setCompilers.popLanguage() 531 if hasattr(self.compilers, 'FC'): 532 self.setCompilers.pushLanguage('FC') 533 fd.write('\"Using Fortran compiler: %s %s %s\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()), escape(self.setCompilers.CPPFLAGS))) 534 self.setCompilers.popLanguage() 535 fd.write('\"-----------------------------------------\\n\";\n') 536 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 537 fd.write('\"Using include paths: %s\\n\"\n' % (escape(self.PETSC_CC_INCLUDES_INSTALL.replace('${PETSC_DIR}', self.installdir.petscDir)))) 538 fd.write('\"-----------------------------------------\\n\";\n') 539 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 540 self.setCompilers.pushLanguage(self.languages.clanguage) 541 fd.write('\"Using C linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 542 self.setCompilers.popLanguage() 543 if hasattr(self.compilers, 'FC'): 544 self.setCompilers.pushLanguage('FC') 545 fd.write('\"Using Fortran linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 546 self.setCompilers.popLanguage() 547 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))) 548 fd.write('\"-----------------------------------------\\n\";\n') 549 fd.close() 550 return 551 552 def configurePrefetch(self): 553 '''Sees if there are any prefetch functions supported''' 554 if config.setCompilers.Configure.isSolaris(self.log) or self.framework.argDB['with-ios'] or not self.framework.argDB['with-prefetch']: 555 self.addDefine('Prefetch(a,b,c)', ' ') 556 return 557 self.pushLanguage(self.languages.clanguage) 558 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 559 # The Intel Intrinsics manual [1] specifies the prototype 560 # 561 # void _mm_prefetch(char const *a, int sel); 562 # 563 # but other vendors seem to insist on using subtly different 564 # prototypes, including void* for the pointer, and an enum for 565 # sel. These are both reasonable changes, but negatively impact 566 # portability. 567 # 568 # [1] https://software.intel.com/file/6373 569 self.addDefine('HAVE_XMMINTRIN_H', 1) 570 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 571 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 572 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 573 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 574 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 575 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 576 self.addDefine('HAVE_XMMINTRIN_H', 1) 577 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 578 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 579 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 580 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 581 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 582 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 583 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 584 # 585 # The value of rw is a compile-time constant one or zero; one 586 # means that the prefetch is preparing for a write to the memory 587 # address and zero, the default, means that the prefetch is 588 # preparing for a read. The value locality must be a compile-time 589 # constant integer between zero and three. A value of zero means 590 # that the data has no temporal locality, so it need not be left 591 # in the cache after the access. A value of three means that the 592 # data has a high degree of temporal locality and should be left 593 # in all levels of cache possible. Values of one and two mean, 594 # respectively, a low or moderate degree of temporal locality. 595 # 596 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 597 # hints. Using macros for these values in necessary since some 598 # compilers require an enum. 599 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 600 self.addDefine('PREFETCH_HINT_NTA', '0') 601 self.addDefine('PREFETCH_HINT_T0', '3') 602 self.addDefine('PREFETCH_HINT_T1', '2') 603 self.addDefine('PREFETCH_HINT_T2', '1') 604 else: 605 self.addDefine('Prefetch(a,b,c)', ' ') 606 self.popLanguage() 607 608 def delGenFiles(self): 609 '''Delete generated files''' 610 delfile = os.path.join(self.arch.arch,'lib','petsc','conf','files') 611 try: 612 os.unlink(delfile) 613 except: pass 614 615 def configureAtoll(self): 616 '''Checks if atoll exists''' 617 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'): 618 self.addDefine('HAVE_ATOLL', '1') 619 620 def configureUnused(self): 621 '''Sees if __attribute((unused)) is supported''' 622 if self.framework.argDB['with-ios']: 623 self.addDefine('UNUSED', ' ') 624 return 625 self.pushLanguage(self.languages.clanguage) 626 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'): 627 self.addDefine('UNUSED', '__attribute((unused))') 628 else: 629 self.addDefine('UNUSED', ' ') 630 self.popLanguage() 631 632 def configureIsatty(self): 633 '''Check if the Unix C function isatty() works correctly 634 Actually just assumes it does not work correctly on batch systems''' 635 if not self.framework.argDB['with-batch']: 636 self.addDefine('USE_ISATTY',1) 637 638 def configureDeprecated(self): 639 '''Check if __attribute((deprecated)) is supported''' 640 def checkDeprecated(macro_base, src, is_intel): 641 ''' 642 run through the various attribute deprecated combinations and define MACRO_BAS(why) to the result 643 it if it compiles. 644 645 If none of the combos work, defines MACRO_BASE(why) as empty 646 ''' 647 full_macro_name = macro_base + '(why)' 648 for prefix in ('__attribute__', '__attribute','__declspec'): 649 if prefix == '__declspec': 650 # declspec does not have an extra set of brackets around the arguments 651 attr_bodies = ('deprecated(why)', 'deprecated') 652 else: 653 attr_bodies = ('(deprecated(why))', '(deprecated)') 654 655 for attr_body in attr_bodies: 656 attr_def = '{}({})'.format(prefix, attr_body) 657 test_src = '\n'.join(( 658 '#define {} {}'.format(full_macro_name, attr_def), 659 src.format(macro_base + '("asdasdadsasd")') 660 )) 661 if self.checkCompile(test_src, ''): 662 self.logPrint('configureDeprecated: \'{}\' appears to work'.format(attr_def)) 663 if is_intel and '(why)' in attr_body: 664 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)) 665 self.logPrint('*** WE WILL THEREFORE REJECT \'{}\' AND CONTINUE TESTING ***'.format(attr_def)) 666 continue 667 self.addDefine(full_macro_name, attr_def) 668 return 669 670 self.addDefine(full_macro_name, ' ') 671 return 672 673 lang = self.languages.clanguage 674 with self.Language(lang): 675 is_intel = self.setCompilers.isIntel(self.getCompiler(lang=lang), self.log) 676 checkDeprecated('DEPRECATED_FUNCTION', '{} int myfunc(void) {{ return 1; }}', is_intel) 677 checkDeprecated('DEPRECATED_TYPEDEF', 'typedef int my_int {};', is_intel) 678 checkDeprecated('DEPRECATED_ENUM', 'enum E {{ oldval {}, newval }};', is_intel) 679 # I was unable to make a CPP macro that takes the old and new values as separate 680 # arguments and builds the message needed by _Pragma hence the deprecation message is 681 # handled as it is 682 if self.checkCompile('#define TEST _Pragma("GCC warning \"Testing _Pragma\"") value'): 683 self.addDefine('DEPRECATED_MACRO(why)', '_Pragma(why)') 684 else: 685 self.addDefine('DEPRECATED_MACRO(why)', ' ') 686 687 def configureAlign(self): 688 '''Check if __attribute(aligned) is supported''' 689 code = '''\ 690struct mystruct {int myint;} __attribute((aligned(16))); 691char assert_aligned[(sizeof(struct mystruct)==16)*2-1]; 692''' 693 self.pushLanguage(self.languages.clanguage) 694 if self.checkCompile(code): 695 self.addDefine('ATTRIBUTEALIGNED(size)', '__attribute((aligned(size)))') 696 self.addDefine('HAVE_ATTRIBUTEALIGNED', 1) 697 else: 698 self.framework.logPrint('Incorrect attribute(aligned)') 699 self.addDefine('ATTRIBUTEALIGNED(size)', ' ') 700 self.popLanguage() 701 return 702 703 def configureExpect(self): 704 '''Sees if the __builtin_expect directive is supported''' 705 self.pushLanguage(self.languages.clanguage) 706 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 707 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 708 self.popLanguage() 709 710 def configureFunctionName(self): 711 '''Sees if the compiler supports __func__ or a variant.''' 712 def getFunctionName(lang): 713 name = '"unknown"' 714 self.pushLanguage(lang) 715 for fname in ['__func__','__FUNCTION__','__extension__ __func__']: 716 code = "if ("+fname+"[0] != 'm') return 1;" 717 if self.checkCompile('',code) and self.checkLink('',code): 718 name = fname 719 break 720 self.popLanguage() 721 return name 722 langs = [] 723 724 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 725 if hasattr(self.compilers, 'CXX'): 726 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 727 728 def configureIntptrt(self): 729 '''Determine what to use for uintptr_t and intptr_t''' 730 def staticAssertSizeMatchesVoidStar(inc,typename): 731 # The declaration is an error if either array size is negative. 732 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 733 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 734 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 735 736 def generate_uintptr_guesses(): 737 for suff in ('max', '64', '32', '16'): 738 yield '#include <stdint.h>', 'uint{}_t'.format(suff), 'PRIx{}'.format(suff.upper()) 739 yield '#include <stdlib.h>\n#include <string.h>', 'size_t', 'zx' 740 yield '', 'unsigned long long', 'llx' 741 yield '', 'unsigned long', 'lx' 742 yield '', 'unsigned', 'x' 743 744 def generate_intptr_guesses(): 745 for suff in ('max', '64', '32', '16'): 746 yield '#include <stdint.h>', 'int{}_t'.format(suff), 'PRIx{}'.format(suff.upper()) 747 yield '', 'long long', 'llx' 748 yield '', 'long', 'lx' 749 yield '', 'int', 'x' 750 751 def check(default_typename, generator): 752 macro_name = default_typename.upper() 753 with self.Language(self.languages.clanguage): 754 if self.checkCompile( 755 '#include <stdint.h>', 756 'int x; {type_name} i = ({type_name})&x; (void)i'.format(type_name=default_typename) 757 ): 758 typename = default_typename 759 print_format = 'PRIxPTR' 760 else: 761 for include, typename, print_format in generator(): 762 if staticAssertSizeMatchesVoidStar(include, typename): 763 break 764 else: 765 raise RuntimeError('Could not find any {} type matching void*'.format(macro_name)) 766 self.addDefine(macro_name , typename) 767 self.addDefine(macro_name + '_FMT', '\"#\" ' + print_format) 768 return 769 770 check('uintptr_t', generate_uintptr_guesses) 771 check('intptr_t', generate_intptr_guesses) 772 return 773 774 def configureRTLDDefault(self): 775 '''Check for dynamic library feature''' 776 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 777 self.addDefine('HAVE_RTLD_DEFAULT','1') 778 return 779 780 def configureSolaris(self): 781 '''Solaris specific stuff''' 782 if os.path.isdir(os.path.join('/usr','ucblib')): 783 try: 784 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 785 except AttributeError: 786 flag = None 787 if flag is None: 788 self.compilers.LIBS += ' -L/usr/ucblib' 789 else: 790 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 791 return 792 793 def configureDarwin(self): 794 '''Log brew configuration for Apple systems''' 795 try: 796 self.executeShellCommand(['brew', 'config'], log = self.log) 797 self.executeShellCommand(['brew', 'info', 'gcc'], log = self.log) 798 except: 799 pass 800 return 801 802 def configureLinux(self): 803 '''Linux specific stuff''' 804 # TODO: Test for this by mallocing an odd number of floats and checking the address 805 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 806 return 807 808 def configureWin32(self): 809 '''Win32 non-cygwin specific stuff''' 810 kernel32=0 811 if self.libraries.add('Kernel32.lib','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 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'): 816 self.addDefine('HAVE_WINDOWS_H',1) 817 self.addDefine('HAVE_GETCOMPUTERNAME',1) 818 kernel32=1 819 if kernel32: 820 if self.framework.argDB['with-windows-graphics']: 821 self.addDefine('USE_WINDOWS_GRAPHICS',1) 822 if self.checkLink('#include <windows.h>','LoadLibrary(0)'): 823 self.addDefine('HAVE_LOADLIBRARY',1) 824 if self.checkLink('#include <windows.h>','GetProcAddress(0,0)'): 825 self.addDefine('HAVE_GETPROCADDRESS',1) 826 if self.checkLink('#include <windows.h>','FreeLibrary(0)'): 827 self.addDefine('HAVE_FREELIBRARY',1) 828 if self.checkLink('#include <windows.h>','GetLastError()'): 829 self.addDefine('HAVE_GETLASTERROR',1) 830 if self.checkLink('#include <windows.h>','SetLastError(0)'): 831 self.addDefine('HAVE_SETLASTERROR',1) 832 if self.checkLink('#include <windows.h>\n','QueryPerformanceCounter(0);\n'): 833 self.addDefine('USE_MICROSOFT_TIME',1) 834 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'): 835 self.addDefine('HAVE_GET_USER_NAME',1) 836 elif self.libraries.add('advapi32','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'): 837 self.addDefine('HAVE_GET_USER_NAME',1) 838 839 if not self.libraries.add('User32.lib','GetDC',prototype='#include <windows.h>',call='GetDC(0);'): 840 self.libraries.add('user32','GetDC',prototype='#include <windows.h>',call='GetDC(0);') 841 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);'): 842 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);') 843 844 self.types.check('int32_t', 'int') 845 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n(void)u'): 846 self.addTypedef('int', 'uid_t') 847 self.addTypedef('int', 'gid_t') 848 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n(void)a'): 849 self.framework.addDefine('R_OK', '04') 850 self.framework.addDefine('W_OK', '02') 851 self.framework.addDefine('X_OK', '01') 852 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 853 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 854 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 855 if self.checkCompile('#include <windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 856 self.addDefine('HAVE_LARGE_INTEGER_U',1) 857 858 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 859 if self.checkCompile('#include <windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'): 860 self.addDefine('HAVE_O_BINARY',1) 861 862 if self.compilers.CC.find('win32fe') >= 0: 863 self.addDefine('HAVE_WINDOWS_COMPILERS',1) 864 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 865 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 866 self.addDefine('CANNOT_START_DEBUGGER',1) 867 (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.installdir.petscDir, log = self.log) 868 self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"') 869 (petscdir,error,status) = self.executeShellCommand('cygpath -m '+self.installdir.petscDir, log = self.log) 870 self.addMakeMacro('wPETSC_DIR',petscdir) 871 if self.dataFilesPath.datafilespath: 872 (datafilespath,error,status) = self.executeShellCommand('cygpath -m '+self.dataFilesPath.datafilespath, log = self.log) 873 self.addMakeMacro('DATAFILESPATH',datafilespath) 874 875 else: 876 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 877 self.addDefine('DIR_SEPARATOR','\'/\'') 878 self.addDefine('DIR','"'+self.installdir.petscDir+'"') 879 self.addMakeMacro('wPETSC_DIR',self.installdir.petscDir) 880 if self.dataFilesPath.datafilespath: 881 self.addMakeMacro('DATAFILESPATH',self.dataFilesPath.datafilespath) 882 self.addDefine('ARCH','"'+self.installdir.petscArch+'"') 883 return 884 885 def configureCoverageForLang(self, log_printer_cls, lang, extra_coverage_flags=None, extra_debug_flags=None): 886 """ 887 Check that a compiler accepts code-coverage flags. If the compiler does accept code-coverage flags 888 try to set debugging flags equivalent to -Og. 889 890 Arguments: 891 - lang: the language to check the coverage flag for 892 - extra_coverage_flags: a list of extra flags to use when checking the coverage flags 893 - extra_debug_flags: a list of extra flags to try when setting debug flags 894 895 On success: 896 - defines PETSC_USE_COVERAGE to 1 897 """ 898 log_print = log_printer_cls(self) 899 900 def quoted(string): 901 return string.join(("'", "'")) 902 903 def make_flag_list(default, extra): 904 ret = [default] 905 if extra is not None: 906 assert isinstance(extra, list) 907 ret.extend(extra) 908 return ret 909 910 log_print('Checking coverage flag for language {}'.format(lang)) 911 912 compiler = self.getCompiler(lang=lang) 913 if self.setCompilers.isGNU(compiler, self.log): 914 is_gnuish = True 915 elif self.setCompilers.isClang(compiler, self.log): 916 is_gnuish = True 917 else: 918 is_gnuish = False 919 920 # if not gnuish and we don't have a set of extra flags, bail 921 if not is_gnuish and extra_coverage_flags is None: 922 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))) 923 return 924 925 coverage_flags = make_flag_list('--coverage', extra_coverage_flags) 926 log_print('Checking set of coverage flags: {}'.format(coverage_flags)) 927 928 found = None 929 with self.Language(lang): 930 with self.setCompilers.Language(lang): 931 for flag in coverage_flags: 932 # the linker also needs to see the coverage flag 933 with self.setCompilers.extraCompilerFlags([flag], compilerOnly=False) as skip_flags: 934 if not skip_flags and self.checkRun(): 935 # flag was accepted 936 found = flag 937 break 938 939 log_print( 940 'Compiler {} did not accept coverage flag {}'.format(quoted(compiler), quoted(flag)) 941 ) 942 943 if found is None: 944 log_print( 945 'Compiler {} did not accept ANY coverage flags: {}, bailing!'.format( 946 quoted(compiler), coverage_flags 947 ) 948 ) 949 return 950 951 # must do this exactly here since: 952 # 953 # 1. setCompilers.extraCompilerFlags() will reset the compiler flags on __exit__() 954 # (so cannot do it in the loop) 955 # 2. we need to set the compiler flag while setCompilers.Language() is still in 956 # effect (so cannot do it outside the with statements) 957 self.setCompilers.insertCompilerFlag(flag, False) 958 959 if not self.functions.haveFunction('__gcov_dump'): 960 self.functions.checkClassify(['__gcov_dump']) 961 962 # now check if we can override the optimization level. It is only kosher to do so if 963 # the user did not explicitly set the optimization flags (via CFLAGS, CXXFLAGS, 964 # CXXOPTFLAGS, etc). If they have done so, we sternly warn them about their lapse in 965 # judgement 966 with self.Language(lang): 967 compiler_flags = self.getCompilerFlags() 968 969 user_set = 0 970 allowed_opt_flags = re.compile(r'|'.join((r'-O[01g]', r'-g[1-9]*'))) 971 for flagsname in [self.getCompilerFlagsName(lang), self.compilerFlags.getOptionalFlagsName(lang)]: 972 if flagsname in self.argDB: 973 opt_flags = [ 974 f for f in self.compilerFlags.findOptFlags(compiler_flags) if not allowed_opt_flags.match(f) 975 ] 976 if opt_flags: 977 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))) 978 user_set = 1 979 break 980 981 # disable this for now, the warning should be sufficient. If the user still chooses to 982 # ignore it, then that's on them 983 if 0 and not user_set: 984 debug_flags = make_flag_list('-Og', extra_debug_flags) 985 with self.setCompilers.Language(lang): 986 for flag in debug_flags: 987 try: 988 self.setCompilers.addCompilerFlag(flag) 989 except RuntimeError: 990 continue 991 break 992 993 self.addDefine('USE_COVERAGE', 1) 994 return 995 996 def configureCoverage(self): 997 """ 998 Configure coverage for all available languages. 999 1000 If user did not request coverage, this function does nothing and returns immediatel. 1001 Therefore the following only apply to the case where the user requested coverage. 1002 1003 On success: 1004 - defines PETSC_USE_COVERAGE to 1 1005 1006 On failure: 1007 - If no compilers supported the coverage flag, throws RuntimeError 1008 - 1009 """ 1010 class LogPrinter: 1011 def __init__(self, cfg): 1012 self.cfg = cfg 1013 try: 1014 import inspect 1015 1016 calling_func_stack = inspect.stack()[1] 1017 if sys.version_info >= (3, 5): 1018 func_name = calling_func_stack.function 1019 else: 1020 func_name = calling_func_stack[3] 1021 except: 1022 func_name = 'Unknown' 1023 self.fmt_str = func_name + '(): {}' 1024 1025 def __call__(self, msg, *args, **kwargs): 1026 return self.cfg.logPrint(self.fmt_str.format(msg), *args, **kwargs) 1027 1028 argdb_flag = 'with-coverage' 1029 log_print = LogPrinter(self) 1030 if not self.argDB[argdb_flag]: 1031 log_print('coverage was disabled from command line or default') 1032 return 1033 1034 tested_langs = [] 1035 for LANG in ['C', 'Cxx', 'CUDA', 'HIP', 'SYCL', 'FC']: 1036 compilerName = LANG.upper() if LANG in {'Cxx', 'FC'} else LANG + 'C' 1037 if hasattr(self.setCompilers, compilerName): 1038 kwargs = {} 1039 if LANG in {'CUDA'}: 1040 # nvcc preprocesses the base file into a bunch of intermediate files, which are 1041 # then compiled by the host compiler. Why is this a problem? Because the 1042 # generated coverage data is based on these preprocessed source files! So gcov 1043 # tries to read it later, but since its in the tmp directory it cannot. Thus we 1044 # need to keep them around (in a place we know about). 1045 nvcc_tmp_dir = os.path.join(self.petscdir.dir, self.arch.arch, 'nvcc_tmp') 1046 try: 1047 os.mkdir(nvcc_tmp_dir) 1048 except FileExistsError: 1049 pass 1050 kwargs['extra_coverage_flags'] = [ 1051 '-Xcompiler --coverage -Xcompiler -fPIC --keep --keep-dir={}'.format(nvcc_tmp_dir) 1052 ] 1053 if self.kokkos.found: 1054 # yet again the kokkos nvcc_wrapper goes out of its way to be as useless as 1055 # possible. Its default arch (sm_35) is actually too low to compile kokkos, 1056 # for whatever reason this works if you dont use the --keep and --keep-dir 1057 # flags above. 1058 kwargs['extra_coverage_flags'].append('-arch=native') 1059 kwargs['extra_debug_flags'] = ['-Xcompiler -Og'] 1060 tested_langs.append(LANG) 1061 self.executeTest(self.configureCoverageForLang, args=[LogPrinter, LANG], kargs=kwargs) 1062 1063 if not self.defines.get('USE_COVERAGE'): 1064 # coverage was requested but no compilers accepted it, this is an error 1065 raise RuntimeError( 1066 'Coverage was requested (--{}={}) but none of the compilers supported it:\n{}\n'.format( 1067 argdb_flag, self.argDB[argdb_flag], 1068 '\n'.join([' - {} ({})'.format(self.getCompiler(lang=lang), lang) for lang in tested_langs]) 1069 ) 1070 ) 1071 1072 return 1073 # Disabled for now, since this does not really work. It solves the problem of 1074 # "undefined reference to __gcov_flush()" but if we add -lgcov we get: 1075 # 1076 # duplicate symbol '___gcov_reset' in: 1077 # /Library/.../libclang_rt.profile_osx.a(GCDAProfiling.c.o) 1078 # /opt/.../libgcov.a(_gcov_reset.o) 1079 # duplicate symbol '___gcov_dump' in: 1080 # /opt/.../libgcov.a(_gcov_dump.o) 1081 # /Library/.../libclang_rt.profile_osx.a(GCDAProfiling.c.o) 1082 # duplicate symbol '___gcov_fork' in: 1083 # /opt/.../libgcov.a(_gcov_fork.o) 1084 # /Library/.../libclang_rt.profile_osx.a(GCDAProfiling.c.o) 1085 # 1086 # I don't know how to solve this. 1087 1088 log_print('Checking if compilers can cross-link disparate coverage libraries') 1089 # At least one of the compilers has coverage enabled. Now need to make sure multiple 1090 # code coverage impls work together, specifically when using clang C/C++ compiler with 1091 # gfortran. 1092 if not hasattr(self.setCompilers, 'FC'): 1093 log_print('No fortran compiler detected. No need to check cross-linking!') 1094 return 1095 1096 c_lang = self.languages.clanguage 1097 if not self.setCompilers.isClang(self.getCompiler(lang=c_lang), self.log): 1098 # must be GCC 1099 log_print('C-language ({}) compiler is not clang, assuming it is GCC, so cross-linking with FC ({}) assumed to be OK'.format(c_lang, self.getCompiler(lang='FC'))) 1100 return 1101 1102 # If we are here we: 1103 # 1. Have both C/C++ compiler and fortran compiler 1104 # 2. The C/C++ compiler is *not* the same as the fortran compiler (unless we start 1105 # using flang) 1106 # 1107 # Now we check if we can cross-link 1108 def can_cross_link(**kwargs): 1109 f_body = " subroutine foo()\n print*,'testing'\n return\n end\n" 1110 c_body = "int main() { }" 1111 1112 return self.compilers.checkCrossLink( 1113 f_body, c_body, language1='FC', language2=c_lang, extralibs=self.compilers.flibs, **kwargs 1114 ) 1115 1116 log_print('Trying to cross-link WITHOUT extra libs') 1117 if can_cross_link(): 1118 log_print('Successfully cross-linked WITHOUT extra libs') 1119 # success, we already can cross-link 1120 return 1121 1122 extra_libs = ['-lgcov'] 1123 log_print('Trying to cross-link with extra libs: {}'.format(extra_libs)) 1124 if can_cross_link(extraObjs=extra_libs): 1125 log_print( 1126 'Successfully cross-linked using extra libs: {}, adding them to LIBS'.format(extra_libs) 1127 ) 1128 self.setCompilers.LIBS += ' ' + ' '.join(extra_libs) 1129 else: 1130 # maybe should be an error? 1131 self.logPrintWarning("Could not successfully cross-link covered code between {} and FC. Sometimes this is a false positive. Assuming this does eventually end up working when the full link-line is assembled when building PETSc. If you later encounter linker errors about missing __gcov_exit(), __gcov_init(), __llvm_cov_flush() etc. this is why!".format(c_lang)) 1132 return 1133 1134 def configureCoverageExecutable(self): 1135 """ 1136 Check that a code-coverage collecting tool exists and is on PATH. 1137 1138 On success: 1139 - Adds PETSC_COVERAGE_EXEC make macro containing the full path to the coverage tool executable. 1140 1141 Raises RuntimeError if: 1142 - User explicitly requests auto-detection of the coverage tool from command line, and this 1143 routine fails to guess the suitable tool name. 1144 - The routine fails to find the tool, and --with-coverage is true 1145 """ 1146 def log_print(msg, *args, **kwargs): 1147 self.logPrint('checkCoverage: '+str(msg), *args, **kwargs) 1148 return 1149 1150 def quoted(string): 1151 return string.join(("'", "'")) 1152 1153 required = bool(self.argDB['with-coverage']) 1154 arg_opt = self.argDB['with-coverage-exec'] 1155 use_default_path = True 1156 search_path = '' 1157 1158 log_print('{} to find an executable'.format('REQUIRED' if required else 'NOT required')) 1159 if arg_opt in {'auto', 'default-auto', '1'}: 1160 # detect it based on the C language compiler, hopefully this does not clash! 1161 lang = self.setCompilers.languages.clanguage 1162 compiler = self.getCompiler(lang=lang) 1163 log_print('User did not explicitly set coverage exec (got {}), trying to auto-detect based on compiler {}'.format(quoted(arg_opt), quoted(compiler))) 1164 if self.setCompilers.isGNU(compiler, self.log): 1165 compiler_version_re = re.compile(r'[gG][cC\+\-]+[0-9]* \(.+\) (\d+)\.(\d+)\.(\d+)') 1166 exec_names = ['gcov'] 1167 elif self.setCompilers.isClang(compiler, self.log): 1168 compiler_version_re = re.compile(r'clang version (\d+)\.(\d+)\.(\d+)') 1169 exec_names = ['llvm-cov'] 1170 if self.setCompilers.isDarwin(self.log): 1171 # macOS masquerades llvm-cov as just 'gcov', so we add this to the list in case 1172 # bare llvm-cov does not work 1173 exec_names.append('gcov') 1174 elif arg_opt == 'default-auto' and not required: 1175 # default-auto implies the user did not set it via command line! 1176 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))) 1177 return 1178 else: 1179 # implies 'auto' explicitly set by user, or we were required to find 1180 # something. either way we should error 1181 raise RuntimeError('Could not auto-detect coverage tool for {}, please set coverage tool name explicitly'.format(quoted(compiler))) 1182 1183 try: 1184 compiler_version_str = self.compilerFlags.version[lang] 1185 except KeyError: 1186 compiler_version_str = 'Unknown' 1187 1188 log_print('Searching version string {} (for compiler {}) using pattern {}'.format(quoted(compiler_version_str), quoted(compiler), quoted(compiler_version_re.pattern))) 1189 compiler_version = compiler_version_re.search(compiler_version_str) 1190 if compiler_version is not None: 1191 log_print('Found major = {}, minor = {}, patch = {}'.format(compiler_version.group(1), compiler_version.group(2), compiler_version.group(3))) 1192 # form [llvm-cov-14, llvm-cov-14.0, llvm-cov, etc.] 1193 cov_exec_name = exec_names[0] 1194 exec_names = [ 1195 # llvm-cov-14 1196 '{}-{}'.format(cov_exec_name, compiler_version.group(1)), 1197 # llvm-cov-14.0 1198 '{}-{}.{}'.format(cov_exec_name, compiler_version.group(1), compiler_version.group(2)) 1199 ] + exec_names 1200 else: 1201 log_print('User explicitly set coverage exec as {}'.format(quoted(arg_opt))) 1202 par_dir = os.path.dirname(arg_opt) 1203 if os.path.exists(par_dir): 1204 # arg_opt is path-like, we should only search the provided directory when we go 1205 # looking for the tool 1206 use_default_path = False 1207 search_path = par_dir 1208 exec_names = [arg_opt] 1209 1210 make_macro_name = 'PETSC_COVERAGE_EXEC' 1211 log_print('Checking for coverage tool(s):\n{}'.format('\n'.join('- '+t for t in exec_names))) 1212 found_exec = self.getExecutables( 1213 exec_names, 1214 path=search_path, getFullPath=True, useDefaultPath=use_default_path, resultName=make_macro_name 1215 ) 1216 1217 if found_exec is None: 1218 # didn't find the coverage tool 1219 if required: 1220 raise RuntimeError('Coverage tool(s) {} could not be found. Please provide explicit path to coverage tool'.format(exec_names)) 1221 return 1222 1223 found_exec_name = os.path.basename(found_exec) 1224 if 'llvm-cov' in found_exec_name and 'gcov' not in found_exec_name: 1225 # llvm-cov needs to be called as 'llvm-cov gcov' to work 1226 self.addMakeMacro(make_macro_name, found_exec + ' gcov') 1227 return 1228 1229 def configureStrictPetscErrorCode(self): 1230 """ 1231 Enables or disables strict PetscErrorCode checking. 1232 1233 If --with-strict-petscerrorcode = 1: 1234 - defines PETSC_USE_STRICT_PETSCERRORCODE to 1 1235 1236 Else: 1237 - deletes any prior PETSC_USE_STRICT_PETSCERRORCODE definitions (if they exist) 1238 """ 1239 define_name = 'USE_STRICT_PETSCERRORCODE' 1240 if self.argDB['with-strict-petscerrorcode']: 1241 self.addDefine(define_name, 1) 1242 else: 1243 # in case it was somehow added previously 1244 self.delDefine(define_name) 1245 return 1246 1247#----------------------------------------------------------------------------------------------------- 1248 def configureCygwinBrokenPipe(self): 1249 '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make 1250 http://cygwin.com/ml/cygwin/2013-05/msg00340.html ''' 1251 if config.setCompilers.Configure.isCygwin(self.log): 1252 import platform 1253 import re 1254 r=re.compile("([0-9]+).([0-9]+).([0-9]+)") 1255 m=r.match(platform.release()) 1256 major=int(m.group(1)) 1257 minor=int(m.group(2)) 1258 subminor=int(m.group(3)) 1259 if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)): 1260 self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1') 1261 return 1262 1263#----------------------------------------------------------------------------------------------------- 1264 def configureDefaultArch(self): 1265 conffile = os.path.join('lib','petsc','conf', 'petscvariables') 1266 if self.framework.argDB['with-default-arch']: 1267 fd = open(conffile, 'w') 1268 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 1269 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 1270 fd.write('include '+os.path.join('$(PETSC_DIR)','$(PETSC_ARCH)','lib','petsc','conf','petscvariables')+'\n') 1271 fd.close() 1272 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 1273 elif os.path.isfile(conffile): 1274 try: 1275 os.unlink(conffile) 1276 except: 1277 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 1278 return 1279 1280#----------------------------------------------------------------------------------------------------- 1281 def configureScript(self): 1282 '''Output a script in the conf directory which will reproduce the configuration''' 1283 import nargs 1284 import sys 1285 scriptName = os.path.join(self.arch.arch,'lib','petsc','conf', 'reconfigure-'+self.arch.arch+'.py') 1286 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 1287 if 'with-clean' in args: 1288 del args['with-clean'] 1289 if 'force' in args: 1290 del args['force'] 1291 if 'configModules' in args: 1292 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 1293 del args['configModules'] 1294 if 'optionsModule' in args: 1295 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions': 1296 del args['optionsModule'] 1297 if not 'PETSC_ARCH' in args: 1298 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 1299 f = open(scriptName, 'w') 1300 f.write('#!'+sys.executable+'\n') 1301 f.write('if __name__ == \'__main__\':\n') 1302 f.write(' import sys\n') 1303 f.write(' import os\n') 1304 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 1305 f.write(' import configure\n') 1306 # pretty print repr(args.values()) 1307 f.write(' configure_options = [\n') 1308 for itm in sorted(args.values()): 1309 f.write(' \''+str(itm)+'\',\n') 1310 f.write(' ]\n') 1311 f.write(' configure.petsc_configure(configure_options)\n') 1312 f.close() 1313 try: 1314 os.chmod(scriptName, 0o775) 1315 except OSError as e: 1316 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 1317 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 1318 return 1319 1320 def configureInstall(self): 1321 '''Setup the directories for installation''' 1322 if self.framework.argDB['prefix']: 1323 self.addMakeRule('print_mesg_after_build','', 1324 ['-@echo "========================================="', 1325 '-@echo "Now to install the libraries do:"', 1326 '-@echo "%s${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"' % self.installdir.installSudo, 1327 '-@echo "========================================="']) 1328 else: 1329 self.addMakeRule('print_mesg_after_build','', 1330 ['-@echo "========================================="', 1331 '-@echo "Now to check if the libraries are working do:"', 1332 '-@echo "${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} check"', 1333 '-@echo "========================================="']) 1334 return 1335 1336 def postProcessPackages(self): 1337 postPackages=[] 1338 for i in self.framework.packages: 1339 if hasattr(i,'postProcess'): postPackages.append(i) 1340 if postPackages: 1341 # ctetgen needs petsc conf files. so attempt to create them early 1342 self.framework.dumpConfFiles() 1343 # tacky fix for dependency of Aluimia on Pflotran; requested via petsc-dev Matt provide a correct fix 1344 for i in postPackages: 1345 if i.name.upper() in ['PFLOTRAN']: 1346 i.postProcess() 1347 postPackages.remove(i) 1348 for i in postPackages: i.postProcess() 1349 for i in postPackages: 1350 if i.installedpetsc: 1351 self.installed = 1 1352 break 1353 return 1354 1355 def configure(self): 1356 if 'package-prefix-hash' in self.argDB: 1357 # turn off prefix if it was only used to for installing external packages. 1358 self.framework.argDB['prefix'] = '' 1359 self.dir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch)) 1360 self.installdir.dir = self.dir 1361 self.installdir.petscDir = self.petscdir.dir 1362 self.petscDir = self.petscdir.dir 1363 self.petscArch = self.arch.arch 1364 self.addMakeMacro('PREFIXDIR',self.dir) 1365 self.confDir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch)) 1366 1367 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 1368 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 1369 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 1370 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 1371 if self.framework.argDB['prefix'] and self.framework.argDB['prefix'].find(' ') > -1: 1372 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') 1373 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)): 1374 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 1375 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 1376 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 1377 self.framework.poisonheader = os.path.join(self.arch.arch,'include','petscconf_poison.h') 1378 self.framework.pkgheader = os.path.join(self.arch.arch,'include','petscpkg_version.h') 1379 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscvariables') 1380 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscrules') 1381 if self.libraries.math is None: 1382 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 1383 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 1384 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 1385 self.executeTest(self.configureRTLDDefault) 1386 self.executeTest(self.configurePrefetch) 1387 self.executeTest(self.configureUnused) 1388 self.executeTest(self.configureDeprecated) 1389 self.executeTest(self.configureIsatty) 1390 self.executeTest(self.configureExpect) 1391 self.executeTest(self.configureAlign) 1392 self.executeTest(self.configureFunctionName) 1393 self.executeTest(self.configureIntptrt) 1394 self.executeTest(self.configureSolaris) 1395 self.executeTest(self.configureLinux) 1396 self.executeTest(self.configureDarwin) 1397 self.executeTest(self.configureWin32) 1398 self.executeTest(self.configureCygwinBrokenPipe) 1399 self.executeTest(self.configureDefaultArch) 1400 self.executeTest(self.configureScript) 1401 self.executeTest(self.configureInstall) 1402 self.executeTest(self.configureAtoll) 1403 self.executeTest(self.configureCoverage) 1404 self.executeTest(self.configureCoverageExecutable) 1405 self.executeTest(self.configureStrictPetscErrorCode) 1406 1407 self.Dump() 1408 self.dumpConfigInfo() 1409 self.dumpMachineInfo() 1410 self.delGenFiles() 1411 # need to save the current state of BuildSystem so that postProcess() packages can read it in and perhaps run make install 1412 self.framework.storeSubstitutions(self.framework.argDB) 1413 self.framework.argDB['configureCache'] = pickle.dumps(self.framework) 1414 self.framework.argDB.save(force = True) 1415 self.DumpPkgconfig('PETSc.pc') 1416 self.DumpPkgconfig('petsc.pc') 1417 self.DumpModule() 1418 self.postProcessPackages() 1419 self.framework.log.write('================================================================================\n') 1420 self.logClear() 1421 return 1422