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