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 return 15 16 def __str2__(self): 17 desc = [' Using GNU make: ' + self.make.make] 18 if not self.installed: 19 desc.append('xxx=========================================================================xxx') 20 desc.append(' Configure stage complete. Now build PETSc libraries with:') 21 desc.append(' %s PETSC_DIR=%s PETSC_ARCH=%s all' % (self.make.make_user, self.petscdir.dir, self.arch.arch)) 22 desc.append('xxx=========================================================================xxx') 23 else: 24 desc.append('xxx=========================================================================xxx') 25 desc.append(' Installation complete. You do not need to run make to compile or install the software') 26 desc.append('xxx=========================================================================xxx') 27 return '\n'.join(desc)+'\n' 28 29 def setupHelp(self, help): 30 import nargs 31 help.addArgument('PETSc', '-prefix=<dir>', nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)')) 32 help.addArgument('PETSc', '-with-prefetch=<bool>', nargs.ArgBool(None, 1,'Enable checking for prefetch instructions')) 33 help.addArgument('Windows','-with-windows-graphics=<bool>', nargs.ArgBool(None, 1,'Enable check for Windows Graphics')) 34 help.addArgument('PETSc', '-with-default-arch=<bool>', nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH')) 35 help.addArgument('PETSc','-with-single-library=<bool>', nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library')) 36 help.addArgument('PETSc','-with-fortran-bindings=<bool>', nargs.ArgBool(None, 1,'Build PETSc fortran bindings in the library and corresponding module files')) 37 help.addArgument('PETSc', '-with-ios=<bool>', nargs.ArgBool(None, 0, 'Build an iPhone/iPad version of PETSc library')) 38 help.addArgument('PETSc', '-with-xsdk-defaults', nargs.ArgBool(None, 0, 'Set the following as defaults for the xSDK standard: --enable-debug=1, --enable-shared=1, --with-precision=double, --with-index-size=32, locate blas/lapack automatically')) 39 help.addArgument('PETSc', '-with-display=<x11display>', nargs.Arg(None, '', 'Specifiy DISPLAY env variable for use with matlab test)')) 40 help.addArgument('PETSc', '-with-package-scripts=<pyscripts>',nargs.ArgFileList(None,None,'Specify configure package scripts for user provided packages')) 41 return 42 43 def registerPythonFile(self,filename,directory): 44 ''' Add a python file to the framework and registers its headerprefix, ... externalpackagedir 45 directory is the directory where the file relative to the BuildSystem or config path in python notation with . ''' 46 (utilityName, ext) = os.path.splitext(filename) 47 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 48 if directory: directory = directory+'.' 49 utilityObj = self.framework.require(directory+utilityName, self) 50 utilityObj.headerPrefix = self.headerPrefix 51 utilityObj.archProvider = self.arch 52 utilityObj.languageProvider = self.languages 53 utilityObj.installDirProvider = self.installdir 54 utilityObj.externalPackagesDirProvider = self.externalpackagesdir 55 utilityObj.precisionProvider = self.scalartypes 56 utilityObj.indexProvider = self.indexTypes 57 setattr(self, utilityName.lower(), utilityObj) 58 return utilityObj 59 return None 60 61 def setupDependencies(self, framework): 62 config.base.Configure.setupDependencies(self, framework) 63 self.programs = framework.require('config.programs', self) 64 self.setCompilers = framework.require('config.setCompilers', self) 65 self.compilers = framework.require('config.compilers', self) 66 self.arch = framework.require('PETSc.options.arch', self.setCompilers) 67 self.petscdir = framework.require('PETSc.options.petscdir', self.arch) 68 self.installdir = framework.require('PETSc.options.installDir', self) 69 self.dataFilesPath = framework.require('PETSc.options.dataFilesPath',self) 70 self.scalartypes = framework.require('PETSc.options.scalarTypes', self) 71 self.indexTypes = framework.require('PETSc.options.indexTypes', self) 72 self.languages = framework.require('PETSc.options.languages', self.setCompilers) 73 self.indexTypes = framework.require('PETSc.options.indexTypes', self.compilers) 74 self.types = framework.require('config.types', self) 75 self.headers = framework.require('config.headers', self) 76 self.functions = framework.require('config.functions', self) 77 self.libraries = framework.require('config.libraries', self) 78 self.atomics = framework.require('config.atomics', self) 79 self.make = framework.require('config.packages.make', self) 80 self.blasLapack = framework.require('config.packages.BlasLapack',self) 81 self.mpi = framework.require('config.packages.MPI', self) 82 self.fortran = framework.require('config.compilersFortran', self) 83 self.externalpackagesdir = framework.require('PETSc.options.externalpackagesdir',self) 84 85 for utility in sorted(os.listdir(os.path.join('config','PETSc','options'))): 86 self.registerPythonFile(utility,'PETSc.options') 87 88 for utility in sorted(os.listdir(os.path.join('config','BuildSystem','config','utilities'))): 89 self.registerPythonFile(utility,'config.utilities') 90 91 for package in sorted(os.listdir(os.path.join('config', 'BuildSystem', 'config', 'packages'))): 92 obj = self.registerPythonFile(package,'config.packages') 93 if obj: 94 obj.archProvider = self.framework.requireModule(obj.archProvider, obj) 95 obj.languageProvider = self.framework.requireModule(obj.languageProvider, obj) 96 obj.installDirProvider = self.framework.requireModule(obj.installDirProvider, obj) 97 obj.externalPackagesDirProvider = self.framework.requireModule(obj.externalPackagesDirProvider, obj) 98 obj.precisionProvider = self.framework.requireModule(obj.precisionProvider, obj) 99 obj.indexProvider = self.framework.requireModule(obj.indexProvider, obj) 100 101 # Force blaslapack and opencl to depend on scalarType so precision is set before BlasLapack is built 102 framework.require('PETSc.options.scalarTypes', self.f2cblaslapack) 103 framework.require('PETSc.options.scalarTypes', self.fblaslapack) 104 framework.require('PETSc.options.scalarTypes', self.blaslapack) 105 framework.require('PETSc.options.scalarTypes', self.opencl) 106 107 self.programs.headerPrefix = self.headerPrefix 108 self.compilers.headerPrefix = self.headerPrefix 109 self.fortran.headerPrefix = self.headerPrefix 110 self.types.headerPrefix = self.headerPrefix 111 self.headers.headerPrefix = self.headerPrefix 112 self.functions.headerPrefix = self.headerPrefix 113 self.libraries.headerPrefix = self.headerPrefix 114 115 # Register user provided package scripts 116 if 'with-package-scripts' in self.framework.argDB: 117 for script in self.framework.argDB['with-package-scripts']: 118 if os.path.splitext(script)[1] != '.py': 119 raise RuntimeError('Only python scripts compatible with configure package script format should be specified! Invalid option -with-package-scripts='+script) 120 self.framework.logPrint('User is registering a new package script: '+script) 121 dname,fname = os.path.split(script) 122 if dname: sys.path.append(dname) 123 self.registerPythonFile(fname,'') 124 125 # test for a variety of basic headers and functions 126 headersC = map(lambda name: name+'.h',['setjmp','dos','fcntl','float','io','malloc','pwd','strings', 127 'unistd','sys/sysinfo','machine/endian','sys/param','sys/procfs','sys/resource', 128 'sys/systeminfo','sys/times','sys/utsname', 129 'sys/socket','sys/wait','netinet/in','netdb','direct','time','Ws2tcpip','sys/types', 130 'WindowsX','float','ieeefp','stdint','pthread','inttypes','immintrin','zmmintrin']) 131 functions = ['access','_access','clock','drand48','getcwd','_getcwd','getdomainname','gethostname', 132 'getwd','memalign','popen','PXFGETARG','rand','getpagesize', 133 'readlink','realpath','usleep','sleep','_sleep', 134 'uname','snprintf','_snprintf','lseek','_lseek','time','fork','stricmp', 135 'strcasecmp','bzero','dlopen','dlsym','dlclose','dlerror', 136 '_set_output_format','_mkdir','socket','gethostbyname','_pipe','fpresetsticky','fpsetsticky'] 137 libraries = [(['fpe'],'handle_sigfpes')] 138 librariessock = [(['socket','nsl'],'socket')] 139 self.headers.headers.extend(headersC) 140 self.functions.functions.extend(functions) 141 self.libraries.libraries.extend(libraries) 142 if not hasattr(self,'socket'): 143 self.libraries.libraries.extend(librariessock) 144 return 145 146 def DumpPkgconfig(self, petsc_pc): 147 ''' Create a pkg-config file ''' 148 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')): 149 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')) 150 with open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig',petsc_pc),'w') as fd: 151 cflags_inc = ['-I${includedir}'] 152 if self.framework.argDB['prefix']: 153 fd.write('prefix='+self.installdir.dir+'\n') 154 else: 155 fd.write('prefix='+os.path.join(self.petscdir.dir, self.arch.arch)+'\n') 156 cflags_inc.append('-I' + os.path.join(self.petscdir.dir, 'include')) 157 fd.write('exec_prefix=${prefix}\n') 158 fd.write('includedir=${prefix}/include\n') 159 fd.write('libdir=${prefix}/lib\n') 160 161 with self.setCompilers.Language('C'): 162 fd.write('ccompiler='+self.setCompilers.getCompiler()+'\n') 163 fd.write('cflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 164 fd.write('cflags_dep='+self.compilers.dependenciesGenerationFlag.get('C','')+'\n') 165 fd.write('ldflag_rpath='+self.setCompilers.CSharedLinkerFlag+'\n') 166 if hasattr(self.compilers, 'CXX'): 167 with self.setCompilers.Language('C++'): 168 fd.write('cxxcompiler='+self.setCompilers.getCompiler()+'\n') 169 fd.write('cxxflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 170 if hasattr(self.compilers, 'FC'): 171 with self.setCompilers.Language('FC'): 172 fd.write('fcompiler='+self.setCompilers.getCompiler()+'\n') 173 fd.write('fflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 174 175 fd.write('\n') 176 fd.write('Name: PETSc\n') 177 fd.write('Description: Library to solve ODEs and algebraic equations\n') 178 fd.write('Version: %s\n' % self.petscdir.version) 179 fd.write('Cflags: ' + ' '.join([self.setCompilers.CPPFLAGS] + cflags_inc) + '\n') 180 fd.write('Libs: '+self.libraries.toStringNoDupes(['-L${libdir}', self.petsclib], with_rpath=False)+'\n') 181 # Remove RPATH flags from library list. User can add them using 182 # pkg-config --variable=ldflag_rpath and pkg-config --libs-only-L 183 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') 184 return 185 186 def DumpModule(self): 187 ''' Create a module file ''' 188 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')): 189 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')) 190 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')): 191 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')) 192 if self.framework.argDB['prefix']: 193 installdir = self.installdir.dir 194 installarch = '' 195 installpath = os.path.join(installdir,'bin') 196 else: 197 installdir = self.petscdir.dir 198 installarch = self.arch.arch 199 installpath = os.path.join(installdir,installarch,'bin')+':'+os.path.join(installdir,'bin') 200 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc',self.petscdir.version),'w') 201 fd.write('''\ 202#%%Module 203 204proc ModulesHelp { } { 205 puts stderr "This module sets the path and environment variables for petsc-%s" 206 puts stderr " see https://www.mcs.anl.gov/petsc/ for more information " 207 puts stderr "" 208} 209module-whatis "PETSc - Portable, Extensible Toolkit for Scientific Computation" 210 211set petsc_dir "%s" 212set petsc_arch "%s" 213 214setenv PETSC_ARCH "$petsc_arch" 215setenv PETSC_DIR "$petsc_dir" 216prepend-path PATH "%s" 217''' % (self.petscdir.version, installdir, installarch, installpath)) 218 fd.close() 219 return 220 221 def Dump(self): 222 ''' Actually put the values into the configuration files ''' 223 # eventually everything between -- should be gone 224 if self.mpi.usingMPIUni: 225 # 226 # Remove any MPI/MPICH include files that may have been put here by previous runs of ./configure 227 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) 228 229 self.logPrintDivider() 230 # Test for compiler-specific macros that need to be defined. 231 if self.setCompilers.isCrayVector('CC', self.log): 232 self.addDefine('HAVE_CRAY_VECTOR','1') 233 234 if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket') and self.headers.haveHeader('netinet/in.h'): 235 self.addDefine('USE_SOCKET_VIEWER','1') 236 if self.checkCompile('#include <sys/socket.h>','setsockopt(0,SOL_SOCKET,SO_REUSEADDR,0,0)'): 237 self.addDefine('HAVE_SO_REUSEADDR','1') 238 239 self.logPrintDivider() 240 self.setCompilers.pushLanguage('C') 241 compiler = self.setCompilers.getCompiler() 242 if compiler.endswith('mpicc') or compiler.endswith('mpiicc'): 243 try: 244 output = self.executeShellCommand(compiler + ' -show', log = self.log)[0] 245 compiler = output.split(' ')[0] 246 self.addDefine('MPICC_SHOW','"'+output.strip().replace('\n','\\\\n')+'"') 247 except: 248 self.addDefine('MPICC_SHOW','"Unavailable"') 249 else: 250 self.addDefine('MPICC_SHOW','"Unavailable"') 251 self.setCompilers.popLanguage() 252#----------------------------------------------------------------------------------------------------- 253 254 # Sometimes we need C compiler, even if built with C++ 255 self.setCompilers.pushLanguage('C') 256 self.addMakeMacro('CC_FLAGS',self.setCompilers.getCompilerFlags()) 257 self.setCompilers.popLanguage() 258 259 # And sometimes we need a C++ compiler even when PETSc is built with C 260 if hasattr(self.compilers, 'CXX'): 261 self.setCompilers.pushLanguage('Cxx') 262 self.addDefine('HAVE_CXX','1') 263 self.addMakeMacro('CXXPP_FLAGS',self.setCompilers.CXXPPFLAGS) 264 self.addMakeMacro('CXX_FLAGS',self.setCompilers.getCompilerFlags()) 265 cxx_linker = self.setCompilers.getLinker() 266 self.addMakeMacro('CXX_LINKER',cxx_linker) 267 self.addMakeMacro('CXX_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 268 self.setCompilers.popLanguage() 269 270 # C preprocessor values 271 self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS) 272 273 # compiler values 274 self.setCompilers.pushLanguage(self.languages.clanguage) 275 self.addMakeMacro('PCC',self.setCompilers.getCompiler()) 276 self.addMakeMacro('PCC_FLAGS',self.setCompilers.getCompilerFlags()) 277 self.addMakeMacro('PCPP_FLAGS',getattr(self.setCompilers,self.languages.clanguage.upper()+'PPFLAGS')) 278 self.addMakeMacro('PFLAGS','${'+self.languages.clanguage.upper()+'FLAGS}') 279 self.addMakeMacro('PPPFLAGS','${'+self.languages.clanguage.upper()+'PPFLAGS}') 280 # ugly work-around for python3 distutils parse_makefile() issue with the above 2 lines 281 self.addMakeMacro('PY_'+self.languages.clanguage.upper()+'FLAGS','') 282 self.addMakeMacro('PY_'+self.languages.clanguage.upper()+'PPFLAGS','') 283 self.setCompilers.popLanguage() 284 # .o or .obj 285 self.addMakeMacro('CC_SUFFIX','o') 286 287 # executable linker values 288 self.setCompilers.pushLanguage(self.languages.clanguage) 289 pcc_linker = self.setCompilers.getLinker() 290 self.addMakeMacro('PCC_LINKER',pcc_linker) 291 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 292 self.setCompilers.popLanguage() 293 # '' for Unix, .exe for Windows 294 self.addMakeMacro('CC_LINKER_SUFFIX','') 295 296 if hasattr(self.compilers, 'FC'): 297 if self.framework.argDB['with-fortran-bindings']: 298 if not self.fortran.fortranIsF90: 299 raise RuntimeError('Error! Fortran compiler "'+self.compilers.FC+'" does not support F90! PETSc fortran bindings require a F90 compiler') 300 self.addDefine('HAVE_FORTRAN','1') 301 self.setCompilers.pushLanguage('FC') 302 # need FPPFLAGS in config/setCompilers 303 self.addMakeMacro('FPP_FLAGS',self.setCompilers.FPPFLAGS) 304 305 # compiler values 306 self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags()) 307 self.setCompilers.popLanguage() 308 # .o or .obj 309 self.addMakeMacro('FC_SUFFIX','o') 310 311 # executable linker values 312 self.setCompilers.pushLanguage('FC') 313 self.addMakeMacro('FC_LINKER',self.setCompilers.getLinker()) 314 self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 315 # apple requires this shared library linker flag on SOME versions of the os 316 if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1: 317 self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ') 318 self.setCompilers.popLanguage() 319 320 # F90 Modules 321 if self.setCompilers.fortranModuleIncludeFlag: 322 self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag) 323 else: # for non-f90 compilers like g77 324 self.addMakeMacro('FC_MODULE_FLAG', '-I') 325 if self.setCompilers.fortranModuleIncludeFlag: 326 self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag) 327 else: 328 self.addMakeMacro('FC','') 329 330 if hasattr(self.compilers, 'CUDAC'): 331 self.setCompilers.pushLanguage('CUDA') 332 self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags()) 333 self.setCompilers.popLanguage() 334 335 if hasattr(self.compilers, 'HIPCC'): 336 self.setCompilers.pushLanguage('HIP') 337 self.addMakeMacro('HIPCC_FLAGS',self.setCompilers.getCompilerFlags()) 338 self.setCompilers.popLanguage() 339 340 if hasattr(self.compilers, 'SYCLCXX'): 341 self.setCompilers.pushLanguage('SYCL') 342 self.addMakeMacro('SYCLCXX_FLAGS',self.setCompilers.getCompilerFlags()) 343 self.setCompilers.popLanguage() 344 345 # shared library linker values 346 self.setCompilers.pushLanguage(self.languages.clanguage) 347 # need to fix BuildSystem to collect these separately 348 self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker()) 349 self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}') 350 self.setCompilers.popLanguage() 351 # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture 352 # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX 353 if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX: 354 self.addMakeMacro('SL_LINKER_SUFFIX', '') 355 self.addDefine('SLSUFFIX','""') 356 else: 357 self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt) 358 self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"') 359 360 self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}') 361 362#----------------------------------------------------------------------------------------------------- 363 364 # CONLY or CPP. We should change the PETSc makefiles to do this better 365 if self.languages.clanguage == 'C': lang = 'CONLY' 366 else: lang = 'CXXONLY' 367 self.addMakeMacro('PETSC_LANGUAGE',lang) 368 369 # real or complex 370 self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype) 371 # double or float 372 self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision) 373 374 if self.framework.argDB['with-batch']: 375 self.addMakeMacro('PETSC_WITH_BATCH','1') 376 377#----------------------------------------------------------------------------------------------------- 378 # print include and lib for makefiles 379 self.logPrintDivider() 380 self.framework.packages.reverse() 381 petscincludes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')] 382 petscincludes_install = [os.path.join(self.installdir.dir, 'include')] if self.framework.argDB['prefix'] else petscincludes 383 includes = [] 384 self.packagelibs = [] 385 for i in self.framework.packages: 386 if not i.required: 387 self.addDefine('HAVE_'+i.PACKAGE.replace('-','_'), 1) # ONLY list package if it is used directly by PETSc (and not only by another package) 388 if not isinstance(i.lib, list): 389 i.lib = [i.lib] 390 if i.linkedbypetsc: self.packagelibs.extend(i.lib) 391 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_LIB', self.libraries.toStringNoDupes(i.lib)) 392 if hasattr(i,'include'): 393 if not isinstance(i.include,list): 394 i.include = [i.include] 395 includes.extend(i.include) 396 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include)) 397 if self.framework.argDB['with-single-library']: 398 self.petsclib = '-lpetsc' 399 else: 400 self.petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys' 401 self.complibs = self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split() 402 self.PETSC_WITH_EXTERNAL_LIB = self.libraries.toStringNoDupes(['-L${PETSC_DIR}/${PETSC_ARCH}/lib', self.petsclib]+self.packagelibs+self.complibs) 403 self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(self.packagelibs+self.complibs) 404 405 self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',self.PETSC_EXTERNAL_LIB_BASIC) 406 allincludes = petscincludes + includes 407 allincludes_install = petscincludes_install + includes 408 self.PETSC_CC_INCLUDES = self.headers.toStringNoDupes(allincludes) 409 self.PETSC_CC_INCLUDES_INSTALL = self.headers.toStringNoDupes(allincludes_install) 410 self.addMakeMacro('PETSC_CC_INCLUDES',self.PETSC_CC_INCLUDES) 411 self.addMakeMacro('PETSC_CC_INCLUDES_INSTALL', self.PETSC_CC_INCLUDES_INSTALL) 412 if hasattr(self.compilers, 'FC'): 413 def modinc(includes): 414 return includes if self.fortran.fortranIsF90 else [] 415 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(allincludes,modinc(allincludes))) 416 self.addMakeMacro('PETSC_FC_INCLUDES_INSTALL',self.headers.toStringNoDupes(allincludes_install,modinc(allincludes_install))) 417 418 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir.dir,'lib')+'"') 419 420 if self.framework.argDB['with-single-library']: 421 # overrides the values set in conf/variables 422 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 423 self.addMakeMacro('SHLIBS','libpetsc') 424 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 425 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 426 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 427 self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc') 428 self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.PETSC_WITH_EXTERNAL_LIB) 429 self.addDefine('USE_SINGLE_LIBRARY', '1') 430 if self.sharedlibraries.useShared: 431 self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 432 self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 433 self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 434 self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 435 self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 436 self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 437 self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 438 self.addMakeMacro('PETSC_TAO_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 439 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 440 self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 441 self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 442 else: 443 self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 444 self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 445 self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}') 446 self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}') 447 self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}') 448 self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}') 449 self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 450 self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}') 451 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 452 self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 453 self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}') 454 455 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 456 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 457 458# add a makefile endtry for display 459 if self.framework.argDB['with-display']: 460 self.addMakeMacro('DISPLAY',self.framework.argDB['with-display']) 461 462 # add a makefile entry for configure options 463 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 464 return 465 466 def dumpConfigInfo(self): 467 import time 468 fd = open(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 469 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"').replace('\\ ','\\\\ ')+'";\n') 470 fd.close() 471 return 472 473 def dumpMachineInfo(self): 474 import platform 475 import datetime 476 import time 477 import script 478 def escape(s): 479 return s.replace('"',r'\"').replace(r'\ ',r'\\ ') # novermin 480 fd = open(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 481 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 482 fd.write('\"-----------------------------------------\\n\"\n') 483 buildhost = platform.node() 484 if os.environ.get('SOURCE_DATE_EPOCH'): 485 buildhost = "reproducible" 486 buildtime = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) 487 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (buildtime, buildhost)) 488 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 489 fd.write('\"Using PETSc directory: %s\\n\"\n' % (escape(self.installdir.petscDir))) 490 fd.write('\"Using PETSc arch: %s\\n\"\n' % (escape(self.installdir.petscArch))) 491 fd.write('\"-----------------------------------------\\n\";\n') 492 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 493 self.setCompilers.pushLanguage(self.languages.clanguage) 494 fd.write('\"Using C compiler: %s %s \\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()))) 495 self.setCompilers.popLanguage() 496 if hasattr(self.compilers, 'FC'): 497 self.setCompilers.pushLanguage('FC') 498 fd.write('\"Using Fortran compiler: %s %s %s\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()), escape(self.setCompilers.CPPFLAGS))) 499 self.setCompilers.popLanguage() 500 fd.write('\"-----------------------------------------\\n\";\n') 501 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 502 fd.write('\"Using include paths: %s\\n\"\n' % (escape(self.PETSC_CC_INCLUDES_INSTALL.replace('${PETSC_DIR}', self.installdir.petscDir)))) 503 fd.write('\"-----------------------------------------\\n\";\n') 504 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 505 self.setCompilers.pushLanguage(self.languages.clanguage) 506 fd.write('\"Using C linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 507 self.setCompilers.popLanguage() 508 if hasattr(self.compilers, 'FC'): 509 self.setCompilers.pushLanguage('FC') 510 fd.write('\"Using Fortran linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 511 self.setCompilers.popLanguage() 512 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))) 513 fd.write('\"-----------------------------------------\\n\";\n') 514 fd.close() 515 return 516 517 def configurePrefetch(self): 518 '''Sees if there are any prefetch functions supported''' 519 if config.setCompilers.Configure.isSolaris(self.log) or self.framework.argDB['with-ios'] or not self.framework.argDB['with-prefetch']: 520 self.addDefine('Prefetch(a,b,c)', ' ') 521 return 522 self.pushLanguage(self.languages.clanguage) 523 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 524 # The Intel Intrinsics manual [1] specifies the prototype 525 # 526 # void _mm_prefetch(char const *a, int sel); 527 # 528 # but other vendors seem to insist on using subtly different 529 # prototypes, including void* for the pointer, and an enum for 530 # sel. These are both reasonable changes, but negatively impact 531 # portability. 532 # 533 # [1] https://software.intel.com/file/6373 534 self.addDefine('HAVE_XMMINTRIN_H', 1) 535 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 536 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 537 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 538 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 539 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 540 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 541 self.addDefine('HAVE_XMMINTRIN_H', 1) 542 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 543 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 544 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 545 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 546 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 547 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 548 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 549 # 550 # The value of rw is a compile-time constant one or zero; one 551 # means that the prefetch is preparing for a write to the memory 552 # address and zero, the default, means that the prefetch is 553 # preparing for a read. The value locality must be a compile-time 554 # constant integer between zero and three. A value of zero means 555 # that the data has no temporal locality, so it need not be left 556 # in the cache after the access. A value of three means that the 557 # data has a high degree of temporal locality and should be left 558 # in all levels of cache possible. Values of one and two mean, 559 # respectively, a low or moderate degree of temporal locality. 560 # 561 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 562 # hints. Using macros for these values in necessary since some 563 # compilers require an enum. 564 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 565 self.addDefine('PREFETCH_HINT_NTA', '0') 566 self.addDefine('PREFETCH_HINT_T0', '3') 567 self.addDefine('PREFETCH_HINT_T1', '2') 568 self.addDefine('PREFETCH_HINT_T2', '1') 569 else: 570 self.addDefine('Prefetch(a,b,c)', ' ') 571 self.popLanguage() 572 573 def configureAtoll(self): 574 '''Checks if atoll exists''' 575 if self.checkLink('#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>','long v = atoll("25")') or self.checkLink ('#include <stdlib.h>','long v = atoll("25")'): 576 self.addDefine('HAVE_ATOLL', '1') 577 578 def configureUnused(self): 579 '''Sees if __attribute((unused)) is supported''' 580 if self.framework.argDB['with-ios']: 581 self.addDefine('UNUSED', ' ') 582 return 583 self.pushLanguage(self.languages.clanguage) 584 if self.checkLink('__attribute((unused)) static int myfunc(__attribute((unused)) void *name){ return 1;}', 'int i = 0;\nint j = myfunc(&i);\ntypedef void* atype;\n__attribute((unused)) atype a;\n'): 585 self.addDefine('UNUSED', '__attribute((unused))') 586 else: 587 self.addDefine('UNUSED', ' ') 588 self.popLanguage() 589 590 def configureIsatty(self): 591 '''Check if the Unix C function isatty() works correctly 592 Actually just assumes it does not work correctly on batch systems''' 593 if not self.framework.argDB['with-batch']: 594 self.addDefine('USE_ISATTY',1) 595 596 def configureDeprecated(self): 597 '''Check if __attribute((deprecated)) is supported''' 598 self.pushLanguage(self.languages.clanguage) 599 ## Recent versions of gcc and clang support __attribute((deprecated("string argument"))), which is very useful, but 600 ## Intel has conspired to make a supremely environment-sensitive compiler. The Intel compiler looks at the gcc 601 ## executable in the environment to determine the language compatibility that it should attempt to emulate. Some 602 ## important Cray installations have built PETSc using the Intel compiler, but with a newer gcc module loaded (e.g., 603 ## 4.7). Thus at PETSc configure time, the Intel compiler decides to support the string argument, but the gcc 604 ## found in the default user environment is older and does not support the argument. If GCC and Intel were cool 605 ## like Clang and supported __has_attribute, we could avoid configure tests entirely, but they don't. And that is 606 ## why we can't have nice things. 607 # 608 # if self.checkCompile("""__attribute((deprecated("Why you shouldn't use myfunc"))) static int myfunc(void) { return 1;}""", ''): 609 # self.addDefine('DEPRECATED_FUNCTION(why)', '__attribute((deprecated(why)))') 610 # self.addDefine('DEPRECATED_TYPEDEF(why)', '__attribute((deprecated(why)))') 611 if self.checkCompile("""__attribute((deprecated)) static int myfunc(void) { return 1;}""", ''): 612 self.addDefine('DEPRECATED_FUNCTION(why)', '__attribute((deprecated))') 613 self.addDefine('DEPRECATED_TYPEDEF(why)', '__attribute((deprecated))') 614 else: 615 self.addDefine('DEPRECATED_FUNCTION(why)', ' ') 616 self.addDefine('DEPRECATED_TYPEDEF(why)', ' ') 617 if self.checkCompile("""enum E {oldval __attribute((deprecated)), newval };""", ''): 618 self.addDefine('DEPRECATED_ENUM(why)', '__attribute((deprecated))') 619 else: 620 self.addDefine('DEPRECATED_ENUM(why)', ' ') 621 # I was unable to make a CPP macro that takes the old and new values as separate arguments and builds the message needed by _Pragma 622 # hence the deprecation message is handled as it is 623 if self.checkCompile('#define TEST _Pragma("GCC warning \"Testing _Pragma\"") value'): 624 self.addDefine('DEPRECATED_MACRO(why)', '_Pragma(why)') 625 else: 626 self.addDefine('DEPRECATED_MACRO(why)', ' ') 627 self.popLanguage() 628 629 def configureAlign(self): 630 '''Check if __attribute(aligned) is supported''' 631 code = '''\ 632struct mystruct {int myint;} __attribute((aligned(16))); 633char assert_aligned[(sizeof(struct mystruct)==16)*2-1]; 634''' 635 self.pushLanguage(self.languages.clanguage) 636 if self.checkCompile(code): 637 self.addDefine('ATTRIBUTEALIGNED(size)', '__attribute((aligned(size)))') 638 self.addDefine('HAVE_ATTRIBUTEALIGNED', 1) 639 else: 640 self.framework.logPrint('Incorrect attribute(aligned)') 641 self.addDefine('ATTRIBUTEALIGNED(size)', ' ') 642 self.popLanguage() 643 return 644 645 def configureExpect(self): 646 '''Sees if the __builtin_expect directive is supported''' 647 self.pushLanguage(self.languages.clanguage) 648 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 649 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 650 self.popLanguage() 651 652 def configureFunctionName(self): 653 '''Sees if the compiler supports __func__ or a variant.''' 654 def getFunctionName(lang): 655 name = '"unknown"' 656 self.pushLanguage(lang) 657 for fname in ['__func__','__FUNCTION__','__extension__ __func__']: 658 code = "if ("+fname+"[0] != 'm') return 1;" 659 if self.checkCompile('',code) and self.checkLink('',code): 660 name = fname 661 break 662 self.popLanguage() 663 return name 664 langs = [] 665 666 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 667 if hasattr(self.compilers, 'CXX'): 668 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 669 670 def configureIntptrt(self): 671 '''Determine what to use for uintptr_t''' 672 def staticAssertSizeMatchesVoidStar(inc,typename): 673 # The declaration is an error if either array size is negative. 674 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 675 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 676 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 677 self.pushLanguage(self.languages.clanguage) 678 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 679 self.addDefine('UINTPTR_T', 'uintptr_t') 680 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 681 self.addDefine('UINTPTR_T', 'unsigned long long') 682 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 683 self.addDefine('UINTPTR_T', 'size_t') 684 elif staticAssertSizeMatchesVoidStar('','unsigned long'): 685 self.addDefine('UINTPTR_T', 'unsigned long') 686 elif staticAssertSizeMatchesVoidStar('','unsigned'): 687 self.addDefine('UINTPTR_T', 'unsigned') 688 else: 689 raise RuntimeError('Could not find any unsigned integer type matching void*') 690 self.popLanguage() 691 692 def configureRTLDDefault(self): 693 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 694 self.addDefine('RTLD_DEFAULT','1') 695 return 696 697 def configureSolaris(self): 698 '''Solaris specific stuff''' 699 if os.path.isdir(os.path.join('/usr','ucblib')): 700 try: 701 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 702 except AttributeError: 703 flag = None 704 if flag is None: 705 self.compilers.LIBS += ' -L/usr/ucblib' 706 else: 707 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 708 return 709 710 def configureLinux(self): 711 '''Linux specific stuff''' 712 # TODO: Test for this by mallocing an odd number of floats and checking the address 713 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 714 return 715 716 def configureWin32(self): 717 '''Win32 non-cygwin specific stuff''' 718 kernel32=0 719 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'): 720 self.addDefine('HAVE_WINDOWS_H',1) 721 self.addDefine('HAVE_GETCOMPUTERNAME',1) 722 kernel32=1 723 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <windows.h>', call='GetComputerName(NULL,NULL);'): 724 self.addDefine('HAVE_WINDOWS_H',1) 725 self.addDefine('HAVE_GETCOMPUTERNAME',1) 726 kernel32=1 727 if kernel32: 728 if self.framework.argDB['with-windows-graphics']: 729 self.addDefine('USE_WINDOWS_GRAPHICS',1) 730 if self.checkLink('#include <windows.h>','LoadLibrary(0)'): 731 self.addDefine('HAVE_LOADLIBRARY',1) 732 if self.checkLink('#include <windows.h>','GetProcAddress(0,0)'): 733 self.addDefine('HAVE_GETPROCADDRESS',1) 734 if self.checkLink('#include <windows.h>','FreeLibrary(0)'): 735 self.addDefine('HAVE_FREELIBRARY',1) 736 if self.checkLink('#include <windows.h>','GetLastError()'): 737 self.addDefine('HAVE_GETLASTERROR',1) 738 if self.checkLink('#include <windows.h>','SetLastError(0)'): 739 self.addDefine('HAVE_SETLASTERROR',1) 740 if self.checkLink('#include <windows.h>\n','QueryPerformanceCounter(0);\n'): 741 self.addDefine('USE_MICROSOFT_TIME',1) 742 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'): 743 self.addDefine('HAVE_GET_USER_NAME',1) 744 elif self.libraries.add('advapi32','GetUserName',prototype='#include <windows.h>', call='GetUserName(NULL,NULL);'): 745 self.addDefine('HAVE_GET_USER_NAME',1) 746 747 if not self.libraries.add('User32.lib','GetDC',prototype='#include <windows.h>',call='GetDC(0);'): 748 self.libraries.add('user32','GetDC',prototype='#include <windows.h>',call='GetDC(0);') 749 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);'): 750 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <windows.h>',call='CreateCompatibleDC(0);') 751 752 self.types.check('int32_t', 'int') 753 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 754 self.addTypedef('int', 'uid_t') 755 self.addTypedef('int', 'gid_t') 756 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 757 self.framework.addDefine('R_OK', '04') 758 self.framework.addDefine('W_OK', '02') 759 self.framework.addDefine('X_OK', '01') 760 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 761 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 762 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 763 if self.checkCompile('#include <windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 764 self.addDefine('HAVE_LARGE_INTEGER_U',1) 765 766 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 767 if self.checkCompile('#include <windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'): 768 self.addDefine('HAVE_O_BINARY',1) 769 770 if self.compilers.CC.find('win32fe') >= 0: 771 self.addDefine('HAVE_WINDOWS_COMPILERS',1) 772 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 773 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 774 self.addDefine('CANNOT_START_DEBUGGER',1) 775 (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.installdir.petscDir, log = self.log) 776 self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"') 777 (petscdir,error,status) = self.executeShellCommand('cygpath -m '+self.installdir.petscDir, log = self.log) 778 self.addMakeMacro('wPETSC_DIR',petscdir) 779 if self.dataFilesPath.datafilespath: 780 (datafilespath,error,status) = self.executeShellCommand('cygpath -m '+self.dataFilesPath.datafilespath, log = self.log) 781 self.addMakeMacro('DATAFILESPATH',datafilespath) 782 783 else: 784 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 785 self.addDefine('DIR_SEPARATOR','\'/\'') 786 self.addDefine('DIR','"'+self.installdir.petscDir+'"') 787 self.addMakeMacro('wPETSC_DIR',self.installdir.petscDir) 788 if self.dataFilesPath.datafilespath: 789 self.addMakeMacro('DATAFILESPATH',self.dataFilesPath.datafilespath) 790 self.addDefine('ARCH','"'+self.installdir.petscArch+'"') 791 return 792 793#----------------------------------------------------------------------------------------------------- 794 def configureCygwinBrokenPipe(self): 795 '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make 796 http://cygwin.com/ml/cygwin/2013-05/msg00340.html ''' 797 if config.setCompilers.Configure.isCygwin(self.log): 798 import platform 799 import re 800 r=re.compile("([0-9]+).([0-9]+).([0-9]+)") 801 m=r.match(platform.release()) 802 major=int(m.group(1)) 803 minor=int(m.group(2)) 804 subminor=int(m.group(3)) 805 if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)): 806 self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1') 807 return 808 809#----------------------------------------------------------------------------------------------------- 810 def configureDefaultArch(self): 811 conffile = os.path.join('lib','petsc','conf', 'petscvariables') 812 if self.framework.argDB['with-default-arch']: 813 fd = open(conffile, 'w') 814 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 815 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 816 fd.write('include '+os.path.join('$(PETSC_DIR)','$(PETSC_ARCH)','lib','petsc','conf','petscvariables')+'\n') 817 fd.close() 818 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 819 elif os.path.isfile(conffile): 820 try: 821 os.unlink(conffile) 822 except: 823 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 824 return 825 826#----------------------------------------------------------------------------------------------------- 827 def configureScript(self): 828 '''Output a script in the conf directory which will reproduce the configuration''' 829 import nargs 830 import sys 831 scriptName = os.path.join(self.arch.arch,'lib','petsc','conf', 'reconfigure-'+self.arch.arch+'.py') 832 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 833 if 'with-clean' in args: 834 del args['with-clean'] 835 if 'force' in args: 836 del args['force'] 837 if 'configModules' in args: 838 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 839 del args['configModules'] 840 if 'optionsModule' in args: 841 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions': 842 del args['optionsModule'] 843 if not 'PETSC_ARCH' in args: 844 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 845 f = open(scriptName, 'w') 846 f.write('#!'+sys.executable+'\n') 847 f.write('if __name__ == \'__main__\':\n') 848 f.write(' import sys\n') 849 f.write(' import os\n') 850 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 851 f.write(' import configure\n') 852 # pretty print repr(args.values()) 853 f.write(' configure_options = [\n') 854 for itm in sorted(args.values()): 855 f.write(' \''+str(itm)+'\',\n') 856 f.write(' ]\n') 857 f.write(' configure.petsc_configure(configure_options)\n') 858 f.close() 859 try: 860 os.chmod(scriptName, 0o775) 861 except OSError as e: 862 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 863 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 864 return 865 866 def configureInstall(self): 867 '''Setup the directories for installation''' 868 if self.framework.argDB['prefix']: 869 self.addMakeRule('print_mesg_after_build','', 870 ['-@echo "========================================="', 871 '-@echo "Now to install the libraries do:"', 872 '-@echo "%s${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"' % self.installdir.installSudo, 873 '-@echo "========================================="']) 874 else: 875 self.addMakeRule('print_mesg_after_build','', 876 ['-@echo "========================================="', 877 '-@echo "Now to check if the libraries are working do:"', 878 '-@echo "${MAKE_USER} PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} check"', 879 '-@echo "========================================="']) 880 return 881 882 def configureGCOV(self): 883 if self.framework.argDB['with-gcov']: 884 self.addDefine('USE_GCOV','1') 885 return 886 887 def postProcessPackages(self): 888 postPackages=[] 889 for i in self.framework.packages: 890 if hasattr(i,'postProcess'): postPackages.append(i) 891 if postPackages: 892 # ctetgen needs petsc conf files. so attempt to create them early 893 self.framework.dumpConfFiles() 894 # tacky fix for dependency of Aluimia on Pflotran; requested via petsc-dev Matt provide a correct fix 895 for i in postPackages: 896 if i.name.upper() in ['PFLOTRAN']: 897 i.postProcess() 898 postPackages.remove(i) 899 for i in postPackages: i.postProcess() 900 for i in postPackages: 901 if i.installedpetsc: 902 self.installed = 1 903 break 904 return 905 906 def configure(self): 907 if 'package-prefix-hash' in self.argDB: 908 # turn off prefix if it was only used to for installing external packages. 909 self.framework.argDB['prefix'] = '' 910 self.dir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch)) 911 self.installdir.dir = self.dir 912 self.installdir.petscDir = self.petscdir.dir 913 self.petscDir = self.petscdir.dir 914 self.petscArch = self.arch.arch 915 self.addMakeMacro('PREFIXDIR',self.dir) 916 self.confDir = os.path.abspath(os.path.join(self.petscdir.dir, self.arch.arch)) 917 918 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 919 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 920 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 921 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 922 if self.framework.argDB['prefix'] and self.framework.argDB['prefix'].find(' ') > -1: 923 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') 924 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)): 925 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 926 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 927 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 928 self.framework.pkgheader = os.path.join(self.arch.arch,'include','petscpkg_version.h') 929 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscvariables') 930 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscrules') 931 if self.libraries.math is None: 932 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 933 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 934 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 935 self.executeTest(self.configureRTLDDefault) 936 self.executeTest(self.configurePrefetch) 937 self.executeTest(self.configureUnused) 938 self.executeTest(self.configureDeprecated) 939 self.executeTest(self.configureIsatty) 940 self.executeTest(self.configureExpect) 941 self.executeTest(self.configureAlign) 942 self.executeTest(self.configureFunctionName) 943 self.executeTest(self.configureIntptrt) 944 self.executeTest(self.configureSolaris) 945 self.executeTest(self.configureLinux) 946 self.executeTest(self.configureWin32) 947 self.executeTest(self.configureCygwinBrokenPipe) 948 self.executeTest(self.configureDefaultArch) 949 self.executeTest(self.configureScript) 950 self.executeTest(self.configureInstall) 951 self.executeTest(self.configureGCOV) 952 self.executeTest(self.configureAtoll) 953 954 self.Dump() 955 self.dumpConfigInfo() 956 self.dumpMachineInfo() 957 # need to save the current state of BuildSystem so that postProcess() packages can read it in and perhaps run make install 958 self.framework.storeSubstitutions(self.framework.argDB) 959 self.framework.argDB['configureCache'] = pickle.dumps(self.framework) 960 self.framework.argDB.save(force = True) 961 self.DumpPkgconfig('PETSc.pc') 962 self.DumpPkgconfig('petsc.pc') 963 self.DumpModule() 964 self.postProcessPackages() 965 self.framework.log.write('================================================================================\n') 966 self.logClear() 967 return 968