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