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