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