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