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