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