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