1import config.base 2 3import os 4import sys 5import re 6import cPickle 7import string 8 9# The sorted() builtin is not available with python-2.3 10try: sorted 11except NameError: 12 def sorted(lst): 13 lst.sort() 14 return lst 15 16class Configure(config.base.Configure): 17 def __init__(self, framework): 18 config.base.Configure.__init__(self, framework) 19 self.headerPrefix = 'PETSC' 20 self.substPrefix = 'PETSC' 21 self.installed = 0 # 1 indicates that Configure itself has already compiled and installed PETSc 22 return 23 24 def __str2__(self): 25 desc = [] 26 if not self.installed: 27 desc.append('xxx=========================================================================xxx') 28 if self.make.getMakeMacro('MAKE_IS_GNUMAKE'): 29 build_type = 'gnumake build' 30 elif self.getMakeMacro('PETSC_BUILD_USING_CMAKE'): 31 build_type = 'cmake build' 32 else: 33 build_type = 'legacy build' 34 desc.append(' Configure stage complete. Now build PETSc libraries with (%s):' % build_type) 35 desc.append(' make PETSC_DIR='+self.petscdir.dir+' PETSC_ARCH='+self.arch.arch+' all') 36 desc.append('xxx=========================================================================xxx') 37 else: 38 desc.append('xxx=========================================================================xxx') 39 desc.append(' Installation complete. You do not need to run make to compile or install the software') 40 desc.append('xxx=========================================================================xxx') 41 return '\n'.join(desc)+'\n' 42 43 def setupHelp(self, help): 44 import nargs 45 help.addArgument('PETSc', '-prefix=<dir>', nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)')) 46 help.addArgument('PETSc', '-with-prefetch=<bool>', nargs.ArgBool(None, 1,'Enable checking for prefetch instructions')) 47 help.addArgument('Windows','-with-windows-graphics=<bool>', nargs.ArgBool(None, 1,'Enable check for Windows Graphics')) 48 help.addArgument('PETSc', '-with-default-arch=<bool>', nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH')) 49 help.addArgument('PETSc','-with-single-library=<bool>', nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library')) 50 help.addArgument('PETSc','-with-fortran-bindings=<bool>', nargs.ArgBool(None, 1,'Build PETSc fortran bindings in the library and corresponding module files')) 51 help.addArgument('PETSc', '-with-ios=<bool>', nargs.ArgBool(None, 0, 'Build an iPhone/iPad version of PETSc library')) 52 help.addArgument('PETSc', '-with-xsdk-defaults', nargs.ArgBool(None, 0, 'Set the following as defaults for the xSDK standard: --enable-debug=1, --enable-shared=1, --with-precision=double, --with-index-size=32, locate blas/lapack automatically')) 53 help.addArgument('PETSc', '-known-has-attribute-aligned=<bool>',nargs.ArgBool(None, None, 'Indicates __attribute((aligned(16)) directive works (the usual test will be skipped)')) 54 help.addArgument('PETSc', '-with-display=<x11display>', nargs.Arg(None, '', 'Specifiy DISPLAY env variable for use with matlab test)')) 55 return 56 57 def registerPythonFile(self,filename,directory): 58 ''' Add a python file to the framework and registers its headerprefix, ... externalpackagedir 59 directory is the directory where the file relative to the BuildSystem or config path in python notation with . ''' 60 (utilityName, ext) = os.path.splitext(filename) 61 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 62 if directory: directory = directory+'.' 63 utilityObj = self.framework.require(directory+utilityName, self) 64 utilityObj.headerPrefix = self.headerPrefix 65 utilityObj.archProvider = self.arch 66 utilityObj.languageProvider = self.languages 67 utilityObj.installDirProvider = self.installdir 68 utilityObj.externalPackagesDirProvider = self.externalpackagesdir 69 utilityObj.precisionProvider = self.scalartypes 70 utilityObj.indexProvider = self.indexTypes 71 setattr(self, utilityName.lower(), utilityObj) 72 return utilityObj 73 return None 74 75 def setupDependencies(self, framework): 76 config.base.Configure.setupDependencies(self, framework) 77 self.programs = framework.require('config.programs', self) 78 self.setCompilers = framework.require('config.setCompilers', self) 79 self.compilers = framework.require('config.compilers', self) 80 self.arch = framework.require('PETSc.options.arch', self.setCompilers) 81 self.petscdir = framework.require('PETSc.options.petscdir', self.arch) 82 self.installdir = framework.require('PETSc.options.installDir', self) 83 self.scalartypes = framework.require('PETSc.options.scalarTypes', self) 84 self.indexTypes = framework.require('PETSc.options.indexTypes', self) 85 self.languages = framework.require('PETSc.options.languages', self.setCompilers) 86 self.indexTypes = framework.require('PETSc.options.indexTypes', self.compilers) 87 self.compilers = framework.require('config.compilers', self) 88 self.types = framework.require('config.types', self) 89 self.headers = framework.require('config.headers', self) 90 self.functions = framework.require('config.functions', self) 91 self.libraries = framework.require('config.libraries', self) 92 self.atomics = framework.require('config.atomics', self) 93 self.make = framework.require('config.packages.make', self) 94 self.blasLapack = framework.require('config.packages.BlasLapack',self) 95 self.cmake = framework.require('config.packages.cmake',self) 96 self.externalpackagesdir = framework.require('PETSc.options.externalpackagesdir',self) 97 self.mpi = framework.require('config.packages.MPI',self) 98 99 for utility in sorted(os.listdir(os.path.join('config','PETSc','options'))): 100 self.registerPythonFile(utility,'PETSc.options') 101 102 for utility in sorted(os.listdir(os.path.join('config','BuildSystem','config','utilities'))): 103 self.registerPythonFile(utility,'config.utilities') 104 105 for package in sorted(os.listdir(os.path.join('config', 'BuildSystem', 'config', 'packages'))): 106 obj = self.registerPythonFile(package,'config.packages') 107 if obj: 108 obj.archProvider = self.framework.requireModule(obj.archProvider, obj) 109 obj.languageProvider = self.framework.requireModule(obj.languageProvider, obj) 110 obj.installDirProvider = self.framework.requireModule(obj.installDirProvider, obj) 111 obj.externalPackagesDirProvider = self.framework.requireModule(obj.externalPackagesDirProvider, obj) 112 obj.precisionProvider = self.framework.requireModule(obj.precisionProvider, obj) 113 obj.indexProvider = self.framework.requireModule(obj.indexProvider, obj) 114 115 # Force blaslapack and opencl to depend on scalarType so precision is set before BlasLapack is built 116 framework.require('PETSc.options.scalarTypes', self.f2cblaslapack) 117 framework.require('PETSc.options.scalarTypes', self.fblaslapack) 118 framework.require('PETSc.options.scalarTypes', self.blaslapack) 119 framework.require('PETSc.options.scalarTypes', self.opencl) 120 121 self.programs.headerPrefix = self.headerPrefix 122 self.compilers.headerPrefix = self.headerPrefix 123 self.types.headerPrefix = self.headerPrefix 124 self.headers.headerPrefix = self.headerPrefix 125 self.functions.headerPrefix = self.headerPrefix 126 self.libraries.headerPrefix = self.headerPrefix 127 128 # Look for any user provided --download-xxx=directory packages 129 for arg in sys.argv: 130 if arg.startswith('--download-') and arg.find('=') > -1: 131 pname = arg[11:arg.find('=')] 132 if not hasattr(self,pname): 133 dname = os.path.dirname(arg[arg.find('=')+1:]) 134 if os.path.isdir(dname) and not os.path.isfile(os.path.join(dname,pname+'.py')): 135 self.framework.logPrint('User is registering a new package: '+arg) 136 sys.path.append(dname) 137 self.registerPythonFile(pname+'.py','') 138 139 # test for a variety of basic headers and functions 140 headersC = map(lambda name: name+'.h', ['setjmp','dos', 'endian', 'fcntl', 'float', 'io', 'limits', 'malloc', 'pwd', 'search', 'strings', 141 'unistd', 'sys/sysinfo', 'machine/endian', 'sys/param', 'sys/procfs', 'sys/resource', 142 'sys/systeminfo', 'sys/times', 'sys/utsname','string', 'stdlib', 143 'sys/socket','sys/wait','netinet/in','netdb','Direct','time','Ws2tcpip','sys/types', 144 'WindowsX', 'cxxabi','float','ieeefp','stdint','sched','pthread','inttypes','immintrin','zmmintrin']) 145 functions = ['access', '_access', 'clock', 'drand48', 'getcwd', '_getcwd', 'getdomainname', 'gethostname', 146 'gettimeofday', 'getwd', 'memalign', 'mkstemp', 'popen', 'PXFGETARG', 'rand', 'getpagesize', 147 'readlink', 'realpath', 'sigaction', 'signal', 'sigset', 'usleep', 'sleep', '_sleep', 'socket', 148 'times', 'gethostbyname', 'uname','snprintf','_snprintf','lseek','_lseek','time','fork','stricmp', 149 'strcasecmp', 'bzero', 'dlopen', 'dlsym', 'dlclose', 'dlerror','get_nprocs','sysctlbyname', 150 '_set_output_format','_mkdir'] 151 libraries1 = [(['socket', 'nsl'], 'socket'), (['fpe'], 'handle_sigfpes')] 152 self.headers.headers.extend(headersC) 153 self.functions.functions.extend(functions) 154 self.libraries.libraries.extend(libraries1) 155 156 return 157 158 def DumpPkgconfig(self): 159 ''' Create a pkg-config file ''' 160 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')): 161 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig')) 162 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','pkgconfig','PETSc.pc'),'w') 163 cflags_inc = ['-I${includedir}'] 164 if self.framework.argDB['prefix']: 165 fd.write('prefix='+self.installdir.dir+'\n') 166 else: 167 fd.write('prefix='+os.path.join(self.petscdir.dir, self.arch.arch)+'\n') 168 cflags_inc.append('-I' + os.path.join(self.petscdir.dir, 'include')) 169 fd.write('exec_prefix=${prefix}\n') 170 fd.write('includedir=${prefix}/include\n') 171 fd.write('libdir=${prefix}/lib\n') 172 173 self.setCompilers.pushLanguage('C') 174 fd.write('ccompiler='+self.setCompilers.getCompiler()+'\n') 175 fd.write('cflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 176 fd.write('cflags_dep='+self.compilers.dependenciesGenerationFlag.get('C','')+'\n') 177 fd.write('ldflag_rpath='+self.setCompilers.CSharedLinkerFlag+'\n') 178 self.setCompilers.popLanguage() 179 if hasattr(self.compilers, 'C++'): 180 self.setCompilers.pushLanguage('C++') 181 fd.write('cxxcompiler='+self.setCompilers.getCompiler()+'\n') 182 fd.write('cxxflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 183 self.setCompilers.popLanguage() 184 if hasattr(self.compilers, 'FC'): 185 self.setCompilers.pushLanguage('FC') 186 fd.write('fcompiler='+self.setCompilers.getCompiler()+'\n') 187 fd.write('fflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 188 self.setCompilers.popLanguage() 189 190 fd.write('\n') 191 fd.write('Name: PETSc\n') 192 fd.write('Description: Library to solve ODEs and algebraic equations\n') 193 fd.write('Version: %s\n' % self.petscdir.version) 194 fd.write('Cflags: ' + ' '.join([self.setCompilers.CPPFLAGS] + cflags_inc) + '\n') 195 fd.write('Libs: '+self.libraries.toStringNoDupes(['-L${libdir}', self.petsclib], with_rpath=False)+'\n') 196 # Remove RPATH flags from library list. User can add them using 197 # pkg-config --variable=ldflag_rpath and pkg-config --libs-only-L 198 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') 199 200 fd.close() 201 return 202 203 def DumpModule(self): 204 ''' Create a module file ''' 205 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')): 206 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules')) 207 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')): 208 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc')) 209 if self.framework.argDB['prefix']: 210 installdir = self.installdir.dir 211 installarch = '' 212 installpath = os.path.join(installdir,'bin') 213 else: 214 installdir = self.petscdir.dir 215 installarch = self.arch.arch 216 installpath = os.path.join(installdir,installarch,'bin')+':'+os.path.join(installdir,'bin') 217 fd = open(os.path.join(self.petscdir.dir,self.arch.arch,'lib','petsc','conf','modules','petsc',self.petscdir.version),'w') 218 fd.write('''\ 219#%%Module 220 221proc ModulesHelp { } { 222 puts stderr "This module sets the path and environment variables for petsc-%s" 223 puts stderr " see http://www.mcs.anl.gov/petsc/ for more information " 224 puts stderr "" 225} 226module-whatis "PETSc - Portable, Extensible Toolkit for Scientific Computation" 227 228set petsc_dir "%s" 229set petsc_arch "%s" 230 231setenv PETSC_ARCH "$petsc_arch" 232setenv PETSC_DIR "$petsc_dir" 233prepend-path PATH "%s" 234''' % (self.petscdir.version, installdir, installarch, installpath)) 235 fd.close() 236 return 237 238 def Dump(self): 239 ''' Actually put the values into the configuration files ''' 240 # eventually everything between -- should be gone 241 if self.mpi.usingMPIUni: 242 # 243 # Remove any MPI/MPICH include files that may have been put here by previous runs of ./configure 244 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) 245 246 self.setCompilers.pushLanguage('C') 247 compiler = self.setCompilers.getCompiler() 248 if compiler.endswith('mpicc') or compiler.endswith('mpiicc'): 249 try: 250 output = self.executeShellCommand(compiler + ' -show', log = self.log)[0] 251 compiler = output.split(' ')[0] 252 self.addDefine('MPICC_SHOW','"'+output.strip().replace('\n','\\\\n')+'"') 253 except: 254 self.addDefine('MPICC_SHOW','"Unavailable"') 255 else: 256 self.addDefine('MPICC_SHOW','"Unavailable"') 257 self.setCompilers.popLanguage() 258#----------------------------------------------------------------------------------------------------- 259 260 # Sometimes we need C compiler, even if built with C++ 261 self.setCompilers.pushLanguage('C') 262 self.addMakeMacro('CC_FLAGS',self.setCompilers.getCompilerFlags()) 263 self.setCompilers.popLanguage() 264 265 # And sometimes we need a C++ compiler even when PETSc is built with C 266 if hasattr(self.compilers, 'CXX'): 267 self.setCompilers.pushLanguage('Cxx') 268 self.addDefine('HAVE_CXX','1') 269 self.addMakeMacro('CXX_FLAGS',self.setCompilers.getCompilerFlags()) 270 cxx_linker = self.setCompilers.getLinker() 271 self.addMakeMacro('CXX_LINKER',cxx_linker) 272 self.addMakeMacro('CXX_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 273 self.setCompilers.popLanguage() 274 275 # C preprocessor values 276 self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS) 277 278 # compiler values 279 self.setCompilers.pushLanguage(self.languages.clanguage) 280 self.addMakeMacro('PCC',self.setCompilers.getCompiler()) 281 self.addMakeMacro('PCC_FLAGS',self.setCompilers.getCompilerFlags()) 282 self.setCompilers.popLanguage() 283 # .o or .obj 284 self.addMakeMacro('CC_SUFFIX','o') 285 286 # executable linker values 287 self.setCompilers.pushLanguage(self.languages.clanguage) 288 pcc_linker = self.setCompilers.getLinker() 289 self.addMakeMacro('PCC_LINKER',pcc_linker) 290 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 291 self.setCompilers.popLanguage() 292 # '' for Unix, .exe for Windows 293 self.addMakeMacro('CC_LINKER_SUFFIX','') 294 295 if hasattr(self.compilers, 'FC'): 296 if self.framework.argDB['with-fortran-bindings']: 297 self.addDefine('HAVE_FORTRAN','1') 298 self.setCompilers.pushLanguage('FC') 299 # need FPPFLAGS in config/setCompilers 300 self.addMakeMacro('FPP_FLAGS',self.setCompilers.CPPFLAGS) 301 302 # compiler values 303 self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags()) 304 self.setCompilers.popLanguage() 305 # .o or .obj 306 self.addMakeMacro('FC_SUFFIX','o') 307 308 # executable linker values 309 self.setCompilers.pushLanguage('FC') 310 # Cannot have NAG f90 as the linker - so use pcc_linker as fc_linker 311 fc_linker = self.setCompilers.getLinker() 312 if config.setCompilers.Configure.isNAG(fc_linker, self.log): 313 self.addMakeMacro('FC_LINKER',pcc_linker) 314 else: 315 self.addMakeMacro('FC_LINKER',fc_linker) 316 self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 317 # apple requires this shared library linker flag on SOME versions of the os 318 if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1: 319 self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ') 320 self.setCompilers.popLanguage() 321 322 # F90 Modules 323 if self.setCompilers.fortranModuleIncludeFlag: 324 self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag) 325 else: # for non-f90 compilers like g77 326 self.addMakeMacro('FC_MODULE_FLAG', '-I') 327 if self.setCompilers.fortranModuleIncludeFlag: 328 self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag) 329 else: 330 self.addMakeMacro('FC','') 331 332 if hasattr(self.compilers, 'CUDAC'): 333 self.setCompilers.pushLanguage('CUDA') 334 self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags()) 335 self.setCompilers.popLanguage() 336 337 # shared library linker values 338 self.setCompilers.pushLanguage(self.languages.clanguage) 339 # need to fix BuildSystem to collect these separately 340 self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker()) 341 self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}') 342 self.setCompilers.popLanguage() 343 # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture 344 # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX 345 if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX: 346 self.addMakeMacro('SL_LINKER_SUFFIX', '') 347 self.addDefine('SLSUFFIX','""') 348 else: 349 self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt) 350 self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"') 351 352 self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}') 353 354#----------------------------------------------------------------------------------------------------- 355 356 # CONLY or CPP. We should change the PETSc makefiles to do this better 357 if self.languages.clanguage == 'C': lang = 'CONLY' 358 else: lang = 'CXXONLY' 359 self.addMakeMacro('PETSC_LANGUAGE',lang) 360 361 # real or complex 362 self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype) 363 # double or float 364 self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision) 365 366 if self.framework.argDB['with-batch']: 367 self.addMakeMacro('PETSC_WITH_BATCH','1') 368 369 # Test for compiler-specific macros that need to be defined. 370 if self.setCompilers.isCrayVector('CC', self.log): 371 self.addDefine('HAVE_CRAY_VECTOR','1') 372 373#----------------------------------------------------------------------------------------------------- 374 if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket') and self.headers.haveHeader('netinet/in.h'): 375 self.addDefine('USE_SOCKET_VIEWER','1') 376 if self.checkCompile('#include <sys/socket.h>','setsockopt(0,SOL_SOCKET,SO_REUSEADDR,0,0)'): 377 self.addDefine('HAVE_SO_REUSEADDR','1') 378 379#----------------------------------------------------------------------------------------------------- 380 # print include and lib for makefiles 381 self.framework.packages.reverse() 382 petscincludes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')] 383 petscincludes_install = [os.path.join(self.installdir.dir, 'include')] if self.framework.argDB['prefix'] else petscincludes 384 includes = [] 385 self.packagelibs = [] 386 for i in self.framework.packages: 387 if i.useddirectly: 388 self.addDefine('HAVE_'+i.PACKAGE.replace('-','_'), 1) # ONLY list package if it is used directly by PETSc (and not only by another package) 389 if not isinstance(i.lib, list): 390 i.lib = [i.lib] 391 if i.linkedbypetsc: self.packagelibs.extend(i.lib) 392 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_LIB', self.libraries.toStringNoDupes(i.lib)) 393 if hasattr(i,'include'): 394 if not isinstance(i.include,list): 395 i.include = [i.include] 396 includes.extend(i.include) 397 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include)) 398 if self.framework.argDB['with-single-library']: 399 self.petsclib = '-lpetsc' 400 else: 401 self.petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys' 402 self.complibs = self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split() 403 self.PETSC_WITH_EXTERNAL_LIB = self.libraries.toStringNoDupes(['-L${PETSC_DIR}/${PETSC_ARCH}/lib', self.petsclib]+self.packagelibs+self.complibs) 404 self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(self.packagelibs+self.complibs) 405 if self.framework.argDB['prefix'] and self.setCompilers.CSharedLinkerFlag not in ['-L']: 406 string.replace(self.PETSC_EXTERNAL_LIB_BASIC,self.setCompilers.CSharedLinkerFlag+os.path.join(self.petscdir.dir,self.arch.arch,'lib'),self.setCompilers.CSharedLinkerFlag+os.path.join(self.installdir.dir,'lib')) 407 408 self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',self.PETSC_EXTERNAL_LIB_BASIC) 409 allincludes = petscincludes + includes 410 allincludes_install = petscincludes_install + includes 411 self.PETSC_CC_INCLUDES = self.headers.toStringNoDupes(allincludes) 412 self.PETSC_CC_INCLUDES_INSTALL = self.headers.toStringNoDupes(allincludes_install) 413 self.addMakeMacro('PETSC_CC_INCLUDES',self.PETSC_CC_INCLUDES) 414 self.addMakeMacro('PETSC_CC_INCLUDES_INSTALL', self.PETSC_CC_INCLUDES_INSTALL) 415 if hasattr(self.compilers, 'FC'): 416 def modinc(includes): 417 return includes if self.compilers.fortranIsF90 else [] 418 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(allincludes,modinc(allincludes))) 419 self.addMakeMacro('PETSC_FC_INCLUDES_INSTALL',self.headers.toStringNoDupes(allincludes_install,modinc(allincludes_install))) 420 421 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir.dir,'lib')+'"') 422 423 if self.framework.argDB['with-single-library']: 424 # overrides the values set in conf/variables 425 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 426 self.addMakeMacro('SHLIBS','libpetsc') 427 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 428 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 429 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 430 self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc') 431 self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.PETSC_WITH_EXTERNAL_LIB) 432 self.addDefine('USE_SINGLE_LIBRARY', '1') 433 if self.sharedlibraries.useShared: 434 self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 435 self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 436 self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 437 self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 438 self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 439 self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 440 self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 441 self.addMakeMacro('PETSC_TAO_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 442 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 443 self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 444 self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 445 else: 446 self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 447 self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 448 self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}') 449 self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}') 450 self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}') 451 self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}') 452 self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 453 self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}') 454 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 455 self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 456 self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}') 457 458 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 459 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 460 461# add a makefile endtry for display 462 if self.framework.argDB['with-display']: 463 self.addMakeMacro('DISPLAY',self.framework.argDB['with-display']) 464 465 # add a makefile entry for configure options 466 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 467 return 468 469 def dumpConfigInfo(self): 470 import time 471 fd = file(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 472 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')+'";\n') 473 fd.close() 474 return 475 476 def dumpMachineInfo(self): 477 import platform 478 import datetime 479 import time 480 import script 481 def escape(s): 482 return s.replace('"',r'\"').replace(r'\ ',r'\\ ') 483 fd = file(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 484 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 485 fd.write('\"-----------------------------------------\\n\"\n') 486 buildhost = platform.node() 487 if os.environ.get('SOURCE_DATE_EPOCH'): 488 buildhost = "reproducible" 489 buildtime = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) 490 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (buildtime, buildhost)) 491 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 492 fd.write('\"Using PETSc directory: %s\\n\"\n' % (escape(self.installdir.petscDir))) 493 fd.write('\"Using PETSc arch: %s\\n\"\n' % (escape(self.installdir.petscArch))) 494 fd.write('\"-----------------------------------------\\n\";\n') 495 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 496 self.setCompilers.pushLanguage(self.languages.clanguage) 497 fd.write('\"Using C compiler: %s %s \\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()))) 498 self.setCompilers.popLanguage() 499 if hasattr(self.compilers, 'FC'): 500 self.setCompilers.pushLanguage('FC') 501 fd.write('\"Using Fortran compiler: %s %s %s\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()), escape(self.setCompilers.CPPFLAGS))) 502 self.setCompilers.popLanguage() 503 fd.write('\"-----------------------------------------\\n\";\n') 504 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 505 fd.write('\"Using include paths: %s\\n\"\n' % (escape(self.PETSC_CC_INCLUDES_INSTALL.replace('${PETSC_DIR}', self.installdir.petscDir)))) 506 fd.write('\"-----------------------------------------\\n\";\n') 507 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 508 self.setCompilers.pushLanguage(self.languages.clanguage) 509 fd.write('\"Using C linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 510 self.setCompilers.popLanguage() 511 if hasattr(self.compilers, 'FC'): 512 self.setCompilers.pushLanguage('FC') 513 fd.write('\"Using Fortran linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 514 self.setCompilers.popLanguage() 515 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))) 516 fd.write('\"-----------------------------------------\\n\";\n') 517 fd.close() 518 return 519 520 def dumpCMakeConfig(self): 521 ''' 522 Writes configuration-specific values to ${PETSC_ARCH}/lib/petsc/conf/PETScBuildInternal.cmake. 523 This file is private to PETSc and should not be included by third parties 524 (a suitable file can be produced later by CMake, but this is not it). 525 ''' 526 def cmakeset(fd,key,val=True): 527 if val == True: val = 'YES' 528 if val == False: val = 'NO' 529 fd.write('set (' + key + ' ' + val + ')\n') 530 def ensurelist(a): 531 if isinstance(a,list): 532 return a 533 else: 534 return [a] 535 def libpath(lib): 536 'Returns a search path if that is what this item provides, else "" which will be cleaned out later' 537 if not isinstance(lib,str): return '' 538 if lib.startswith('-L'): return lib[2:] 539 if lib.startswith('-R'): return lib[2:] 540 if lib.startswith('-Wl,-rpath,'): 541 # This case occurs when an external package needs a specific system library that is normally provided by the compiler. 542 # In other words, the -L path is builtin to the wrapper or compiler, here we provide it so that CMake can locate the 543 # corresponding library. 544 return lib[len('-Wl,-rpath,'):] 545 if lib.startswith('-'): return '' 546 return os.path.dirname(lib) 547 def cleanlib(lib): 548 'Returns a library name if that is what this item provides, else "" which will be cleaned out later' 549 if not isinstance(lib,str): return '' 550 if lib.startswith('-l'): return lib[2:] 551 if lib.startswith('-Wl') or lib.startswith('-L'): return '' 552 lib = os.path.splitext(os.path.basename(lib))[0] 553 if lib.startswith('lib'): return lib[3:] 554 return lib 555 def nub(lst): 556 'Return a list containing the first occurrence of each unique element' 557 unique = [] 558 for elem in lst: 559 if elem not in unique and elem != '': 560 unique.append(elem) 561 return unique 562 try: reversed # reversed was added in Python-2.4 563 except NameError: 564 def reversed(lst): return lst[::-1] 565 def nublast(lst): 566 'Return a list containing the last occurrence of each unique entry in a list' 567 return reversed(nub(reversed(lst))) 568 def cmakeexpand(varname): 569 return r'"${' + varname + r'}"' 570 def uniqextend(lst,new): 571 for x in ensurelist(new): 572 if x not in lst: 573 lst.append(x) 574 def notstandardinclude(path): 575 return path not in '/usr/include'.split() # /usr/local/include is not automatically included on FreeBSD 576 def writeMacroDefinitions(fd): 577 if self.mpi.usingMPIUni: 578 cmakeset(fd,'PETSC_HAVE_MPIUNI') 579 for pkg in self.framework.packages: 580 if pkg.useddirectly: 581 cmakeset(fd,'PETSC_HAVE_' + pkg.PACKAGE.replace('-','_')) 582 for pair in pkg.defines.items(): 583 if pair[0].startswith('HAVE_') and pair[1]: 584 cmakeset(fd, self.framework.getFullDefineName(pkg, pair[0]), pair[1]) 585 for name,val in self.functions.defines.items(): 586 cmakeset(fd,'PETSC_'+name,val) 587 for dct in [self.defines, self.libraryoptions.defines]: 588 for k,v in dct.items(): 589 if k.startswith('USE_'): 590 cmakeset(fd,'PETSC_' + k, v) 591 cmakeset(fd,'PETSC_USE_COMPLEX', self.scalartypes.scalartype == 'complex') 592 cmakeset(fd,'PETSC_USE_REAL_' + self.scalartypes.precision.upper()) 593 cmakeset(fd,'PETSC_CLANGUAGE_'+self.languages.clanguage) 594 if hasattr(self.compilers, 'FC'): 595 cmakeset(fd,'PETSC_HAVE_FORTRAN') 596 if self.compilers.fortranIsF90: 597 cmakeset(fd,'PETSC_USING_F90') 598 if self.compilers.fortranIsF2003: 599 cmakeset(fd,'PETSC_USING_F2003') 600 if hasattr(self.compilers, 'CXX'): 601 cmakeset(fd,'PETSC_HAVE_CXX') 602 if self.sharedlibraries.useShared: 603 cmakeset(fd,'BUILD_SHARED_LIBS') 604 def writeBuildFlags(fd): 605 def extendby(lib): 606 libs = ensurelist(lib) 607 lib_paths.extend(map(libpath,libs)) 608 lib_libs.extend(map(cleanlib,libs)) 609 lib_paths = [] 610 lib_libs = [] 611 includes = [] 612 libvars = [] 613 for pkg in self.framework.packages: 614 if pkg.linkedbypetsc: 615 extendby(pkg.lib) 616 uniqextend(includes,pkg.include) 617 extendby(self.libraries.math) 618 extendby(self.libraries.rt) 619 extendby(self.compilers.flibs) 620 extendby(self.compilers.cxxlibs) 621 extendby(self.compilers.LIBS.split()) 622 for libname in nublast(lib_libs): 623 libvar = 'PETSC_' + libname.upper() + '_LIB' 624 addpath = '' 625 for lpath in nublast(lib_paths): 626 addpath += '"' + str(lpath) + '" ' 627 fd.write('find_library (' + libvar + ' ' + libname + ' HINTS ' + addpath + ')\n') 628 libvars.append(libvar) 629 fd.write('mark_as_advanced (' + ' '.join(libvars) + ')\n') 630 fd.write('set (PETSC_PACKAGE_LIBS ' + ' '.join(map(cmakeexpand,libvars)) + ')\n') 631 includes = filter(notstandardinclude,includes) 632 fd.write('set (PETSC_PACKAGE_INCLUDES ' + ' '.join(map(lambda i: '"'+i+'"',includes)) + ')\n') 633 fd = open(os.path.join(self.arch.arch,'lib','petsc','conf','PETScBuildInternal.cmake'), 'w') 634 writeMacroDefinitions(fd) 635 writeBuildFlags(fd) 636 fd.close() 637 return 638 639 def dumpCMakeLists(self): 640 import sys 641 if sys.version_info >= (2,4): 642 import cmakegen 643 try: 644 cmakegen.main(self.petscdir.dir, log=self.framework.log) 645 except (OSError) as e: 646 self.framework.logPrint('Generating CMakeLists.txt failed:\n' + str(e)) 647 else: 648 self.framework.logPrint('Skipping cmakegen due to old python version: ' +str(sys.version_info) ) 649 650 def cmakeBoot(self): 651 import sys 652 self.cmakeboot_success = False 653 if sys.version_info >= (2,4) and hasattr(self.cmake,'cmake'): 654 oldRead = self.argDB.readonly 655 self.argDB.readonly = True 656 try: 657 import cmakeboot 658 self.cmakeboot_success = cmakeboot.main(petscdir=self.petscdir.dir,petscarch=self.arch.arch,argDB=self.argDB,framework=self.framework,log=self.framework.log) 659 except (OSError) as e: 660 self.framework.logPrint('Booting CMake in PETSC_ARCH failed:\n' + str(e)) 661 except (ImportError, KeyError) as e: 662 self.framework.logPrint('Importing cmakeboot failed:\n' + str(e)) 663 self.argDB.readonly = oldRead 664 if self.cmakeboot_success: 665 if hasattr(self.compilers, 'FC') and self.compilers.fortranIsF90 and not self.setCompilers.fortranModuleOutputFlag: 666 self.framework.logPrint('CMake configured successfully, but could not be used by default because of missing fortranModuleOutputFlag\n') 667 else: 668 self.framework.logPrint('CMake configured successfully, using as default build\n') 669 self.addMakeMacro('PETSC_BUILD_USING_CMAKE',1) 670 else: 671 self.framework.logPrint('CMake configuration was unsuccessful\n') 672 else: 673 self.framework.logPrint('Skipping cmakeboot due to old python version: ' +str(sys.version_info) ) 674 return 675 676 def configurePrefetch(self): 677 '''Sees if there are any prefetch functions supported''' 678 if config.setCompilers.Configure.isSolaris(self.log) or self.framework.argDB['with-ios'] or not self.framework.argDB['with-prefetch']: 679 self.addDefine('Prefetch(a,b,c)', ' ') 680 return 681 self.pushLanguage(self.languages.clanguage) 682 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 683 # The Intel Intrinsics manual [1] specifies the prototype 684 # 685 # void _mm_prefetch(char const *a, int sel); 686 # 687 # but other vendors seem to insist on using subtly different 688 # prototypes, including void* for the pointer, and an enum for 689 # sel. These are both reasonable changes, but negatively impact 690 # portability. 691 # 692 # [1] http://software.intel.com/file/6373 693 self.addDefine('HAVE_XMMINTRIN_H', 1) 694 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 695 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 696 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 697 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 698 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 699 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 700 self.addDefine('HAVE_XMMINTRIN_H', 1) 701 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 702 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 703 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 704 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 705 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 706 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 707 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 708 # 709 # The value of rw is a compile-time constant one or zero; one 710 # means that the prefetch is preparing for a write to the memory 711 # address and zero, the default, means that the prefetch is 712 # preparing for a read. The value locality must be a compile-time 713 # constant integer between zero and three. A value of zero means 714 # that the data has no temporal locality, so it need not be left 715 # in the cache after the access. A value of three means that the 716 # data has a high degree of temporal locality and should be left 717 # in all levels of cache possible. Values of one and two mean, 718 # respectively, a low or moderate degree of temporal locality. 719 # 720 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 721 # hints. Using macros for these values in necessary since some 722 # compilers require an enum. 723 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 724 self.addDefine('PREFETCH_HINT_NTA', '0') 725 self.addDefine('PREFETCH_HINT_T0', '3') 726 self.addDefine('PREFETCH_HINT_T1', '2') 727 self.addDefine('PREFETCH_HINT_T2', '1') 728 else: 729 self.addDefine('Prefetch(a,b,c)', ' ') 730 self.popLanguage() 731 732 def configureAtoll(self): 733 '''Checks if atoll exists''' 734 if self.checkLink('#define _POSIX_C_SOURCE 200112L\n#include <stdlib.h>','long v = atoll("25")') or self.checkLink ('#include <stdlib.h>','long v = atoll("25")'): 735 self.addDefine('HAVE_ATOLL', '1') 736 737 def configureUnused(self): 738 '''Sees if __attribute((unused)) is supported''' 739 if self.framework.argDB['with-ios']: 740 self.addDefine('UNUSED', ' ') 741 return 742 self.pushLanguage(self.languages.clanguage) 743 if self.checkLink('__attribute((unused)) static int myfunc(__attribute((unused)) void *name){ return 1;}', 'int i = 0;\nint j = myfunc(&i);\ntypedef void* atype;\n__attribute((unused)) atype a;\n'): 744 self.addDefine('UNUSED', '__attribute((unused))') 745 else: 746 self.addDefine('UNUSED', ' ') 747 self.popLanguage() 748 749 def configureIsatty(self): 750 '''Check if the Unix C function isatty() works correctly 751 Actually just assumes it does not work correctly on batch systems''' 752 if not self.framework.argDB['with-batch']: 753 self.addDefine('USE_ISATTY',1) 754 755 def configureDeprecated(self): 756 '''Check if __attribute((deprecated)) is supported''' 757 self.pushLanguage(self.languages.clanguage) 758 ## Recent versions of gcc and clang support __attribute((deprecated("string argument"))), which is very useful, but 759 ## Intel has conspired to make a supremely environment-sensitive compiler. The Intel compiler looks at the gcc 760 ## executable in the environment to determine the language compatibility that it should attempt to emulate. Some 761 ## important Cray installations have built PETSc using the Intel compiler, but with a newer gcc module loaded (e.g., 762 ## 4.7). Thus at PETSc configure time, the Intel compiler decides to support the string argument, but the gcc 763 ## found in the default user environment is older and does not support the argument. If GCC and Intel were cool 764 ## like Clang and supported __has_attribute, we could avoid configure tests entirely, but they don't. And that is 765 ## why we can't have nice things. 766 # 767 # if self.checkCompile("""__attribute((deprecated("Why you shouldn't use myfunc"))) static int myfunc(void) { return 1;}""", ''): 768 # self.addDefine('DEPRECATED(why)', '__attribute((deprecated(why)))') 769 if self.checkCompile("""__attribute((deprecated)) static int myfunc(void) { return 1;}""", ''): 770 self.addDefine('DEPRECATED(why)', '__attribute((deprecated))') 771 else: 772 self.addDefine('DEPRECATED(why)', ' ') 773 self.popLanguage() 774 775 def configureAlign(self): 776 '''Check if __attribute(align) is supported''' 777 filename = 'conftestalign' 778 includes = ''' 779#include <sys/types.h> 780#if STDC_HEADERS 781#include <stdlib.h> 782#include <stdio.h> 783#include <stddef.h> 784#endif\n''' 785 body = ''' 786struct mystruct {int myint;} __attribute((aligned(16))); 787FILE *f = fopen("'''+filename+'''", "w"); 788if (!f) exit(1); 789fprintf(f, "%lu\\n", (unsigned long)sizeof(struct mystruct)); 790''' 791 if 'known-has-attribute-aligned' in self.argDB: 792 if self.argDB['known-has-attribute-aligned']: 793 size = 16 794 else: 795 size = -3 796 elif not self.argDB['with-batch']: 797 self.pushLanguage(self.languages.clanguage) 798 try: 799 if self.checkRun(includes, body) and os.path.exists(filename): 800 f = file(filename) 801 size = int(f.read()) 802 f.close() 803 os.remove(filename) 804 else: 805 size = -4 806 except: 807 size = -1 808 self.framework.logPrint('Error checking attribute(aligned)') 809 self.popLanguage() 810 else: 811 self.framework.addBatchInclude(['#include <stdlib.h>', '#include <stdio.h>', '#include <sys/types.h>','struct mystruct {int myint;} __attribute((aligned(16)));']) 812 self.framework.addBatchBody('fprintf(output, " \'--known-has-attribute-aligned=%d\',\\n", sizeof(struct mystruct)==16);') 813 size = -2 814 if size == 16: 815 self.addDefine('ATTRIBUTEALIGNED(size)', '__attribute((aligned (size)))') 816 self.addDefine('HAVE_ATTRIBUTEALIGNED', 1) 817 else: 818 self.framework.logPrint('incorrect alignment. Found alignment:'+ str(size)) 819 self.addDefine('ATTRIBUTEALIGNED(size)', ' ') 820 return 821 822 def configureExpect(self): 823 '''Sees if the __builtin_expect directive is supported''' 824 self.pushLanguage(self.languages.clanguage) 825 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 826 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 827 self.popLanguage() 828 829 def configureFunctionName(self): 830 '''Sees if the compiler supports __func__ or a variant.''' 831 def getFunctionName(lang): 832 name = '"unknown"' 833 self.pushLanguage(lang) 834 for fname in ['__func__','__FUNCTION__','__extension__ __func__']: 835 code = "if ("+fname+"[0] != 'm') return 1;" 836 if self.checkCompile('',code) and self.checkLink('',code): 837 name = fname 838 break 839 self.popLanguage() 840 return name 841 langs = [] 842 843 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 844 if hasattr(self.compilers, 'CXX'): 845 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 846 847 def configureIntptrt(self): 848 '''Determine what to use for uintptr_t''' 849 def staticAssertSizeMatchesVoidStar(inc,typename): 850 # The declaration is an error if either array size is negative. 851 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 852 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 853 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 854 self.pushLanguage(self.languages.clanguage) 855 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 856 self.addDefine('UINTPTR_T', 'uintptr_t') 857 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 858 self.addDefine('UINTPTR_T', 'unsigned long long') 859 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 860 self.addDefine('UINTPTR_T', 'size_t') 861 elif staticAssertSizeMatchesVoidStar('','unsigned long'): 862 self.addDefine('UINTPTR_T', 'unsigned long') 863 elif staticAssertSizeMatchesVoidStar('','unsigned'): 864 self.addDefine('UINTPTR_T', 'unsigned') 865 else: 866 raise RuntimeError('Could not find any unsigned integer type matching void*') 867 self.popLanguage() 868 869 def configureRTLDDefault(self): 870 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 871 self.addDefine('RTLD_DEFAULT','1') 872 return 873 874 def configureSolaris(self): 875 '''Solaris specific stuff''' 876 if os.path.isdir(os.path.join('/usr','ucblib')): 877 try: 878 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 879 except AttributeError: 880 flag = None 881 if flag is None: 882 self.compilers.LIBS += ' -L/usr/ucblib' 883 else: 884 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 885 return 886 887 def configureLinux(self): 888 '''Linux specific stuff''' 889 # TODO: Test for this by mallocing an odd number of floats and checking the address 890 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 891 return 892 893 def configureWin32(self): 894 '''Win32 non-cygwin specific stuff''' 895 kernel32=0 896 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 897 self.addDefine('HAVE_WINDOWS_H',1) 898 self.addDefine('HAVE_GETCOMPUTERNAME',1) 899 kernel32=1 900 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 901 self.addDefine('HAVE_WINDOWS_H',1) 902 self.addDefine('HAVE_GETCOMPUTERNAME',1) 903 kernel32=1 904 if kernel32: 905 if self.framework.argDB['with-windows-graphics']: 906 self.addDefine('USE_WINDOWS_GRAPHICS',1) 907 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 908 self.addDefine('HAVE_LOADLIBRARY',1) 909 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 910 self.addDefine('HAVE_GETPROCADDRESS',1) 911 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 912 self.addDefine('HAVE_FREELIBRARY',1) 913 if self.checkLink('#include <Windows.h>','GetLastError()'): 914 self.addDefine('HAVE_GETLASTERROR',1) 915 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 916 self.addDefine('HAVE_SETLASTERROR',1) 917 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 918 self.addDefine('USE_MICROSOFT_TIME',1) 919 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 920 self.addDefine('HAVE_GET_USER_NAME',1) 921 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 922 self.addDefine('HAVE_GET_USER_NAME',1) 923 924 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 925 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 926 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 927 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 928 929 self.types.check('int32_t', 'int') 930 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 931 self.addTypedef('int', 'uid_t') 932 self.addTypedef('int', 'gid_t') 933 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 934 self.framework.addDefine('R_OK', '04') 935 self.framework.addDefine('W_OK', '02') 936 self.framework.addDefine('X_OK', '01') 937 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 938 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 939 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 940 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 941 self.addDefine('HAVE_LARGE_INTEGER_U',1) 942 943 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 944 if self.checkCompile('#include <Windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'): 945 self.addDefine('HAVE_O_BINARY',1) 946 947 if self.compilers.CC.find('win32fe') >= 0: 948 self.addDefine('HAVE_WINDOWS_COMPILERS',1) 949 self.addDefine('PATH_SEPARATOR','\';\'') 950 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 951 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 952 self.addDefine('CANNOT_START_DEBUGGER',1) 953 (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.installdir.petscDir, log = self.log) 954 self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"') 955 (petscdir,error,status) = self.executeShellCommand('cygpath -m '+self.installdir.petscDir, log = self.log) 956 self.addMakeMacro('wPETSC_DIR',petscdir) 957 else: 958 self.addDefine('PATH_SEPARATOR','\':\'') 959 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 960 self.addDefine('DIR_SEPARATOR','\'/\'') 961 self.addDefine('DIR','"'+self.installdir.petscDir+'"') 962 self.addMakeMacro('wPETSC_DIR',self.installdir.petscDir) 963 self.addDefine('ARCH','"'+self.installdir.petscArch+'"') 964 return 965 966#----------------------------------------------------------------------------------------------------- 967 def configureCygwinBrokenPipe(self): 968 '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make 969 http://cygwin.com/ml/cygwin/2013-05/msg00340.html ''' 970 if config.setCompilers.Configure.isCygwin(self.log): 971 import platform 972 import re 973 r=re.compile("([0-9]+).([0-9]+).([0-9]+)") 974 m=r.match(platform.release()) 975 major=int(m.group(1)) 976 minor=int(m.group(2)) 977 subminor=int(m.group(3)) 978 if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)): 979 self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1') 980 return 981 982#----------------------------------------------------------------------------------------------------- 983 def configureDefaultArch(self): 984 conffile = os.path.join('lib','petsc','conf', 'petscvariables') 985 if self.framework.argDB['with-default-arch']: 986 fd = file(conffile, 'w') 987 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 988 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 989 fd.write('include '+os.path.join('$(PETSC_DIR)','$(PETSC_ARCH)','lib','petsc','conf','petscvariables')+'\n') 990 fd.close() 991 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 992 elif os.path.isfile(conffile): 993 try: 994 os.unlink(conffile) 995 except: 996 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 997 return 998 999#----------------------------------------------------------------------------------------------------- 1000 def configureScript(self): 1001 '''Output a script in the conf directory which will reproduce the configuration''' 1002 import nargs 1003 import sys 1004 scriptName = os.path.join(self.arch.arch,'lib','petsc','conf', 'reconfigure-'+self.arch.arch+'.py') 1005 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 1006 if 'with-clean' in args: 1007 del args['with-clean'] 1008 if 'configModules' in args: 1009 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 1010 del args['configModules'] 1011 if 'optionsModule' in args: 1012 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions': 1013 del args['optionsModule'] 1014 if not 'PETSC_ARCH' in args: 1015 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 1016 f = file(scriptName, 'w') 1017 f.write('#!'+sys.executable+'\n') 1018 f.write('if __name__ == \'__main__\':\n') 1019 f.write(' import sys\n') 1020 f.write(' import os\n') 1021 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 1022 f.write(' import configure\n') 1023 # pretty print repr(args.values()) 1024 f.write(' configure_options = [\n') 1025 for itm in sorted(args.values()): 1026 f.write(' \''+str(itm)+'\',\n') 1027 f.write(' ]\n') 1028 f.write(' configure.petsc_configure(configure_options)\n') 1029 f.close() 1030 try: 1031 os.chmod(scriptName, 0o775) 1032 except OSError as e: 1033 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 1034 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 1035 return 1036 1037 def configureInstall(self): 1038 '''Setup the directories for installation''' 1039 if self.framework.argDB['prefix']: 1040 self.addMakeRule('shared_install','',['-@echo "Now to install the libraries do:"',\ 1041 '-@echo "'+self.installdir.installSudo+'make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 1042 '-@echo "========================================="']) 1043 else: 1044 self.addMakeRule('shared_install','',['-@echo "Now to check if the libraries are working do:"',\ 1045 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} check"',\ 1046 '-@echo "========================================="']) 1047 return 1048 1049 def configureGCOV(self): 1050 if self.framework.argDB['with-gcov']: 1051 self.addDefine('USE_GCOV','1') 1052 return 1053 1054 def postProcessPackages(self): 1055 postPackages=[] 1056 for i in self.framework.packages: 1057 if hasattr(i,'postProcess'): postPackages.append(i) 1058 if postPackages: 1059 # ctetgen needs petsc conf files. so attempt to create them early 1060 self.framework.dumpConfFiles() 1061 # tacky fix for dependency of Aluimia on Pflotran; requested via petsc-dev Matt provide a correct fix 1062 for i in postPackages: 1063 if i.name.upper() in ['PFLOTRAN']: 1064 i.postProcess() 1065 postPackages.remove(i) 1066 for i in postPackages: i.postProcess() 1067 for i in postPackages: 1068 if i.installedpetsc: 1069 self.installed = 1 1070 break 1071 return 1072 1073 def configure(self): 1074 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 1075 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 1076 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 1077 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 1078 if self.framework.argDB['prefix'] and self.framework.argDB['prefix'].find(' ') > -1: 1079 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') 1080 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)): 1081 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 1082 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 1083 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 1084 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscvariables') 1085 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscrules') 1086 if self.libraries.math is None: 1087 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 1088 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 1089 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 1090 self.executeTest(self.configureRTLDDefault) 1091 self.executeTest(self.configurePrefetch) 1092 self.executeTest(self.configureUnused) 1093 self.executeTest(self.configureDeprecated) 1094 self.executeTest(self.configureIsatty) 1095 self.executeTest(self.configureExpect); 1096 self.executeTest(self.configureAlign); 1097 self.executeTest(self.configureFunctionName); 1098 self.executeTest(self.configureIntptrt); 1099 self.executeTest(self.configureSolaris) 1100 self.executeTest(self.configureLinux) 1101 self.executeTest(self.configureWin32) 1102 self.executeTest(self.configureCygwinBrokenPipe) 1103 self.executeTest(self.configureDefaultArch) 1104 self.executeTest(self.configureScript) 1105 self.executeTest(self.configureInstall) 1106 self.executeTest(self.configureGCOV) 1107 self.executeTest(self.configureAtoll) 1108 1109 self.Dump() 1110 self.dumpConfigInfo() 1111 self.dumpMachineInfo() 1112 self.dumpCMakeConfig() 1113 self.dumpCMakeLists() 1114 # need to save the current state of BuildSystem so that postProcess() packages can read it in and perhaps run make install 1115 self.framework.storeSubstitutions(self.framework.argDB) 1116 self.framework.argDB['configureCache'] = cPickle.dumps(self.framework) 1117 self.framework.argDB.save(force = True) 1118 self.cmakeBoot() 1119 self.DumpPkgconfig() 1120 self.DumpModule() 1121 self.postProcessPackages() 1122 self.framework.log.write('================================================================================\n') 1123 self.logClear() 1124 return 1125