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