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