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