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