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