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