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