diff --git a/easybuild/easyblocks/b/boost.py b/easybuild/easyblocks/b/boost.py index fa684f1575..aa163b8d95 100644 --- a/easybuild/easyblocks/b/boost.py +++ b/easybuild/easyblocks/b/boost.py @@ -49,7 +49,8 @@ from easybuild.framework.easyblock import EasyBlock from easybuild.framework.easyconfig import CUSTOM from easybuild.tools.build_log import EasyBuildError -from easybuild.tools.filetools import copy, mkdir, write_file +from easybuild.tools.config import ERROR +from easybuild.tools.filetools import apply_regex_substitutions, copy, mkdir, which, write_file from easybuild.tools.modules import get_software_root, get_software_version from easybuild.tools.run import run_cmd from easybuild.tools.systemtools import AARCH64, POWER, UNKNOWN @@ -78,7 +79,9 @@ def extra_options(): extra_vars = { 'boost_mpi': [False, "Build mpi boost module", CUSTOM], 'boost_multi_thread': [False, "Build boost with multi-thread option", CUSTOM], - 'toolset': [None, "Toolset to use for Boost configuration ('--with-toolset for bootstrap.sh')", CUSTOM], + 'toolset': [None, "Toolset to use for Boost configuration ('--with-toolset' for bootstrap.sh)", CUSTOM], + 'build_toolset': [None, "Toolset to use for Boost compilation " + "('toolset' for b2, default calculated from toolset)", CUSTOM], 'mpi_launcher': [None, "Launcher to use when running MPI regression tests", CUSTOM], 'only_python_bindings': [False, "Only install Boost.Python library providing Python bindings", CUSTOM], 'use_glibcxx11_abi': [None, "Use the GLIBCXX11 ABI", CUSTOM], @@ -139,6 +142,20 @@ def configure_step(self): tup = (self.cfg['preconfigopts'], toolset, self.objdir, self.cfg['configopts']) run_cmd(cmd % tup, log_all=True, simple=True) + # Use build_toolset if specified or the bootstrap toolset without the OS suffix + self.toolset = self.cfg['build_toolset'] or re.sub('-linux$', '', toolset) + + user_config = [] + + # Explicitely set the compiler path to avoid B2 checking some standard paths like /opt + cxx = os.getenv('CXX') + if cxx: + cxx = which(cxx, on_error=ERROR) + # Remove default toolset config which may lead to duplicate toolsets (e.g. for intel-linux) + apply_regex_substitutions('project-config.jam', [('using %s ;' % toolset, '')]) + # Add our toolset config with no version and full path to compiler + user_config.append("using %s : : %s ;" % (self.toolset, cxx)) + if self.cfg['boost_mpi']: self.toolchain.options['usempi'] = True @@ -146,13 +163,17 @@ def configure_step(self): # http://www.boost.org/doc/libs/1_47_0/doc/html/mpi/getting_started.html # let Boost.Build know to look here for the config file - txt = '' # Check if using a Cray toolchain and configure MPI accordingly if self.toolchain.toolchain_family() == toolchain.CRAYPE: if self.toolchain.PRGENV_MODULE_NAME_SUFFIX == 'gnu': craympichdir = os.getenv('CRAY_MPICH2_DIR') craygccversion = os.getenv('GCC_VERSION') - txt = '\n'.join([ + # We configure the gcc toolchain below, so make sure the EC doesn't use another toolset + if self.toolset != 'gcc': + raise EasyBuildError("For the cray toolchain the 'gcc' toolset must be used.") + # Remove the previous "using gcc" line add above (via self.toolset) if present + user_config = [x for x in user_config if not x.startswith('using gcc :')] + user_config.extend([ 'local CRAY_MPICH2_DIR = %s ;' % craympichdir, 'using gcc ', ': %s' % craygccversion, @@ -170,9 +191,9 @@ def configure_step(self): else: raise EasyBuildError("Bailing out: only PrgEnv-gnu supported for now") else: - txt = "using mpi : %s ;" % os.getenv("MPICXX") + user_config.append("using mpi : %s ;" % os.getenv("MPICXX")) - write_file('user-config.jam', txt, append=True) + write_file('user-config.jam', '\n'.join(user_config), append=True) def build_boost_variant(self, bjamoptions, paracmd): """Build Boost library with specified options for bjam.""" @@ -184,12 +205,14 @@ def build_boost_variant(self, bjamoptions, paracmd): self.cfg['preinstallopts'], self.bjamcmd, bjamoptions, paracmd, self.cfg['installopts']) run_cmd(cmd, log_all=True, simple=True) # clean up before proceeding with next build - run_cmd("./%s --clean-all" % self.bjamcmd, log_all=True, simple=True) + run_cmd("./%s %s --clean-all" % (self.bjamcmd, bjamoptions), log_all=True, simple=True) def build_step(self): """Build Boost with bjam tool.""" - bjamoptions = " --prefix=%s" % self.objdir + bjamoptions = " --prefix=%s --user-config=user-config.jam" % self.objdir + if 'toolset=' not in self.cfg['buildopts']: + bjamoptions += " toolset=" + self.toolset cxxflags = os.getenv('CXXFLAGS') # only disable -D_GLIBCXX_USE_CXX11_ABI if use_glibcxx11_abi was explicitly set to False @@ -224,7 +247,7 @@ def build_step(self): if self.cfg['boost_mpi']: self.log.info("Building boost_mpi library") - self.build_boost_variant(bjamoptions + " --user-config=user-config.jam --with-mpi", paracmd) + self.build_boost_variant(bjamoptions + " --with-mpi", paracmd) if self.cfg['boost_multi_thread']: self.log.info("Building boost with multi threading") @@ -233,7 +256,7 @@ def build_step(self): # if both boost_mpi and boost_multi_thread are enabled, build boost mpi with multi-thread support if self.cfg['boost_multi_thread'] and self.cfg['boost_mpi']: self.log.info("Building boost_mpi with multi threading") - extra_bjamoptions = " --user-config=user-config.jam --with-mpi threading=multi --layout=tagged" + extra_bjamoptions = " --with-mpi threading=multi --layout=tagged" self.build_boost_variant(bjamoptions + extra_bjamoptions, paracmd) # install remainder of boost libraries