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