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