1import config.base 2 3import os 4import sys 5import re 6import pickle 7 8class Configure(config.base.Configure): 9 def __init__(self, framework): 10 config.base.Configure.__init__(self, framework) 11 self.headerPrefix = 'PETSC' 12 self.substPrefix = 'PETSC' 13 self.installed = 0 # 1 indicates that Configure itself has already compiled and installed PETSc 14 return 15 16 def __str2__(self): 17 desc = [] 18 if not self.installed: 19 desc.append('xxx=========================================================================xxx') 20 desc.append(' Configure stage complete. Now build PETSc libraries with:') 21 desc.append(' make PETSC_DIR='+self.petscdir.dir+' PETSC_ARCH='+self.arch.arch+' all') 22 desc.append('xxx=========================================================================xxx') 23 else: 24 desc.append('xxx=========================================================================xxx') 25 desc.append(' Installation complete. You do not need to run make to compile or install the software') 26 desc.append('xxx=========================================================================xxx') 27 return '\n'.join(desc)+'\n' 28 29 def setupHelp(self, help): 30 import nargs 31 help.addArgument('PETSc', '-prefix=<dir>', nargs.Arg(None, '', 'Specifiy location to install PETSc (eg. /usr/local)')) 32 help.addArgument('PETSc', '-with-prefetch=<bool>', nargs.ArgBool(None, 1,'Enable checking for prefetch instructions')) 33 help.addArgument('Windows','-with-windows-graphics=<bool>', nargs.ArgBool(None, 1,'Enable check for Windows Graphics')) 34 help.addArgument('PETSc', '-with-default-arch=<bool>', nargs.ArgBool(None, 1, 'Allow using the last configured arch without setting PETSC_ARCH')) 35 help.addArgument('PETSc','-with-single-library=<bool>', nargs.ArgBool(None, 1,'Put all PETSc code into the single -lpetsc library')) 36 help.addArgument('PETSc','-with-fortran-bindings=<bool>', nargs.ArgBool(None, 1,'Build PETSc fortran bindings in the library and corresponding module files')) 37 help.addArgument('PETSc', '-with-ios=<bool>', nargs.ArgBool(None, 0, 'Build an iPhone/iPad version of PETSc library')) 38 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')) 39 help.addArgument('PETSc', '-known-has-attribute-aligned=<bool>',nargs.ArgBool(None, None, 'Indicates __attribute((aligned(16)) directive works (the usual test will be skipped)')) 40 help.addArgument('PETSc', '-with-display=<x11display>', nargs.Arg(None, '', 'Specifiy DISPLAY env variable for use with matlab test)')) 41 help.addArgument('PETSc', '-with-package-scripts=<pyscripts>',nargs.ArgFileList(None,None,'Specify configure package scripts for user provided packages')) 42 return 43 44 def registerPythonFile(self,filename,directory): 45 ''' Add a python file to the framework and registers its headerprefix, ... externalpackagedir 46 directory is the directory where the file relative to the BuildSystem or config path in python notation with . ''' 47 (utilityName, ext) = os.path.splitext(filename) 48 if not utilityName.startswith('.') and not utilityName.startswith('#') and ext == '.py' and not utilityName == '__init__': 49 if directory: directory = directory+'.' 50 utilityObj = self.framework.require(directory+utilityName, self) 51 utilityObj.headerPrefix = self.headerPrefix 52 utilityObj.archProvider = self.arch 53 utilityObj.languageProvider = self.languages 54 utilityObj.installDirProvider = self.installdir 55 utilityObj.externalPackagesDirProvider = self.externalpackagesdir 56 utilityObj.precisionProvider = self.scalartypes 57 utilityObj.indexProvider = self.indexTypes 58 setattr(self, utilityName.lower(), utilityObj) 59 return utilityObj 60 return None 61 62 def setupDependencies(self, framework): 63 config.base.Configure.setupDependencies(self, framework) 64 self.programs = framework.require('config.programs', self) 65 self.setCompilers = framework.require('config.setCompilers', self) 66 self.compilers = framework.require('config.compilers', self) 67 self.arch = framework.require('PETSc.options.arch', self.setCompilers) 68 self.petscdir = framework.require('PETSc.options.petscdir', self.arch) 69 self.installdir = framework.require('PETSc.options.installDir', self) 70 self.scalartypes = framework.require('PETSc.options.scalarTypes', self) 71 self.indexTypes = framework.require('PETSc.options.indexTypes', self) 72 self.languages = framework.require('PETSc.options.languages', self.setCompilers) 73 self.indexTypes = framework.require('PETSc.options.indexTypes', self.compilers) 74 self.compilers = framework.require('config.compilers', self) 75 self.types = framework.require('config.types', self) 76 self.headers = framework.require('config.headers', self) 77 self.functions = framework.require('config.functions', self) 78 self.libraries = framework.require('config.libraries', self) 79 self.atomics = framework.require('config.atomics', self) 80 self.make = framework.require('config.packages.make', self) 81 self.blasLapack = framework.require('config.packages.BlasLapack',self) 82 self.externalpackagesdir = framework.require('PETSc.options.externalpackagesdir',self) 83 self.mpi = framework.require('config.packages.MPI',self) 84 85 for utility in sorted(os.listdir(os.path.join('config','PETSc','options'))): 86 self.registerPythonFile(utility,'PETSc.options') 87 88 for utility in sorted(os.listdir(os.path.join('config','BuildSystem','config','utilities'))): 89 self.registerPythonFile(utility,'config.utilities') 90 91 for package in sorted(os.listdir(os.path.join('config', 'BuildSystem', 'config', 'packages'))): 92 obj = self.registerPythonFile(package,'config.packages') 93 if obj: 94 obj.archProvider = self.framework.requireModule(obj.archProvider, obj) 95 obj.languageProvider = self.framework.requireModule(obj.languageProvider, obj) 96 obj.installDirProvider = self.framework.requireModule(obj.installDirProvider, obj) 97 obj.externalPackagesDirProvider = self.framework.requireModule(obj.externalPackagesDirProvider, obj) 98 obj.precisionProvider = self.framework.requireModule(obj.precisionProvider, obj) 99 obj.indexProvider = self.framework.requireModule(obj.indexProvider, obj) 100 101 # Force blaslapack and opencl to depend on scalarType so precision is set before BlasLapack is built 102 framework.require('PETSc.options.scalarTypes', self.f2cblaslapack) 103 framework.require('PETSc.options.scalarTypes', self.fblaslapack) 104 framework.require('PETSc.options.scalarTypes', self.blaslapack) 105 framework.require('PETSc.options.scalarTypes', self.opencl) 106 107 self.programs.headerPrefix = self.headerPrefix 108 self.compilers.headerPrefix = self.headerPrefix 109 self.types.headerPrefix = self.headerPrefix 110 self.headers.headerPrefix = self.headerPrefix 111 self.functions.headerPrefix = self.headerPrefix 112 self.libraries.headerPrefix = self.headerPrefix 113 114 # Register user provided package scripts 115 if 'with-package-scripts' in self.framework.argDB: 116 for script in self.framework.argDB['with-package-scripts']: 117 if os.path.splitext(script)[1] != '.py': 118 raise RuntimeError('Only python scripts compatible with configure package script format should be specified! Invalid option -with-package-scripts='+script) 119 self.framework.logPrint('User is registering a new package script: '+script) 120 dname,fname = os.path.split(script) 121 if dname: sys.path.append(dname) 122 self.registerPythonFile(fname,'') 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','inttypes','immintrin','zmmintrin']) 130 functions = ['access', '_access', 'clock', 'drand48', 'getcwd', '_getcwd', 'getdomainname', 'gethostname', 131 'gettimeofday', 'getwd', 'memalign', '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 cflags_inc = ['-I${includedir}'] 149 if self.framework.argDB['prefix']: 150 fd.write('prefix='+self.installdir.dir+'\n') 151 else: 152 fd.write('prefix='+os.path.join(self.petscdir.dir, self.arch.arch)+'\n') 153 cflags_inc.append('-I' + os.path.join(self.petscdir.dir, 'include')) 154 fd.write('exec_prefix=${prefix}\n') 155 fd.write('includedir=${prefix}/include\n') 156 fd.write('libdir=${prefix}/lib\n') 157 158 self.setCompilers.pushLanguage('C') 159 fd.write('ccompiler='+self.setCompilers.getCompiler()+'\n') 160 fd.write('cflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 161 fd.write('cflags_dep='+self.compilers.dependenciesGenerationFlag.get('C','')+'\n') 162 fd.write('ldflag_rpath='+self.setCompilers.CSharedLinkerFlag+'\n') 163 self.setCompilers.popLanguage() 164 if hasattr(self.compilers, 'CXX'): 165 self.setCompilers.pushLanguage('C++') 166 fd.write('cxxcompiler='+self.setCompilers.getCompiler()+'\n') 167 fd.write('cxxflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 168 self.setCompilers.popLanguage() 169 if hasattr(self.compilers, 'FC'): 170 self.setCompilers.pushLanguage('FC') 171 fd.write('fcompiler='+self.setCompilers.getCompiler()+'\n') 172 fd.write('fflags_extra='+self.setCompilers.getCompilerFlags().strip()+'\n') 173 self.setCompilers.popLanguage() 174 175 fd.write('\n') 176 fd.write('Name: PETSc\n') 177 fd.write('Description: Library to solve ODEs and algebraic equations\n') 178 fd.write('Version: %s\n' % self.petscdir.version) 179 fd.write('Cflags: ' + ' '.join([self.setCompilers.CPPFLAGS] + cflags_inc) + '\n') 180 fd.write('Libs: '+self.libraries.toStringNoDupes(['-L${libdir}', self.petsclib], with_rpath=False)+'\n') 181 # Remove RPATH flags from library list. User can add them using 182 # pkg-config --variable=ldflag_rpath and pkg-config --libs-only-L 183 fd.write('Libs.private: '+self.libraries.toStringNoDupes([f for f in self.packagelibs+self.complibs if not f.startswith(self.setCompilers.CSharedLinkerFlag)], with_rpath=False)+'\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 https://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 self.setCompilers.pushLanguage('C') 232 compiler = self.setCompilers.getCompiler() 233 if compiler.endswith('mpicc') or compiler.endswith('mpiicc'): 234 try: 235 output = self.executeShellCommand(compiler + ' -show', log = self.log)[0] 236 compiler = output.split(' ')[0] 237 self.addDefine('MPICC_SHOW','"'+output.strip().replace('\n','\\\\n')+'"') 238 except: 239 self.addDefine('MPICC_SHOW','"Unavailable"') 240 else: 241 self.addDefine('MPICC_SHOW','"Unavailable"') 242 self.setCompilers.popLanguage() 243#----------------------------------------------------------------------------------------------------- 244 245 # Sometimes we need C compiler, even if built with C++ 246 self.setCompilers.pushLanguage('C') 247 self.addMakeMacro('CC_FLAGS',self.setCompilers.getCompilerFlags()) 248 self.setCompilers.popLanguage() 249 250 # And sometimes we need a C++ compiler even when PETSc is built with C 251 if hasattr(self.compilers, 'CXX'): 252 self.setCompilers.pushLanguage('Cxx') 253 self.addDefine('HAVE_CXX','1') 254 self.addMakeMacro('CXX_FLAGS',self.setCompilers.getCompilerFlags()) 255 cxx_linker = self.setCompilers.getLinker() 256 self.addMakeMacro('CXX_LINKER',cxx_linker) 257 self.addMakeMacro('CXX_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 258 self.setCompilers.popLanguage() 259 260 # C preprocessor values 261 self.addMakeMacro('CPP_FLAGS',self.setCompilers.CPPFLAGS) 262 263 # compiler values 264 self.setCompilers.pushLanguage(self.languages.clanguage) 265 self.addMakeMacro('PCC',self.setCompilers.getCompiler()) 266 self.addMakeMacro('PCC_FLAGS',self.setCompilers.getCompilerFlags()) 267 self.setCompilers.popLanguage() 268 # .o or .obj 269 self.addMakeMacro('CC_SUFFIX','o') 270 271 # executable linker values 272 self.setCompilers.pushLanguage(self.languages.clanguage) 273 pcc_linker = self.setCompilers.getLinker() 274 self.addMakeMacro('PCC_LINKER',pcc_linker) 275 self.addMakeMacro('PCC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 276 self.setCompilers.popLanguage() 277 # '' for Unix, .exe for Windows 278 self.addMakeMacro('CC_LINKER_SUFFIX','') 279 280 if hasattr(self.compilers, 'FC'): 281 if self.framework.argDB['with-fortran-bindings']: 282 self.addDefine('HAVE_FORTRAN','1') 283 self.setCompilers.pushLanguage('FC') 284 # need FPPFLAGS in config/setCompilers 285 self.addMakeMacro('FPP_FLAGS',self.setCompilers.CPPFLAGS) 286 287 # compiler values 288 self.addMakeMacro('FC_FLAGS',self.setCompilers.getCompilerFlags()) 289 self.setCompilers.popLanguage() 290 # .o or .obj 291 self.addMakeMacro('FC_SUFFIX','o') 292 293 # executable linker values 294 self.setCompilers.pushLanguage('FC') 295 # Cannot have NAG f90 as the linker - so use pcc_linker as fc_linker 296 fc_linker = self.setCompilers.getLinker() 297 if config.setCompilers.Configure.isNAG(fc_linker, self.log): 298 self.addMakeMacro('FC_LINKER',pcc_linker) 299 else: 300 self.addMakeMacro('FC_LINKER',fc_linker) 301 self.addMakeMacro('FC_LINKER_FLAGS',self.setCompilers.getLinkerFlags()) 302 # apple requires this shared library linker flag on SOME versions of the os 303 if self.setCompilers.getLinkerFlags().find('-Wl,-commons,use_dylibs') > -1: 304 self.addMakeMacro('DARWIN_COMMONS_USE_DYLIBS',' -Wl,-commons,use_dylibs ') 305 self.setCompilers.popLanguage() 306 307 # F90 Modules 308 if self.setCompilers.fortranModuleIncludeFlag: 309 self.addMakeMacro('FC_MODULE_FLAG', self.setCompilers.fortranModuleIncludeFlag) 310 else: # for non-f90 compilers like g77 311 self.addMakeMacro('FC_MODULE_FLAG', '-I') 312 if self.setCompilers.fortranModuleIncludeFlag: 313 self.addMakeMacro('FC_MODULE_OUTPUT_FLAG', self.setCompilers.fortranModuleOutputFlag) 314 else: 315 self.addMakeMacro('FC','') 316 317 if hasattr(self.compilers, 'CUDAC'): 318 self.setCompilers.pushLanguage('CUDA') 319 self.addMakeMacro('CUDAC_FLAGS',self.setCompilers.getCompilerFlags()) 320 self.setCompilers.popLanguage() 321 322 # shared library linker values 323 self.setCompilers.pushLanguage(self.languages.clanguage) 324 # need to fix BuildSystem to collect these separately 325 self.addMakeMacro('SL_LINKER',self.setCompilers.getLinker()) 326 self.addMakeMacro('SL_LINKER_FLAGS','${PCC_LINKER_FLAGS}') 327 self.setCompilers.popLanguage() 328 # One of 'a', 'so', 'lib', 'dll', 'dylib' (perhaps others also?) depending on the library generator and architecture 329 # Note: . is not included in this macro, consistent with AR_LIB_SUFFIX 330 if self.setCompilers.sharedLibraryExt == self.setCompilers.AR_LIB_SUFFIX: 331 self.addMakeMacro('SL_LINKER_SUFFIX', '') 332 self.addDefine('SLSUFFIX','""') 333 else: 334 self.addMakeMacro('SL_LINKER_SUFFIX', self.setCompilers.sharedLibraryExt) 335 self.addDefine('SLSUFFIX','"'+self.setCompilers.sharedLibraryExt+'"') 336 337 self.addMakeMacro('SL_LINKER_LIBS','${PETSC_EXTERNAL_LIB_BASIC}') 338 339#----------------------------------------------------------------------------------------------------- 340 341 # CONLY or CPP. We should change the PETSc makefiles to do this better 342 if self.languages.clanguage == 'C': lang = 'CONLY' 343 else: lang = 'CXXONLY' 344 self.addMakeMacro('PETSC_LANGUAGE',lang) 345 346 # real or complex 347 self.addMakeMacro('PETSC_SCALAR',self.scalartypes.scalartype) 348 # double or float 349 self.addMakeMacro('PETSC_PRECISION',self.scalartypes.precision) 350 351 if self.framework.argDB['with-batch']: 352 self.addMakeMacro('PETSC_WITH_BATCH','1') 353 354 # Test for compiler-specific macros that need to be defined. 355 if self.setCompilers.isCrayVector('CC', self.log): 356 self.addDefine('HAVE_CRAY_VECTOR','1') 357 358#----------------------------------------------------------------------------------------------------- 359 if self.functions.haveFunction('gethostbyname') and self.functions.haveFunction('socket') and self.headers.haveHeader('netinet/in.h'): 360 self.addDefine('USE_SOCKET_VIEWER','1') 361 if self.checkCompile('#include <sys/socket.h>','setsockopt(0,SOL_SOCKET,SO_REUSEADDR,0,0)'): 362 self.addDefine('HAVE_SO_REUSEADDR','1') 363 364#----------------------------------------------------------------------------------------------------- 365 # print include and lib for makefiles 366 self.framework.packages.reverse() 367 petscincludes = [os.path.join(self.petscdir.dir,'include'),os.path.join(self.petscdir.dir,self.arch.arch,'include')] 368 petscincludes_install = [os.path.join(self.installdir.dir, 'include')] if self.framework.argDB['prefix'] else petscincludes 369 includes = [] 370 self.packagelibs = [] 371 for i in self.framework.packages: 372 if i.useddirectly: 373 self.addDefine('HAVE_'+i.PACKAGE.replace('-','_'), 1) # ONLY list package if it is used directly by PETSc (and not only by another package) 374 if not isinstance(i.lib, list): 375 i.lib = [i.lib] 376 if i.linkedbypetsc: self.packagelibs.extend(i.lib) 377 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_LIB', self.libraries.toStringNoDupes(i.lib)) 378 if hasattr(i,'include'): 379 if not isinstance(i.include,list): 380 i.include = [i.include] 381 includes.extend(i.include) 382 self.addMakeMacro(i.PACKAGE.replace('-','_')+'_INCLUDE',self.headers.toStringNoDupes(i.include)) 383 if self.framework.argDB['with-single-library']: 384 self.petsclib = '-lpetsc' 385 else: 386 self.petsclib = '-lpetscts -lpetscsnes -lpetscksp -lpetscdm -lpetscmat -lpetscvec -lpetscsys' 387 self.complibs = self.compilers.flibs+self.compilers.cxxlibs+self.compilers.LIBS.split() 388 self.PETSC_WITH_EXTERNAL_LIB = self.libraries.toStringNoDupes(['-L${PETSC_DIR}/${PETSC_ARCH}/lib', self.petsclib]+self.packagelibs+self.complibs) 389 self.PETSC_EXTERNAL_LIB_BASIC = self.libraries.toStringNoDupes(self.packagelibs+self.complibs) 390 391 self.addMakeMacro('PETSC_EXTERNAL_LIB_BASIC',self.PETSC_EXTERNAL_LIB_BASIC) 392 allincludes = petscincludes + includes 393 allincludes_install = petscincludes_install + includes 394 self.PETSC_CC_INCLUDES = self.headers.toStringNoDupes(allincludes) 395 self.PETSC_CC_INCLUDES_INSTALL = self.headers.toStringNoDupes(allincludes_install) 396 self.addMakeMacro('PETSC_CC_INCLUDES',self.PETSC_CC_INCLUDES) 397 self.addMakeMacro('PETSC_CC_INCLUDES_INSTALL', self.PETSC_CC_INCLUDES_INSTALL) 398 if hasattr(self.compilers, 'FC'): 399 def modinc(includes): 400 return includes if self.compilers.fortranIsF90 else [] 401 self.addMakeMacro('PETSC_FC_INCLUDES',self.headers.toStringNoDupes(allincludes,modinc(allincludes))) 402 self.addMakeMacro('PETSC_FC_INCLUDES_INSTALL',self.headers.toStringNoDupes(allincludes_install,modinc(allincludes_install))) 403 404 self.addDefine('LIB_DIR','"'+os.path.join(self.installdir.dir,'lib')+'"') 405 406 if self.framework.argDB['with-single-library']: 407 # overrides the values set in conf/variables 408 self.addMakeMacro('LIBNAME','${INSTALL_LIB_DIR}/libpetsc.${AR_LIB_SUFFIX}') 409 self.addMakeMacro('SHLIBS','libpetsc') 410 self.addMakeMacro('PETSC_LIB_BASIC','-lpetsc') 411 self.addMakeMacro('PETSC_KSP_LIB_BASIC','-lpetsc') 412 self.addMakeMacro('PETSC_TS_LIB_BASIC','-lpetsc') 413 self.addMakeMacro('PETSC_TAO_LIB_BASIC','-lpetsc') 414 self.addMakeMacro('PETSC_WITH_EXTERNAL_LIB',self.PETSC_WITH_EXTERNAL_LIB) 415 self.addDefine('USE_SINGLE_LIBRARY', '1') 416 if self.sharedlibraries.useShared: 417 self.addMakeMacro('PETSC_SYS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 418 self.addMakeMacro('PETSC_VEC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 419 self.addMakeMacro('PETSC_MAT_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 420 self.addMakeMacro('PETSC_DM_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 421 self.addMakeMacro('PETSC_KSP_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 422 self.addMakeMacro('PETSC_SNES_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 423 self.addMakeMacro('PETSC_TS_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 424 self.addMakeMacro('PETSC_TAO_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 425 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 426 self.addMakeMacro('PETSC_LIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 427 self.addMakeMacro('PETSC_CONTRIB','${C_SH_LIB_PATH} ${PETSC_WITH_EXTERNAL_LIB}') 428 else: 429 self.addMakeMacro('PETSC_SYS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 430 self.addMakeMacro('PETSC_VEC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 431 self.addMakeMacro('PETSC_MAT_LIB','${PETSC_WITH_EXTERNAL_LIB}') 432 self.addMakeMacro('PETSC_DM_LIB','${PETSC_WITH_EXTERNAL_LIB}') 433 self.addMakeMacro('PETSC_KSP_LIB','${PETSC_WITH_EXTERNAL_LIB}') 434 self.addMakeMacro('PETSC_SNES_LIB','${PETSC_WITH_EXTERNAL_LIB}') 435 self.addMakeMacro('PETSC_TS_LIB','${PETSC_WITH_EXTERNAL_LIB}') 436 self.addMakeMacro('PETSC_TAO_LIB','${PETSC_WITH_EXTERNAL_LIB}') 437 self.addMakeMacro('PETSC_CHARACTERISTIC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 438 self.addMakeMacro('PETSC_LIB','${PETSC_WITH_EXTERNAL_LIB}') 439 self.addMakeMacro('PETSC_CONTRIB','${PETSC_WITH_EXTERNAL_LIB}') 440 441 if not os.path.exists(os.path.join(self.petscdir.dir,self.arch.arch,'lib')): 442 os.makedirs(os.path.join(self.petscdir.dir,self.arch.arch,'lib')) 443 444# add a makefile endtry for display 445 if self.framework.argDB['with-display']: 446 self.addMakeMacro('DISPLAY',self.framework.argDB['with-display']) 447 448 # add a makefile entry for configure options 449 self.addMakeMacro('CONFIGURE_OPTIONS', self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')) 450 return 451 452 def dumpConfigInfo(self): 453 import time 454 fd = open(os.path.join(self.arch.arch,'include','petscconfiginfo.h'),'w') 455 fd.write('static const char *petscconfigureoptions = "'+self.framework.getOptionsString(['configModules', 'optionsModule']).replace('\"','\\"')+'";\n') 456 fd.close() 457 return 458 459 def dumpMachineInfo(self): 460 import platform 461 import datetime 462 import time 463 import script 464 def escape(s): 465 return s.replace('"',r'\"').replace(r'\ ',r'\\ ') 466 fd = open(os.path.join(self.arch.arch,'include','petscmachineinfo.h'),'w') 467 fd.write('static const char *petscmachineinfo = \"\\n\"\n') 468 fd.write('\"-----------------------------------------\\n\"\n') 469 buildhost = platform.node() 470 if os.environ.get('SOURCE_DATE_EPOCH'): 471 buildhost = "reproducible" 472 buildtime = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) 473 fd.write('\"Libraries compiled on %s on %s \\n\"\n' % (buildtime, buildhost)) 474 fd.write('\"Machine characteristics: %s\\n\"\n' % (platform.platform())) 475 fd.write('\"Using PETSc directory: %s\\n\"\n' % (escape(self.installdir.petscDir))) 476 fd.write('\"Using PETSc arch: %s\\n\"\n' % (escape(self.installdir.petscArch))) 477 fd.write('\"-----------------------------------------\\n\";\n') 478 fd.write('static const char *petsccompilerinfo = \"\\n\"\n') 479 self.setCompilers.pushLanguage(self.languages.clanguage) 480 fd.write('\"Using C compiler: %s %s \\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()))) 481 self.setCompilers.popLanguage() 482 if hasattr(self.compilers, 'FC'): 483 self.setCompilers.pushLanguage('FC') 484 fd.write('\"Using Fortran compiler: %s %s %s\\n\"\n' % (escape(self.setCompilers.getCompiler()), escape(self.setCompilers.getCompilerFlags()), escape(self.setCompilers.CPPFLAGS))) 485 self.setCompilers.popLanguage() 486 fd.write('\"-----------------------------------------\\n\";\n') 487 fd.write('static const char *petsccompilerflagsinfo = \"\\n\"\n') 488 fd.write('\"Using include paths: %s\\n\"\n' % (escape(self.PETSC_CC_INCLUDES_INSTALL.replace('${PETSC_DIR}', self.installdir.petscDir)))) 489 fd.write('\"-----------------------------------------\\n\";\n') 490 fd.write('static const char *petsclinkerinfo = \"\\n\"\n') 491 self.setCompilers.pushLanguage(self.languages.clanguage) 492 fd.write('\"Using C linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 493 self.setCompilers.popLanguage() 494 if hasattr(self.compilers, 'FC'): 495 self.setCompilers.pushLanguage('FC') 496 fd.write('\"Using Fortran linker: %s\\n\"\n' % (escape(self.setCompilers.getLinker()))) 497 self.setCompilers.popLanguage() 498 fd.write('\"Using libraries: %s%s -L%s %s %s\\n\"\n' % (escape(self.setCompilers.CSharedLinkerFlag), escape(os.path.join(self.installdir.petscDir, self.installdir.petscArch, 'lib')), escape(os.path.join(self.installdir.petscDir, self.installdir.petscArch, 'lib')), escape(self.petsclib), escape(self.PETSC_EXTERNAL_LIB_BASIC))) 499 fd.write('\"-----------------------------------------\\n\";\n') 500 fd.close() 501 return 502 503 def configurePrefetch(self): 504 '''Sees if there are any prefetch functions supported''' 505 if config.setCompilers.Configure.isSolaris(self.log) or self.framework.argDB['with-ios'] or not self.framework.argDB['with-prefetch']: 506 self.addDefine('Prefetch(a,b,c)', ' ') 507 return 508 self.pushLanguage(self.languages.clanguage) 509 if self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch((const char*)v,_MM_HINT_NTA);\n'): 510 # The Intel Intrinsics manual [1] specifies the prototype 511 # 512 # void _mm_prefetch(char const *a, int sel); 513 # 514 # but other vendors seem to insist on using subtly different 515 # prototypes, including void* for the pointer, and an enum for 516 # sel. These are both reasonable changes, but negatively impact 517 # portability. 518 # 519 # [1] https://software.intel.com/file/6373 520 self.addDefine('HAVE_XMMINTRIN_H', 1) 521 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const char*)(a),(c))') 522 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 523 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 524 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 525 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 526 elif self.checkLink('#include <xmmintrin.h>', 'void *v = 0;_mm_prefetch(v,_MM_HINT_NTA);\n'): 527 self.addDefine('HAVE_XMMINTRIN_H', 1) 528 self.addDefine('Prefetch(a,b,c)', '_mm_prefetch((const void*)(a),(c))') 529 self.addDefine('PREFETCH_HINT_NTA', '_MM_HINT_NTA') 530 self.addDefine('PREFETCH_HINT_T0', '_MM_HINT_T0') 531 self.addDefine('PREFETCH_HINT_T1', '_MM_HINT_T1') 532 self.addDefine('PREFETCH_HINT_T2', '_MM_HINT_T2') 533 elif self.checkLink('', 'void *v = 0;__builtin_prefetch(v,0,0);\n'): 534 # From GCC docs: void __builtin_prefetch(const void *addr,int rw,int locality) 535 # 536 # The value of rw is a compile-time constant one or zero; one 537 # means that the prefetch is preparing for a write to the memory 538 # address and zero, the default, means that the prefetch is 539 # preparing for a read. The value locality must be a compile-time 540 # constant integer between zero and three. A value of zero means 541 # that the data has no temporal locality, so it need not be left 542 # in the cache after the access. A value of three means that the 543 # data has a high degree of temporal locality and should be left 544 # in all levels of cache possible. Values of one and two mean, 545 # respectively, a low or moderate degree of temporal locality. 546 # 547 # Here we adopt Intel's x86/x86-64 naming scheme for the locality 548 # hints. Using macros for these values in necessary since some 549 # compilers require an enum. 550 self.addDefine('Prefetch(a,b,c)', '__builtin_prefetch((a),(b),(c))') 551 self.addDefine('PREFETCH_HINT_NTA', '0') 552 self.addDefine('PREFETCH_HINT_T0', '3') 553 self.addDefine('PREFETCH_HINT_T1', '2') 554 self.addDefine('PREFETCH_HINT_T2', '1') 555 else: 556 self.addDefine('Prefetch(a,b,c)', ' ') 557 self.popLanguage() 558 559 def configureAtoll(self): 560 '''Checks if atoll exists''' 561 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")'): 562 self.addDefine('HAVE_ATOLL', '1') 563 564 def configureUnused(self): 565 '''Sees if __attribute((unused)) is supported''' 566 if self.framework.argDB['with-ios']: 567 self.addDefine('UNUSED', ' ') 568 return 569 self.pushLanguage(self.languages.clanguage) 570 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'): 571 self.addDefine('UNUSED', '__attribute((unused))') 572 else: 573 self.addDefine('UNUSED', ' ') 574 self.popLanguage() 575 576 def configureIsatty(self): 577 '''Check if the Unix C function isatty() works correctly 578 Actually just assumes it does not work correctly on batch systems''' 579 if not self.framework.argDB['with-batch']: 580 self.addDefine('USE_ISATTY',1) 581 582 def configureDeprecated(self): 583 '''Check if __attribute((deprecated)) is supported''' 584 self.pushLanguage(self.languages.clanguage) 585 ## Recent versions of gcc and clang support __attribute((deprecated("string argument"))), which is very useful, but 586 ## Intel has conspired to make a supremely environment-sensitive compiler. The Intel compiler looks at the gcc 587 ## executable in the environment to determine the language compatibility that it should attempt to emulate. Some 588 ## important Cray installations have built PETSc using the Intel compiler, but with a newer gcc module loaded (e.g., 589 ## 4.7). Thus at PETSc configure time, the Intel compiler decides to support the string argument, but the gcc 590 ## found in the default user environment is older and does not support the argument. If GCC and Intel were cool 591 ## like Clang and supported __has_attribute, we could avoid configure tests entirely, but they don't. And that is 592 ## why we can't have nice things. 593 # 594 # if self.checkCompile("""__attribute((deprecated("Why you shouldn't use myfunc"))) static int myfunc(void) { return 1;}""", ''): 595 # self.addDefine('DEPRECATED_FUNCTION(why)', '__attribute((deprecated(why)))') 596 # self.addDefine('DEPRECATED_TYPEDEF(why)', '__attribute((deprecated(why)))') 597 if self.checkCompile("""__attribute((deprecated)) static int myfunc(void) { return 1;}""", ''): 598 self.addDefine('DEPRECATED_FUNCTION(why)', '__attribute((deprecated))') 599 self.addDefine('DEPRECATED_TYPEDEF(why)', '__attribute((deprecated))') 600 else: 601 self.addDefine('DEPRECATED_FUNCTION(why)', ' ') 602 self.addDefine('DEPRECATED_TYPEDEF(why)', ' ') 603 if self.checkCompile("""enum E {oldval __attribute((deprecated)), newval };""", ''): 604 self.addDefine('DEPRECATED_ENUM(why)', '__attribute((deprecated))') 605 else: 606 self.addDefine('DEPRECATED_ENUM(why)', ' ') 607 # I was unable to make a CPP macro that takes the old and new values as seperate arguments and builds the message needed by _Pragma 608 # hence the deprecation message is handled as it is 609 if self.checkCompile('#define TEST _Pragma("GCC warning \"Testing _Pragma\"") value'): 610 self.addDefine('DEPRECATED_MACRO(why)', '_Pragma(why)') 611 else: 612 self.addDefine('DEPRECATED_MACRO(why)', ' ') 613 self.popLanguage() 614 615 def configureAlign(self): 616 '''Check if __attribute(align) is supported''' 617 filename = 'conftestalign' 618 includes = ''' 619#include <sys/types.h> 620#if STDC_HEADERS 621#include <stdlib.h> 622#include <stdio.h> 623#include <stddef.h> 624#endif\n''' 625 body = ''' 626struct mystruct {int myint;} __attribute((aligned(16))); 627FILE *f = fopen("'''+filename+'''", "w"); 628if (!f) exit(1); 629fprintf(f, "%lu\\n", (unsigned long)sizeof(struct mystruct)); 630''' 631 if 'known-has-attribute-aligned' in self.argDB: 632 if self.argDB['known-has-attribute-aligned']: 633 size = 16 634 else: 635 size = -3 636 elif not self.argDB['with-batch']: 637 self.pushLanguage(self.languages.clanguage) 638 try: 639 if self.checkRun(includes, body) and os.path.exists(filename): 640 f = open(filename) 641 size = int(f.read()) 642 f.close() 643 os.remove(filename) 644 else: 645 size = -4 646 except: 647 size = -1 648 self.framework.logPrint('Error checking attribute(aligned)') 649 self.popLanguage() 650 else: 651 self.framework.addBatchInclude(['#include <stdlib.h>', '#include <stdio.h>', '#include <sys/types.h>','struct mystruct {int myint;} __attribute((aligned(16)));']) 652 self.framework.addBatchBody('fprintf(output, " \'--known-has-attribute-aligned=%d\',\\n", sizeof(struct mystruct)==16);') 653 size = -2 654 if size == 16: 655 self.addDefine('ATTRIBUTEALIGNED(size)', '__attribute((aligned (size)))') 656 self.addDefine('HAVE_ATTRIBUTEALIGNED', 1) 657 else: 658 self.framework.logPrint('incorrect alignment. Found alignment:'+ str(size)) 659 self.addDefine('ATTRIBUTEALIGNED(size)', ' ') 660 return 661 662 def configureExpect(self): 663 '''Sees if the __builtin_expect directive is supported''' 664 self.pushLanguage(self.languages.clanguage) 665 if self.checkLink('', 'if (__builtin_expect(0,1)) return 1;'): 666 self.addDefine('HAVE_BUILTIN_EXPECT', 1) 667 self.popLanguage() 668 669 def configureFunctionName(self): 670 '''Sees if the compiler supports __func__ or a variant.''' 671 def getFunctionName(lang): 672 name = '"unknown"' 673 self.pushLanguage(lang) 674 for fname in ['__func__','__FUNCTION__','__extension__ __func__']: 675 code = "if ("+fname+"[0] != 'm') return 1;" 676 if self.checkCompile('',code) and self.checkLink('',code): 677 name = fname 678 break 679 self.popLanguage() 680 return name 681 langs = [] 682 683 self.addDefine('FUNCTION_NAME_C', getFunctionName('C')) 684 if hasattr(self.compilers, 'CXX'): 685 self.addDefine('FUNCTION_NAME_CXX', getFunctionName('Cxx')) 686 687 def configureIntptrt(self): 688 '''Determine what to use for uintptr_t''' 689 def staticAssertSizeMatchesVoidStar(inc,typename): 690 # The declaration is an error if either array size is negative. 691 # It should be okay to use an int that is too large, but it would be very unlikely for this to be the case 692 return self.checkCompile(inc, ('#define STATIC_ASSERT(cond) char negative_length_if_false[2*(!!(cond))-1]\n' 693 + 'STATIC_ASSERT(sizeof(void*) == sizeof(%s));'%typename)) 694 self.pushLanguage(self.languages.clanguage) 695 if self.checkCompile('#include <stdint.h>', 'int x; uintptr_t i = (uintptr_t)&x;'): 696 self.addDefine('UINTPTR_T', 'uintptr_t') 697 elif staticAssertSizeMatchesVoidStar('','unsigned long long'): 698 self.addDefine('UINTPTR_T', 'unsigned long long') 699 elif staticAssertSizeMatchesVoidStar('#include <stdlib.h>','size_t') or staticAssertSizeMatchesVoidStar('#include <string.h>', 'size_t'): 700 self.addDefine('UINTPTR_T', 'size_t') 701 elif staticAssertSizeMatchesVoidStar('','unsigned long'): 702 self.addDefine('UINTPTR_T', 'unsigned long') 703 elif staticAssertSizeMatchesVoidStar('','unsigned'): 704 self.addDefine('UINTPTR_T', 'unsigned') 705 else: 706 raise RuntimeError('Could not find any unsigned integer type matching void*') 707 self.popLanguage() 708 709 def configureRTLDDefault(self): 710 if self.checkCompile('#include <dlfcn.h>\n void *ptr = RTLD_DEFAULT;'): 711 self.addDefine('RTLD_DEFAULT','1') 712 return 713 714 def configureSolaris(self): 715 '''Solaris specific stuff''' 716 if os.path.isdir(os.path.join('/usr','ucblib')): 717 try: 718 flag = getattr(self.setCompilers, self.language[-1]+'SharedLinkerFlag') 719 except AttributeError: 720 flag = None 721 if flag is None: 722 self.compilers.LIBS += ' -L/usr/ucblib' 723 else: 724 self.compilers.LIBS += ' '+flag+'/usr/ucblib' 725 return 726 727 def configureLinux(self): 728 '''Linux specific stuff''' 729 # TODO: Test for this by mallocing an odd number of floats and checking the address 730 self.addDefine('HAVE_DOUBLE_ALIGN_MALLOC', 1) 731 return 732 733 def configureWin32(self): 734 '''Win32 non-cygwin specific stuff''' 735 kernel32=0 736 if self.libraries.add('Kernel32.lib','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 737 self.addDefine('HAVE_WINDOWS_H',1) 738 self.addDefine('HAVE_GETCOMPUTERNAME',1) 739 kernel32=1 740 elif self.libraries.add('kernel32','GetComputerName',prototype='#include <Windows.h>', call='GetComputerName(NULL,NULL);'): 741 self.addDefine('HAVE_WINDOWS_H',1) 742 self.addDefine('HAVE_GETCOMPUTERNAME',1) 743 kernel32=1 744 if kernel32: 745 if self.framework.argDB['with-windows-graphics']: 746 self.addDefine('USE_WINDOWS_GRAPHICS',1) 747 if self.checkLink('#include <Windows.h>','LoadLibrary(0)'): 748 self.addDefine('HAVE_LOADLIBRARY',1) 749 if self.checkLink('#include <Windows.h>','GetProcAddress(0,0)'): 750 self.addDefine('HAVE_GETPROCADDRESS',1) 751 if self.checkLink('#include <Windows.h>','FreeLibrary(0)'): 752 self.addDefine('HAVE_FREELIBRARY',1) 753 if self.checkLink('#include <Windows.h>','GetLastError()'): 754 self.addDefine('HAVE_GETLASTERROR',1) 755 if self.checkLink('#include <Windows.h>','SetLastError(0)'): 756 self.addDefine('HAVE_SETLASTERROR',1) 757 if self.checkLink('#include <Windows.h>\n','QueryPerformanceCounter(0);\n'): 758 self.addDefine('USE_MICROSOFT_TIME',1) 759 if self.libraries.add('Advapi32.lib','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 760 self.addDefine('HAVE_GET_USER_NAME',1) 761 elif self.libraries.add('advapi32','GetUserName',prototype='#include <Windows.h>', call='GetUserName(NULL,NULL);'): 762 self.addDefine('HAVE_GET_USER_NAME',1) 763 764 if not self.libraries.add('User32.lib','GetDC',prototype='#include <Windows.h>',call='GetDC(0);'): 765 self.libraries.add('user32','GetDC',prototype='#include <Windows.h>',call='GetDC(0);') 766 if not self.libraries.add('Gdi32.lib','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);'): 767 self.libraries.add('gdi32','CreateCompatibleDC',prototype='#include <Windows.h>',call='CreateCompatibleDC(0);') 768 769 self.types.check('int32_t', 'int') 770 if not self.checkCompile('#include <sys/types.h>\n','uid_t u;\n'): 771 self.addTypedef('int', 'uid_t') 772 self.addTypedef('int', 'gid_t') 773 if not self.checkLink('#if defined(PETSC_HAVE_UNISTD_H)\n#include <unistd.h>\n#endif\n','int a=R_OK;\n'): 774 self.framework.addDefine('R_OK', '04') 775 self.framework.addDefine('W_OK', '02') 776 self.framework.addDefine('X_OK', '01') 777 if not self.checkLink('#include <sys/stat.h>\n','int a=0;\nif (S_ISDIR(a)){}\n'): 778 self.framework.addDefine('S_ISREG(a)', '(((a)&_S_IFMT) == _S_IFREG)') 779 self.framework.addDefine('S_ISDIR(a)', '(((a)&_S_IFMT) == _S_IFDIR)') 780 if self.checkCompile('#include <Windows.h>\n','LARGE_INTEGER a;\nDWORD b=a.u.HighPart;\n'): 781 self.addDefine('HAVE_LARGE_INTEGER_U',1) 782 783 # Windows requires a Binary file creation flag when creating/opening binary files. Is a better test in order? 784 if self.checkCompile('#include <Windows.h>\n#include <fcntl.h>\n', 'int flags = O_BINARY;'): 785 self.addDefine('HAVE_O_BINARY',1) 786 787 if self.compilers.CC.find('win32fe') >= 0: 788 self.addDefine('HAVE_WINDOWS_COMPILERS',1) 789 self.addDefine('PATH_SEPARATOR','\';\'') 790 self.addDefine('DIR_SEPARATOR','\'\\\\\'') 791 self.addDefine('REPLACE_DIR_SEPARATOR','\'/\'') 792 self.addDefine('CANNOT_START_DEBUGGER',1) 793 (petscdir,error,status) = self.executeShellCommand('cygpath -w '+self.installdir.petscDir, log = self.log) 794 self.addDefine('DIR','"'+petscdir.replace('\\','\\\\')+'"') 795 (petscdir,error,status) = self.executeShellCommand('cygpath -m '+self.installdir.petscDir, log = self.log) 796 self.addMakeMacro('wPETSC_DIR',petscdir) 797 else: 798 self.addDefine('PATH_SEPARATOR','\':\'') 799 self.addDefine('REPLACE_DIR_SEPARATOR','\'\\\\\'') 800 self.addDefine('DIR_SEPARATOR','\'/\'') 801 self.addDefine('DIR','"'+self.installdir.petscDir+'"') 802 self.addMakeMacro('wPETSC_DIR',self.installdir.petscDir) 803 self.addDefine('ARCH','"'+self.installdir.petscArch+'"') 804 return 805 806#----------------------------------------------------------------------------------------------------- 807 def configureCygwinBrokenPipe(self): 808 '''Cygwin version <= 1.7.18 had issues with pipes and long commands invoked from gnu-make 809 http://cygwin.com/ml/cygwin/2013-05/msg00340.html ''' 810 if config.setCompilers.Configure.isCygwin(self.log): 811 import platform 812 import re 813 r=re.compile("([0-9]+).([0-9]+).([0-9]+)") 814 m=r.match(platform.release()) 815 major=int(m.group(1)) 816 minor=int(m.group(2)) 817 subminor=int(m.group(3)) 818 if ((major < 1) or (major == 1 and minor < 7) or (major == 1 and minor == 7 and subminor <= 18)): 819 self.addMakeMacro('PETSC_CYGWIN_BROKEN_PIPE','1') 820 return 821 822#----------------------------------------------------------------------------------------------------- 823 def configureDefaultArch(self): 824 conffile = os.path.join('lib','petsc','conf', 'petscvariables') 825 if self.framework.argDB['with-default-arch']: 826 fd = open(conffile, 'w') 827 fd.write('PETSC_ARCH='+self.arch.arch+'\n') 828 fd.write('PETSC_DIR='+self.petscdir.dir+'\n') 829 fd.write('include '+os.path.join('$(PETSC_DIR)','$(PETSC_ARCH)','lib','petsc','conf','petscvariables')+'\n') 830 fd.close() 831 self.framework.actions.addArgument('PETSc', 'Build', 'Set default architecture to '+self.arch.arch+' in '+conffile) 832 elif os.path.isfile(conffile): 833 try: 834 os.unlink(conffile) 835 except: 836 raise RuntimeError('Unable to remove file '+conffile+'. Did a different user create it?') 837 return 838 839#----------------------------------------------------------------------------------------------------- 840 def configureScript(self): 841 '''Output a script in the conf directory which will reproduce the configuration''' 842 import nargs 843 import sys 844 scriptName = os.path.join(self.arch.arch,'lib','petsc','conf', 'reconfigure-'+self.arch.arch+'.py') 845 args = dict([(nargs.Arg.parseArgument(arg)[0], arg) for arg in self.framework.clArgs]) 846 if 'with-clean' in args: 847 del args['with-clean'] 848 if 'configModules' in args: 849 if nargs.Arg.parseArgument(args['configModules'])[1] == 'PETSc.Configure': 850 del args['configModules'] 851 if 'optionsModule' in args: 852 if nargs.Arg.parseArgument(args['optionsModule'])[1] == 'config.compilerOptions': 853 del args['optionsModule'] 854 if not 'PETSC_ARCH' in args: 855 args['PETSC_ARCH'] = 'PETSC_ARCH='+str(self.arch.arch) 856 f = open(scriptName, 'w') 857 f.write('#!'+sys.executable+'\n') 858 f.write('if __name__ == \'__main__\':\n') 859 f.write(' import sys\n') 860 f.write(' import os\n') 861 f.write(' sys.path.insert(0, os.path.abspath(\'config\'))\n') 862 f.write(' import configure\n') 863 # pretty print repr(args.values()) 864 f.write(' configure_options = [\n') 865 for itm in sorted(args.values()): 866 f.write(' \''+str(itm)+'\',\n') 867 f.write(' ]\n') 868 f.write(' configure.petsc_configure(configure_options)\n') 869 f.close() 870 try: 871 os.chmod(scriptName, 0o775) 872 except OSError as e: 873 self.framework.logPrint('Unable to make reconfigure script executable:\n'+str(e)) 874 self.framework.actions.addArgument('PETSc', 'File creation', 'Created '+scriptName+' for automatic reconfiguration') 875 return 876 877 def configureInstall(self): 878 '''Setup the directories for installation''' 879 if self.framework.argDB['prefix']: 880 self.addMakeRule('print_mesg_after_build','',['-@echo "Now to install the libraries do:"',\ 881 '-@echo "'+self.installdir.installSudo+'make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} install"',\ 882 '-@echo "========================================="']) 883 else: 884 self.addMakeRule('print_mesg_after_build','',['-@echo "Now to check if the libraries are working do:"',\ 885 '-@echo "make PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} check"',\ 886 '-@echo "========================================="']) 887 return 888 889 def configureGCOV(self): 890 if self.framework.argDB['with-gcov']: 891 self.addDefine('USE_GCOV','1') 892 return 893 894 def postProcessPackages(self): 895 postPackages=[] 896 for i in self.framework.packages: 897 if hasattr(i,'postProcess'): postPackages.append(i) 898 if postPackages: 899 # ctetgen needs petsc conf files. so attempt to create them early 900 self.framework.dumpConfFiles() 901 # tacky fix for dependency of Aluimia on Pflotran; requested via petsc-dev Matt provide a correct fix 902 for i in postPackages: 903 if i.name.upper() in ['PFLOTRAN']: 904 i.postProcess() 905 postPackages.remove(i) 906 for i in postPackages: i.postProcess() 907 for i in postPackages: 908 if i.installedpetsc: 909 self.installed = 1 910 break 911 return 912 913 def configure(self): 914 if not os.path.samefile(self.petscdir.dir, os.getcwd()): 915 raise RuntimeError('Wrong PETSC_DIR option specified: '+str(self.petscdir.dir) + '\n Configure invoked in: '+os.path.realpath(os.getcwd())) 916 if self.framework.argDB['prefix'] and os.path.isdir(self.framework.argDB['prefix']) and os.path.samefile(self.framework.argDB['prefix'],self.petscdir.dir): 917 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR!') 918 if self.framework.argDB['prefix'] and self.framework.argDB['prefix'].find(' ') > -1: 919 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') 920 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)): 921 raise RuntimeError('Incorrect option --prefix='+self.framework.argDB['prefix']+' specified. It cannot be same as PETSC_DIR/PETSC_ARCH!') 922 self.framework.header = os.path.join(self.arch.arch,'include','petscconf.h') 923 self.framework.cHeader = os.path.join(self.arch.arch,'include','petscfix.h') 924 self.framework.makeMacroHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscvariables') 925 self.framework.makeRuleHeader = os.path.join(self.arch.arch,'lib','petsc','conf','petscrules') 926 if self.libraries.math is None: 927 raise RuntimeError('PETSc requires a functional math library. Please send configure.log to petsc-maint@mcs.anl.gov.') 928 if self.languages.clanguage == 'Cxx' and not hasattr(self.compilers, 'CXX'): 929 raise RuntimeError('Cannot set C language to C++ without a functional C++ compiler.') 930 self.executeTest(self.configureRTLDDefault) 931 self.executeTest(self.configurePrefetch) 932 self.executeTest(self.configureUnused) 933 self.executeTest(self.configureDeprecated) 934 self.executeTest(self.configureIsatty) 935 self.executeTest(self.configureExpect); 936 self.executeTest(self.configureAlign); 937 self.executeTest(self.configureFunctionName); 938 self.executeTest(self.configureIntptrt); 939 self.executeTest(self.configureSolaris) 940 self.executeTest(self.configureLinux) 941 self.executeTest(self.configureWin32) 942 self.executeTest(self.configureCygwinBrokenPipe) 943 self.executeTest(self.configureDefaultArch) 944 self.executeTest(self.configureScript) 945 self.executeTest(self.configureInstall) 946 self.executeTest(self.configureGCOV) 947 self.executeTest(self.configureAtoll) 948 949 self.Dump() 950 self.dumpConfigInfo() 951 self.dumpMachineInfo() 952 # need to save the current state of BuildSystem so that postProcess() packages can read it in and perhaps run make install 953 self.framework.storeSubstitutions(self.framework.argDB) 954 self.framework.argDB['configureCache'] = pickle.dumps(self.framework) 955 self.framework.argDB.save(force = True) 956 self.DumpPkgconfig() 957 self.DumpModule() 958 self.postProcessPackages() 959 self.framework.log.write('================================================================================\n') 960 self.logClear() 961 return 962