PageRenderTime 83ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/config/PETSc/Configure.py

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