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