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