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