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