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 else: 476 self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 477 self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 478 self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}') 479 self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}') 480 self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}') 481 self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}') 482 self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 483 self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}') 484 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 485 self.addMakeMacro('PETSC_LIB','${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 + '(string_literal_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(string_literal_why)', 'deprecated') 652 else: 653 attr_bodies = ('(deprecated(string_literal_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_BASE', '{} int myfunc(void) {{ return 1; }}', is_intel) 677 checkDeprecated('DEPRECATED_TYPEDEF_BASE', 'typedef int my_int {};', is_intel) 678 checkDeprecated('DEPRECATED_ENUM_BASE', 'enum E {{ oldval {}, newval }};', is_intel) 679 checkDeprecated('DEPRECATED_OBJECT_BASE', '{} int x;', is_intel) 680 # I was unable to make a CPP macro that takes the old and new values as separate 681 # arguments and builds the message needed by _Pragma hence the deprecation message is 682 # handled as it is 683 if self.checkCompile('#define TEST _Pragma("GCC warning \"Testing _Pragma\"") value'): 684 self.addDefine('DEPRECATED_MACRO_BASE_(why)', '_Pragma(#why)') 685 self.addDefine('DEPRECATED_MACRO_BASE(string_literal_why)', self.substPrefix + '_DEPRECATED_MACRO_BASE_(GCC warning string_literal_why)') 686 else: 687 self.addDefine('DEPRECATED_MACRO_BASE(why)', ' ') 688 689 def configureAlign(self): 690 '''Check if __attribute(aligned) is supported''' 691 code = '''\ 692struct mystruct {int myint;} __attribute((aligned(16))); 693char assert_aligned[(sizeof(struct mystruct)==16)*2-1]; 694''' 695 self.pushLanguage(self.languages.clanguage) 696 if self.checkCompile(code): 697 self.addDefine('ATTRIBUTEALIGNED(size)', '__attribute((aligned(size)))') 698 self.addDefine('HAVE_ATTRIBUTEALIGNED', 1) 699 else: 700 self.framework.logPrint('Incorrect attribute(aligned)') 701 self.addDefine('ATTRIBUTEALIGNED(size)', ' ') 702 self.popLanguage() 703 return 704 705 def configureExpect(self): 706 '''Sees if the __builtin_expect directive is supported''' 707 self.pushLanguage(self.languages.clanguage) 708 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 709 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 710 self.popLanguage() 711 712 def configureFunctionName(self): 713 '''Sees if the compiler supports __func__ or a variant.''' 714 def getFunctionName(lang): 715 name = '"unknown"' 716 self.pushLanguage(lang) 717 for fname in ['__func__','__FUNCTION__','__extension__ __func__']: 718 code = "if ("+fname+"[0] != 'm') return 1;" 719 if self.checkCompile('',code) and self.checkLink('',code): 720 name = fname 721 break 722 self.popLanguage() 723 return name 724 langs = [] 725 726 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 727 if hasattr(self.compilers, 'CXX'): 728 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 729 730 def configureIntptrt(self): 731 '''Determine what to use for uintptr_t and intptr_t''' 732 def staticAssertSizeMatchesVoidStar(inc,typename): 733 # The declaration is an error if either array size is negative. 734 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 735 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 736 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 737 738 def generate_uintptr_guesses(): 739 for suff in ('max', '64', '32', '16'): 740 yield '#include <stdint.h>', 'uint{}_t'.format(suff), 'PRIx{}'.format(suff.upper()) 741 yield '#include <stdlib.h>\n#include <string.h>', 'size_t', 'zx' 742 yield '', 'unsigned long long', 'llx' 743 yield '', 'unsigned long', 'lx' 744 yield '', 'unsigned', 'x' 745 746 def generate_intptr_guesses(): 747 for suff in ('max', '64', '32', '16'): 748 yield '#include <stdint.h>', 'int{}_t'.format(suff), 'PRIx{}'.format(suff.upper()) 749 yield '', 'long long', 'llx' 750 yield '', 'long', 'lx' 751 yield '', 'int', 'x' 752 753 def check(default_typename, generator): 754 macro_name = default_typename.upper() 755 with self.Language(self.languages.clanguage): 756 if self.checkCompile( 757 '#include <stdint.h>', 758 'int x; {type_name} i = ({type_name})&x; (void)i'.format(type_name=default_typename) 759 ): 760 typename = default_typename 761 print_format = 'PRIxPTR' 762 else: 763 for include, typename, print_format in generator(): 764 if staticAssertSizeMatchesVoidStar(include, typename): 765 break 766 else: 767 raise RuntimeError('Could not find any {} type matching void*'.format(macro_name)) 768 self.addDefine(macro_name , typename) 769 self.addDefine(macro_name + '_FMT', '\"#\" ' + print_format) 770 return 771 772 check('uintptr_t', generate_uintptr_guesses) 773 check('intptr_t', generate_intptr_guesses) 774 return 775 776 def configureRTLDDefault(self): 777 '''Check for dynamic library feature''' 778 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 779 self.addDefine('HAVE_RTLD_DEFAULT','1') 780 return 781 782 def configureSolaris(self): 783 '''Solaris specific stuff''' 784 if os.path.isdir(os.path.join('/usr','ucblib')): 785 try: 786 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 787 except AttributeError: 788 flag = None 789 if flag is None: 790 self.compilers.LIBS += ' -L/usr/ucblib' 791 else: 792 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 793 return 794 795 def configureDarwin(self): 796 '''Log brew configuration for Apple systems''' 797 try: 798 self.executeShellCommand(['brew', 'config'], log = self.log) 799 self.executeShellCommand(['brew', 'info', 'gcc'], log = self.log) 800 except: 801 pass 802 return 803 804 def configureLinux(self): 805 '''Linux specific stuff''' 806 # TODO: Test for this by mallocing an odd number of floats and checking the address 807 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 808 return 809 810 def configureWin32(self): 811 '''Win32 non-cygwin specific stuff''' 812 kernel32=0 813 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'): 814 self.addDefine('HAVE_WINDOWS_H',1) 815 self.addDefine('HAVE_GETCOMPUTERNAME',1) 816 kernel32=1 817 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'): 818 self.addDefine('HAVE_WINDOWS_H',1) 819 self.addDefine('HAVE_GETCOMPUTERNAME',1) 820 kernel32=1 821 if kernel32: 822 if self.framework.argDB['with-windows-graphics']: 823 self.addDefine('USE_WINDOWS_GRAPHICS',1) 824 if self.checkLink('#include <windows.h>','LoadLibrary(0)'): 825 self.addDefine('HAVE_LOADLIBRARY',1) 826 if self.checkLink('#include <windows.h>','GetProcAddress(0,0)'): 827 self.addDefine('HAVE_GETPROCADDRESS',1) 828 if self.checkLink('#include <windows.h>','FreeLibrary(0)'): 829 self.addDefine('HAVE_FREELIBRARY',1) 830 if self.checkLink('#include <windows.h>','GetLastError()'): 831 self.addDefine('HAVE_GETLASTERROR',1) 832 if self.checkLink('#include <windows.h>','SetLastError(0)'): 833 self.addDefine('HAVE_SETLASTERROR',1) 834 if self.checkLink('#include <windows.h>\n','QueryPerformanceCounter(0);\n'): 835 self.addDefine('USE_MICROSOFT_TIME',1) 836 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'): 837 self.addDefine('HAVE_GET_USER_NAME',1) 838 elif self.libraries.add('advapi32','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'): 839 self.addDefine('HAVE_GET_USER_NAME',1) 840 841 if not self.libraries.add('User32.lib','GetDC',prototype='#include <windows.h>',call='GetDC(0);'): 842 self.libraries.add('user32','GetDC',prototype='#include <windows.h>',call='GetDC(0);') 843 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);'): 844 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);') 845 846 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n(void)u'): 847 self.addTypedef('int', 'uid_t') 848 self.addTypedef('int', 'gid_t') 849 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n(void)a'): 850 self.framework.addDefine('R_OK', '04') 851 self.framework.addDefine('W_OK', '02') 852 self.framework.addDefine('X_OK', '01') 853 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 854 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 855 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 856 if self.checkCompile('#include <windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 857 self.addDefine('HAVE_LARGE_INTEGER_U',1) 858 859 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 860 if self.checkCompile('#include <windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'): 861 self.addDefine('HAVE_O_BINARY',1) 862 863 if self.compilers.CC.find('win32fe') >= 0: 864 self.addDefine('HAVE_WINDOWS_COMPILERS',1) 865 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 866 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 867 self.addDefine('CANNOT_START_DEBUGGER',1) 868 (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.installdir.petscDir, log = self.log) 869 self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"') 870 (petscdir,error,status) = self.executeShellCommand('cygpath -m '+self.installdir.petscDir, log = self.log) 871 self.addMakeMacro('wPETSC_DIR',petscdir) 872 if self.dataFilesPath.datafilespath: 873 (datafilespath,error,status) = self.executeShellCommand('cygpath -m '+self.dataFilesPath.datafilespath, log = self.log) 874 self.addMakeMacro('DATAFILESPATH',datafilespath) 875 876 else: 877 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 878 self.addDefine('DIR_SEPARATOR','\'/\'') 879 self.addDefine('DIR','"'+self.installdir.petscDir+'"') 880 self.addMakeMacro('wPETSC_DIR',self.installdir.petscDir) 881 if self.dataFilesPath.datafilespath: 882 self.addMakeMacro('DATAFILESPATH',self.dataFilesPath.datafilespath) 883 self.addDefine('ARCH','"'+self.installdir.petscArch+'"') 884 return 885 886 def configureCoverageForLang(self, log_printer_cls, lang, extra_coverage_flags=None, extra_debug_flags=None): 887 """ 888 Check that a compiler accepts code-coverage flags. If the compiler does accept code-coverage flags 889 try to set debugging flags equivalent to -Og. 890 891 Arguments: 892 - lang: the language to check the coverage flag for 893 - extra_coverage_flags: a list of extra flags to use when checking the coverage flags 894 - extra_debug_flags: a list of extra flags to try when setting debug flags 895 896 On success: 897 - defines PETSC_USE_COVERAGE to 1 898 """ 899 log_print = log_printer_cls(self) 900 901 def quoted(string): 902 return string.join(("'", "'")) 903 904 def make_flag_list(default, extra): 905 ret = [default] 906 if extra is not None: 907 assert isinstance(extra, list) 908 ret.extend(extra) 909 return ret 910 911 log_print('Checking coverage flag for language {}'.format(lang)) 912 913 compiler = self.getCompiler(lang=lang) 914 if self.setCompilers.isGNU(compiler, self.log): 915 is_gnuish = True 916 elif self.setCompilers.isClang(compiler, self.log): 917 is_gnuish = True 918 else: 919 is_gnuish = False 920 921 # if not gnuish and we don't have a set of extra flags, bail 922 if not is_gnuish and extra_coverage_flags is None: 923 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))) 924 return 925 926 coverage_flags = make_flag_list('--coverage', extra_coverage_flags) 927 log_print('Checking set of coverage flags: {}'.format(coverage_flags)) 928 929 found = None 930 with self.Language(lang): 931 with self.setCompilers.Language(lang): 932 for flag in coverage_flags: 933 # the linker also needs to see the coverage flag 934 with self.setCompilers.extraCompilerFlags([flag], compilerOnly=False) as skip_flags: 935 if not skip_flags and self.checkRun(): 936 # flag was accepted 937 found = flag 938 break 939 940 log_print( 941 'Compiler {} did not accept coverage flag {}'.format(quoted(compiler), quoted(flag)) 942 ) 943 944 if found is None: 945 log_print( 946 'Compiler {} did not accept ANY coverage flags: {}, bailing!'.format( 947 quoted(compiler), coverage_flags 948 ) 949 ) 950 return 951 952 # must do this exactly here since: 953 # 954 # 1. setCompilers.extraCompilerFlags() will reset the compiler flags on __exit__() 955 # (so cannot do it in the loop) 956 # 2. we need to set the compiler flag while setCompilers.Language() is still in 957 # effect (so cannot do it outside the with statements) 958 self.setCompilers.insertCompilerFlag(flag, False) 959 960 if not self.functions.haveFunction('__gcov_dump'): 961 self.functions.checkClassify(['__gcov_dump']) 962 963 # now check if we can override the optimization level. It is only kosher to do so if 964 # the user did not explicitly set the optimization flags (via CFLAGS, CXXFLAGS, 965 # CXXOPTFLAGS, etc). If they have done so, we sternly warn them about their lapse in 966 # judgement 967 with self.Language(lang): 968 compiler_flags = self.getCompilerFlags() 969 970 user_set = 0 971 allowed_opt_flags = re.compile(r'|'.join((r'-O[01g]', r'-g[1-9]*'))) 972 for flagsname in [self.getCompilerFlagsName(lang), self.compilerFlags.getOptionalFlagsName(lang)]: 973 if flagsname in self.argDB: 974 opt_flags = [ 975 f for f in self.compilerFlags.findOptFlags(compiler_flags) if not allowed_opt_flags.match(f) 976 ] 977 if opt_flags: 978 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))) 979 user_set = 1 980 break 981 982 # disable this for now, the warning should be sufficient. If the user still chooses to 983 # ignore it, then that's on them 984 if 0 and not user_set: 985 debug_flags = make_flag_list('-Og', extra_debug_flags) 986 with self.setCompilers.Language(lang): 987 for flag in debug_flags: 988 try: 989 self.setCompilers.addCompilerFlag(flag) 990 except RuntimeError: 991 continue 992 break 993 994 self.addDefine('USE_COVERAGE', 1) 995 return 996 997 def configureCoverage(self): 998 """ 999 Configure coverage for all available languages. 1000 1001 If user did not request coverage, this function does nothing and returns immediatel. 1002 Therefore the following only apply to the case where the user requested coverage. 1003 1004 On success: 1005 - defines PETSC_USE_COVERAGE to 1 1006 1007 On failure: 1008 - If no compilers supported the coverage flag, throws RuntimeError 1009 - 1010 """ 1011 class LogPrinter: 1012 def __init__(self, cfg): 1013 self.cfg = cfg 1014 try: 1015 import inspect 1016 1017 calling_func_stack = inspect.stack()[1] 1018 if sys.version_info >= (3, 5): 1019 func_name = calling_func_stack.function 1020 else: 1021 func_name = calling_func_stack[3] 1022 except: 1023 func_name = 'Unknown' 1024 self.fmt_str = func_name + '(): {}' 1025 1026 def __call__(self, msg, *args, **kwargs): 1027 return self.cfg.logPrint(self.fmt_str.format(msg), *args, **kwargs) 1028 1029 argdb_flag = 'with-coverage' 1030 log_print = LogPrinter(self) 1031 if not self.argDB[argdb_flag]: 1032 log_print('coverage was disabled from command line or default') 1033 return 1034 1035 tested_langs = [] 1036 for LANG in ['C', 'Cxx', 'CUDA', 'HIP', 'SYCL', 'FC']: 1037 compilerName = LANG.upper() if LANG in {'Cxx', 'FC'} else LANG + 'C' 1038 if hasattr(self.setCompilers, compilerName): 1039 kwargs = {} 1040 if LANG in {'CUDA'}: 1041 # nvcc preprocesses the base file into a bunch of intermediate files, which are 1042 # then compiled by the host compiler. Why is this a problem? Because the 1043 # generated coverage data is based on these preprocessed source files! So gcov 1044 # tries to read it later, but since its in the tmp directory it cannot. Thus we 1045 # need to keep them around (in a place we know about). 1046 nvcc_tmp_dir = os.path.join(self.petscdir.dir, self.arch.arch, 'nvcc_tmp') 1047 try: 1048 os.mkdir(nvcc_tmp_dir) 1049 except FileExistsError: 1050 pass 1051 kwargs['extra_coverage_flags'] = [ 1052 '-Xcompiler --coverage -Xcompiler -fPIC --keep --keep-dir={}'.format(nvcc_tmp_dir) 1053 ] 1054 if self.kokkos.found: 1055 # yet again the kokkos nvcc_wrapper goes out of its way to be as useless as 1056 # possible. Its default arch (sm_35) is actually too low to compile kokkos, 1057 # for whatever reason this works if you dont use the --keep and --keep-dir 1058 # flags above. 1059 kwargs['extra_coverage_flags'].append('-arch=native') 1060 kwargs['extra_debug_flags'] = ['-Xcompiler -Og'] 1061 tested_langs.append(LANG) 1062 self.executeTest(self.configureCoverageForLang, args=[LogPrinter, LANG], kargs=kwargs) 1063 1064 if not self.defines.get('USE_COVERAGE'): 1065 # coverage was requested but no compilers accepted it, this is an error 1066 raise RuntimeError( 1067 'Coverage was requested (--{}={}) but none of the compilers supported it:\n{}\n'.format( 1068 argdb_flag, self.argDB[argdb_flag], 1069 '\n'.join([' - {} ({})'.format(self.getCompiler(lang=lang), lang) for lang in tested_langs]) 1070 ) 1071 ) 1072 1073 return 1074 # Disabled for now, since this does not really work. It solves the problem of 1075 # "undefined reference to __gcov_flush()" but if we add -lgcov we get: 1076 # 1077 # duplicate symbol '___gcov_reset' in: 1078 # /Library/.../libclang_rt.profile_osx.a(GCDAProfiling.c.o) 1079 # /opt/.../libgcov.a(_gcov_reset.o) 1080 # duplicate symbol '___gcov_dump' in: 1081 # /opt/.../libgcov.a(_gcov_dump.o) 1082 # /Library/.../libclang_rt.profile_osx.a(GCDAProfiling.c.o) 1083 # duplicate symbol '___gcov_fork' in: 1084 # /opt/.../libgcov.a(_gcov_fork.o) 1085 # /Library/.../libclang_rt.profile_osx.a(GCDAProfiling.c.o) 1086 # 1087 # I don't know how to solve this. 1088 1089 log_print('Checking if compilers can cross-link disparate coverage libraries') 1090 # At least one of the compilers has coverage enabled. Now need to make sure multiple 1091 # code coverage impls work together, specifically when using clang C/C++ compiler with 1092 # gfortran. 1093 if not hasattr(self.setCompilers, 'FC'): 1094 log_print('No fortran compiler detected. No need to check cross-linking!') 1095 return 1096 1097 c_lang = self.languages.clanguage 1098 if not self.setCompilers.isClang(self.getCompiler(lang=c_lang), self.log): 1099 # must be GCC 1100 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'))) 1101 return 1102 1103 # If we are here we: 1104 # 1. Have both C/C++ compiler and fortran compiler 1105 # 2. The C/C++ compiler is *not* the same as the fortran compiler (unless we start 1106 # using flang) 1107 # 1108 # Now we check if we can cross-link 1109 def can_cross_link(**kwargs): 1110 f_body = " subroutine foo()\n print*,'testing'\n return\n end\n" 1111 c_body = "int main() { }" 1112 1113 return self.compilers.checkCrossLink( 1114 f_body, c_body, language1='FC', language2=c_lang, extralibs=self.compilers.flibs, **kwargs 1115 ) 1116 1117 log_print('Trying to cross-link WITHOUT extra libs') 1118 if can_cross_link(): 1119 log_print('Successfully cross-linked WITHOUT extra libs') 1120 # success, we already can cross-link 1121 return 1122 1123 extra_libs = ['-lgcov'] 1124 log_print('Trying to cross-link with extra libs: {}'.format(extra_libs)) 1125 if can_cross_link(extraObjs=extra_libs): 1126 log_print( 1127 'Successfully cross-linked using extra libs: {}, adding them to LIBS'.format(extra_libs) 1128 ) 1129 self.setCompilers.LIBS += ' ' + ' '.join(extra_libs) 1130 else: 1131 # maybe should be an error? 1132 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)) 1133 return 1134 1135 def configureCoverageExecutable(self): 1136 """ 1137 Check that a code-coverage collecting tool exists and is on PATH. 1138 1139 On success: 1140 - Adds PETSC_COVERAGE_EXEC make macro containing the full path to the coverage tool executable. 1141 1142 Raises RuntimeError if: 1143 - User explicitly requests auto-detection of the coverage tool from command line, and this 1144 routine fails to guess the suitable tool name. 1145 - The routine fails to find the tool, and --with-coverage is true 1146 """ 1147 def log_print(msg, *args, **kwargs): 1148 self.logPrint('checkCoverage: '+str(msg), *args, **kwargs) 1149 return 1150 1151 def quoted(string): 1152 return string.join(("'", "'")) 1153 1154 required = bool(self.argDB['with-coverage']) 1155 arg_opt = self.argDB['with-coverage-exec'] 1156 use_default_path = True 1157 search_path = '' 1158 1159 log_print('{} to find an executable'.format('REQUIRED' if required else 'NOT required')) 1160 if arg_opt in {'auto', 'default-auto', '1'}: 1161 # detect it based on the C language compiler, hopefully this does not clash! 1162 lang = self.setCompilers.languages.clanguage 1163 compiler = self.getCompiler(lang=lang) 1164 log_print('User did not explicitly set coverage exec (got {}), trying to auto-detect based on compiler {}'.format(quoted(arg_opt), quoted(compiler))) 1165 if self.setCompilers.isGNU(compiler, self.log): 1166 compiler_version_re = re.compile(r'[gG][cC\+\-]+[0-9]* \(.+\) (\d+)\.(\d+)\.(\d+)') 1167 exec_names = ['gcov'] 1168 elif self.setCompilers.isClang(compiler, self.log): 1169 compiler_version_re = re.compile(r'clang version (\d+)\.(\d+)\.(\d+)') 1170 exec_names = ['llvm-cov'] 1171 if self.setCompilers.isDarwin(self.log): 1172 # macOS masquerades llvm-cov as just 'gcov', so we add this to the list in case 1173 # bare llvm-cov does not work 1174 exec_names.append('gcov') 1175 elif arg_opt == 'default-auto' and not required: 1176 # default-auto implies the user did not set it via command line! 1177 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))) 1178 return 1179 else: 1180 # implies 'auto' explicitly set by user, or we were required to find 1181 # something. either way we should error 1182 raise RuntimeError('Could not auto-detect coverage tool for {}, please set coverage tool name explicitly'.format(quoted(compiler))) 1183 1184 try: 1185 compiler_version_str = self.compilerFlags.version[lang] 1186 except KeyError: 1187 compiler_version_str = 'Unknown' 1188 1189 log_print('Searching version string {} (for compiler {}) using pattern {}'.format(quoted(compiler_version_str), quoted(compiler), quoted(compiler_version_re.pattern))) 1190 compiler_version = compiler_version_re.search(compiler_version_str) 1191 if compiler_version is not None: 1192 log_print('Found major = {}, minor = {}, patch = {}'.format(compiler_version.group(1), compiler_version.group(2), compiler_version.group(3))) 1193 # form [llvm-cov-14, llvm-cov-14.0, llvm-cov, etc.] 1194 cov_exec_name = exec_names[0] 1195 exec_names = [ 1196 # llvm-cov-14 1197 '{}-{}'.format(cov_exec_name, compiler_version.group(1)), 1198 # llvm-cov-14.0 1199 '{}-{}.{}'.format(cov_exec_name, compiler_version.group(1), compiler_version.group(2)) 1200 ] + exec_names 1201 else: 1202 log_print('User explicitly set coverage exec as {}'.format(quoted(arg_opt))) 1203 par_dir = os.path.dirname(arg_opt) 1204 if os.path.exists(par_dir): 1205 # arg_opt is path-like, we should only search the provided directory when we go 1206 # looking for the tool 1207 use_default_path = False 1208 search_path = par_dir 1209 exec_names = [arg_opt] 1210 1211 make_macro_name = 'PETSC_COVERAGE_EXEC' 1212 log_print('Checking for coverage tool(s):\n{}'.format('\n'.join('- '+t for t in exec_names))) 1213 found_exec = self.getExecutables( 1214 exec_names, 1215 path=search_path, getFullPath=True, useDefaultPath=use_default_path, resultName=make_macro_name 1216 ) 1217 1218 if found_exec is None: 1219 # didn't find the coverage tool 1220 if required: 1221 raise RuntimeError('Coverage tool(s) {} could not be found. Please provide explicit path to coverage tool'.format(exec_names)) 1222 return 1223 1224 found_exec_name = os.path.basename(found_exec) 1225 if 'llvm-cov' in found_exec_name and 'gcov' not in found_exec_name: 1226 # llvm-cov needs to be called as 'llvm-cov gcov' to work 1227 self.addMakeMacro(make_macro_name, found_exec + ' gcov') 1228 return 1229 1230 def configureStrictPetscErrorCode(self): 1231 """ 1232 Enables or disables strict PetscErrorCode checking. 1233 1234 If --with-strict-petscerrorcode = 1: 1235 - defines PETSC_USE_STRICT_PETSCERRORCODE to 1 1236 1237 Else: 1238 - deletes any prior PETSC_USE_STRICT_PETSCERRORCODE definitions (if they exist) 1239 """ 1240 define_name = 'USE_STRICT_PETSCERRORCODE' 1241 if self.argDB['with-strict-petscerrorcode']: 1242 self.addDefine(define_name, 1) 1243 else: 1244 # in case it was somehow added previously 1245 self.delDefine(define_name) 1246 return 1247 1248#----------------------------------------------------------------------------------------------------- 1249 def configureCygwinBrokenPipe(self): 1250 '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make 1251 http://cygwin.com/ml/cygwin/2013-05/msg00340.html ''' 1252 if config.setCompilers.Configure.isCygwin(self.log): 1253 import platform 1254 import re 1255 r=re.compile("([0-9]+).([0-9]+).([0-9]+)") 1256 m=r.match(platform.release()) 1257 major=int(m.group(1)) 1258 minor=int(m.group(2)) 1259 subminor=int(m.group(3)) 1260 if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)): 1261 self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1') 1262 return 1263 1264#----------------------------------------------------------------------------------------------------- 1265 def configureDefaultArch(self): 1266 conffile = os.path.join('lib','petsc','conf', 'petscvariables') 1267 if self.framework.argDB['with-default-arch']: 1268 fd = open(conffile, 'w') 1269 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 1270 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 1271 fd.write('include '+os.path.join('$(PETSC_DIR)','$(PETSC_ARCH)','lib','petsc','conf','petscvariables')+'\n') 1272 fd.close() 1273 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 1274 elif os.path.isfile(conffile): 1275 try: 1276 os.unlink(conffile) 1277 except: 1278 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 1279 return 1280 1281#----------------------------------------------------------------------------------------------------- 1282 def configureScript(self): 1283 '''Output a script in the conf directory which will reproduce the configuration''' 1284 import nargs 1285 import sys 1286 scriptName = os.path.join(self.arch.arch,'lib','petsc','conf', 'reconfigure-'+self.arch.arch+'.py') 1287 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 1288 if 'with-clean' in args: 1289 del args['with-clean'] 1290 if 'force' in args: 1291 del args['force'] 1292 if 'configModules' in args: 1293 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 1294 del args['configModules'] 1295 if 'optionsModule' in args: 1296 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions': 1297 del args['optionsModule'] 1298 if not 'PETSC_ARCH' in args: 1299 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 1300 f = open(scriptName, 'w') 1301 f.write('#!'+sys.executable+'\n') 1302 f.write('if __name__ == \'__main__\':\n') 1303 f.write(' import sys\n') 1304 f.write(' import os\n') 1305 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 1306 f.write(' import configure\n') 1307 # pretty print repr(args.values()) 1308 f.write(' configure_options = [\n') 1309 for itm in sorted(args.values()): 1310 f.write(' \''+str(itm)+'\',\n') 1311 f.write(' ]\n') 1312 f.write(' configure.petsc_configure(configure_options)\n') 1313 f.close() 1314 try: 1315 os.chmod(scriptName, 0o775) 1316 except OSError as e: 1317 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 1318 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 1319 return 1320 1321 def configureInstall(self): 1322 '''Setup the directories for installation''' 1323 if self.framework.argDB['prefix']: 1324 self.addMakeRule('print_mesg_after_build','', 1325 ['-@echo "========================================="', 1326 '-@echo "Now to install the libraries do:"', 1327 '-@echo "%s${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"' % self.installdir.installSudo, 1328 '-@echo "========================================="']) 1329 else: 1330 self.addMakeRule('print_mesg_after_build','', 1331 ['-@echo "========================================="', 1332 '-@echo "Now to check if the libraries are working do:"', 1333 '-@echo "${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} check"', 1334 '-@echo "========================================="']) 1335 return 1336 1337 def postProcessPackages(self): 1338 postPackages=[] 1339 for i in self.framework.packages: 1340 if hasattr(i,'postProcess'): postPackages.append(i) 1341 if postPackages: 1342 # ctetgen needs petsc conf files. so attempt to create them early 1343 self.framework.dumpConfFiles() 1344 # tacky fix for dependency of Aluimia on Pflotran; requested via petsc-dev Matt provide a correct fix 1345 for i in postPackages: 1346 if i.name.upper() in ['PFLOTRAN']: 1347 i.postProcess() 1348 postPackages.remove(i) 1349 for i in postPackages: i.postProcess() 1350 for i in postPackages: 1351 if i.installedpetsc: 1352 self.installed = 1 1353 break 1354 return 1355 1356 def configure(self): 1357 if 'package-prefix-hash' in self.argDB: 1358 # turn off prefix if it was only used to for installing external packages. 1359 self.framework.argDB['prefix'] = '' 1360 self.dir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch)) 1361 self.installdir.dir = self.dir 1362 self.installdir.petscDir = self.petscdir.dir 1363 self.petscDir = self.petscdir.dir 1364 self.petscArch = self.arch.arch 1365 self.addMakeMacro('PREFIXDIR',self.dir) 1366 self.confDir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch)) 1367 1368 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 1369 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 1370 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 1371 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 1372 if self.framework.argDB['prefix'] and self.framework.argDB['prefix'].find(' ') > -1: 1373 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') 1374 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)): 1375 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 1376 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 1377 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 1378 self.framework.poisonheader = os.path.join(self.arch.arch,'include','petscconf_poison.h') 1379 self.framework.pkgheader = os.path.join(self.arch.arch,'include','petscpkg_version.h') 1380 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscvariables') 1381 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscrules') 1382 if self.libraries.math is None: 1383 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 1384 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 1385 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 1386 self.executeTest(self.configureRTLDDefault) 1387 self.executeTest(self.configurePrefetch) 1388 self.executeTest(self.configureUnused) 1389 self.executeTest(self.configureDeprecated) 1390 self.executeTest(self.configureIsatty) 1391 self.executeTest(self.configureExpect) 1392 self.executeTest(self.configureAlign) 1393 self.executeTest(self.configureFunctionName) 1394 self.executeTest(self.configureIntptrt) 1395 self.executeTest(self.configureSolaris) 1396 self.executeTest(self.configureLinux) 1397 self.executeTest(self.configureDarwin) 1398 self.executeTest(self.configureWin32) 1399 self.executeTest(self.configureCygwinBrokenPipe) 1400 self.executeTest(self.configureDefaultArch) 1401 self.executeTest(self.configureScript) 1402 self.executeTest(self.configureInstall) 1403 self.executeTest(self.configureAtoll) 1404 self.executeTest(self.configureCoverage) 1405 self.executeTest(self.configureCoverageExecutable) 1406 self.executeTest(self.configureStrictPetscErrorCode) 1407 1408 self.Dump() 1409 self.dumpConfigInfo() 1410 self.dumpMachineInfo() 1411 self.delGenFiles() 1412 # need to save the current state of BuildSystem so that postProcess() packages can read it in and perhaps run make install 1413 self.framework.storeSubstitutions(self.framework.argDB) 1414 self.framework.argDB['configureCache'] = pickle.dumps(self.framework) 1415 self.framework.argDB.save(force = True) 1416 self.DumpPkgconfig('PETSc.pc') 1417 self.DumpPkgconfig('petsc.pc') 1418 self.DumpModule() 1419 self.postProcessPackages() 1420 self.framework.log.write('================================================================================\n') 1421 self.logClear() 1422 return 1423