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