xref: /petsc/config/BuildSystem/config/packages/boost.py (revision b78ea06ca2360cbc3704cad5b3ce835b2b1ccf4f)
1from __future__ import generators
2import config.package
3import sysconfig
4from pathlib import Path
5
6class Configure(config.package.Package):
7  def __init__(self, framework):
8    config.package.Package.__init__(self, framework)
9    self.version           = '1.89.0'
10    self.download          = ['https://archives.boost.io/release/'+self.version+'/source/boost_'+self.version.replace('.','_')+'.tar.bz2',
11                              'https://web.cels.anl.gov/projects/petsc/download/externalpackages/boost_'+self.version.replace('.','_')+'.tar.bz2']
12    self.includes          = ['boost/multi_index_container.hpp']
13    self.liblist           = []
14    self.buildLanguages    = ['Cxx']
15    self.downloadonWindows = 1
16    self.useddirectly      = 0
17
18  def setupHelp(self, help):
19    import nargs
20    config.package.Package.setupHelp(self, help)
21    help.addArgument('BOOST', '-download-boost-headers-only=<bool>', nargs.ArgBool(None, 0, 'When true, do not build Boost libraries, only install headers'))
22    help.addArgument('BOOST', '-download-boost-bootstrap-arguments=<string>', nargs.ArgString(None, 0, 'Additional arguments for bootstrap of Boost build'))
23
24  def Install(self):
25    conffile = Path(self.packageDir) / (self.package + '.petscconf')
26    conffile.write_text(self.installDir)
27
28    if not self.installNeeded(str(conffile)):
29      return self.installDir
30
31    if self.argDB['download-boost-headers-only']:
32      boostIncludeDir = Path(self.installDir) / self.includedir / 'boost'
33      self.logPrintBox('Configure option --boost-headers-only is ENABLED ... boost libraries will not be built')
34      self.logPrintBox('Installing boost headers, this should not take long')
35      try:
36        if boostIncludeDir.exists() or boostIncludeDir.is_symlink():
37          boostIncludeDir.unlink()
38        cmd = 'cd {} && ln -s $PWD/boost {}'.format(self.packageDir, boostIncludeDir)
39        config.base.Configure.executeShellCommand(cmd, timeout=6000, log=self.log)
40      except RuntimeError as e:
41        raise RuntimeError('Error linking Boost headers:\n'+str(e))
42    else:
43      if not self.checkCompile('#include <bzlib.h>', ''):
44        raise RuntimeError('Boost requires bzlib.h. Please install it in default compiler search location.')
45
46      if not (Path(sysconfig.get_paths()['include']) / 'pyconfig.h').is_file():
47        raise RuntimeError('pyconfig.h missing: Boost requires python development version to be installed. (pythonX.x-dev)')
48
49      with self.Language('Cxx'):
50        cxx = self.getCompiler()
51        cxxflags = self.getCompilerFlags()
52
53      if config.setCompilers.Configure.isGNU(cxx, self.log):
54        toolset = 'gcc'
55        pch = 'on'
56      elif config.setCompilers.Configure.isOneAPI(cxx, self.log) or config.setCompilers.Configure.isIntel(cxx, self.log):
57        toolset = 'intel-linux'
58        pch = 'off' # https://github.com/bfgroup/b2/issues/413
59      elif config.setCompilers.Configure.isClang(cxx, self.log):
60        toolset='clang'
61        pch='on'
62      else:
63        raise RuntimeError('Invalid CXX compiler specifield for boost: {}'.format(cxx))
64
65      self.logPrintBox('Building Boost with toolset "{}", compiler "{}"'.format(toolset, cxx))
66
67      jamfile = Path(self.packageDir) / 'user-config.jam'
68      jamfile.write_text('using {} : : {} : <cxxflags>"{}" ;\n'.format(toolset, cxx, cxxflags))
69
70      if 'download-boost-bootstrap-arguments' in self.argDB and self.argDB['download-boost-bootstrap-arguments']:
71        bootstrap_arguments = self.argDB['download-boost-bootstrap-arguments']
72      else:
73        bootstrap_arguments = ''
74
75      bootstrap_cmd = 'cd {} && ./bootstrap.sh --with-toolset={} --prefix={}'.format(self.packageDir, toolset, self.installDir)
76      out, err, ret = config.base.Configure.executeShellCommand(bootstrap_cmd, timeout=6000, log=self.log)
77
78      build_cmd = 'cd {} && ./b2 toolset={} {} pch={} -j{}'.format(self.packageDir, toolset, bootstrap_arguments, pch, self.make.make_np)
79      out, err, ret = config.base.Configure.executeShellCommand(build_cmd, timeout=6000, log=self.log)
80
81      install_cmd = 'cd {} && ./b2 toolset={} {} pch={} -j{} install'.format(self.packageDir, toolset, bootstrap_arguments, pch, self.make.make_np)
82      out, err, ret = config.base.Configure.executeShellCommand(install_cmd, timeout=6000, log=self.log)
83
84      self.postInstall(out + err, str(conffile))
85    return self.installDir
86