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