diff --git a/easybuild/framework/easyblock.py b/easybuild/framework/easyblock.py index 8425125808..e2bcb78264 100644 --- a/easybuild/framework/easyblock.py +++ b/easybuild/framework/easyblock.py @@ -1537,13 +1537,6 @@ def check_readiness_step(self): if len(loadedmods) > 0: self.log.warning("Loaded modules detected: %s" % loadedmods) - # do all dependencies have a toolchain version? - self.toolchain.add_dependencies(self.cfg.dependencies()) - if not len(self.cfg.dependencies()) == len(self.toolchain.dependencies): - self.log.debug("dep %s (%s)" % (len(self.cfg.dependencies()), self.cfg.dependencies())) - self.log.debug("tc.dep %s (%s)" % (len(self.toolchain.dependencies), self.toolchain.dependencies)) - raise EasyBuildError('Not all dependencies have a matching toolchain version') - # check if the application is not loaded at the moment (root, env_var) = get_software_root(self.name, with_env_var=True) if root: @@ -1832,8 +1825,8 @@ def prepare_step(self, start_dir=True): self.rpath_include_dirs.append('$ORIGIN/../lib64') # prepare toolchain: load toolchain module and dependencies, set up build environment - self.toolchain.prepare(self.cfg['onlytcmod'], silent=self.silent, rpath_filter_dirs=self.rpath_filter_dirs, - rpath_include_dirs=self.rpath_include_dirs) + self.toolchain.prepare(self.cfg['onlytcmod'], deps=self.cfg.dependencies(), silent=self.silent, + rpath_filter_dirs=self.rpath_filter_dirs, rpath_include_dirs=self.rpath_include_dirs) # keep track of environment variables that were tweaked and need to be restored after environment got reset # $TMPDIR may be tweaked for OpenMPI 2.x, which doesn't like long $TMPDIR paths... diff --git a/easybuild/tools/toolchain/toolchain.py b/easybuild/tools/toolchain/toolchain.py index 19adb0342c..fd036e7e65 100644 --- a/easybuild/tools/toolchain/toolchain.py +++ b/easybuild/tools/toolchain/toolchain.py @@ -385,9 +385,9 @@ def get_dependency_version(self, dependency): raise EasyBuildError("No toolchain version for dependency name %s (suffix %s) found", dependency['name'], toolchain_suffix) - def add_dependencies(self, dependencies): - """ Verify if the given dependencies exist and add them """ - self.log.debug("add_dependencies: adding toolchain dependencies %s", dependencies) + def _check_dependencies(self, dependencies): + """ Verify if the given dependencies exist and return them """ + self.log.debug("_check_dependencies: adding toolchain dependencies %s", dependencies) # use *full* module name to check existence of dependencies, since the modules may not be available in the # current $MODULEPATH without loading the prior dependencies in a module hierarchy @@ -397,23 +397,36 @@ def add_dependencies(self, dependencies): dep_mod_names = [dep['full_mod_name'] for dep in dependencies] # check whether modules exist - self.log.debug("add_dependencies: MODULEPATH: %s", os.environ['MODULEPATH']) + self.log.debug("_check_dependencies: MODULEPATH: %s", os.environ['MODULEPATH']) if self.dry_run: deps_exist = [True] * len(dep_mod_names) else: deps_exist = self.modules_tool.exist(dep_mod_names) missing_dep_mods = [] + deps = [] for dep, dep_mod_name, dep_exists in zip(dependencies, dep_mod_names, deps_exist): if dep_exists: - self.dependencies.append(dep) - self.log.devel("add_dependencies: added toolchain dependency %s", str(dep)) + deps.append(dep) + self.log.devel("_check_dependencies: added toolchain dependency %s", str(dep)) else: missing_dep_mods.append(dep_mod_name) if missing_dep_mods: raise EasyBuildError("Missing modules for one or more dependencies: %s", ', '.join(missing_dep_mods)) + return deps + + def add_dependencies(self, dependencies): + """ + [DEPRECATED] Verify if the given dependencies exist, and return them. + + This method is deprecated. + You should pass the dependencies to the 'prepare' method instead, via the 'deps' named argument. + """ + self.log.deprecated("use of 'Toolchain.add_dependencies' method", '4.0') + self.dependencies = self._check_dependencies(dependencies) + def is_required(self, name): """Determine whether this is a required toolchain element.""" # default: assume every element is required @@ -674,12 +687,14 @@ def is_deprecated(self): """Return whether or not this toolchain is deprecated.""" return False - def prepare(self, onlymod=None, silent=False, loadmod=True, rpath_filter_dirs=None, rpath_include_dirs=None): + def prepare(self, onlymod=None, deps=None, silent=False, loadmod=True, + rpath_filter_dirs=None, rpath_include_dirs=None): """ Prepare a set of environment parameters based on name/version of toolchain - load modules for toolchain and dependencies - generate extra variables and set them in the environment + :param deps: list of dependencies :param onlymod: boolean/string to indicate if the toolchain should only load the environment with module (True) or also set all other variables (False) like compiler CC etc (If string: comma separated list of variables that will be ignored). @@ -688,6 +703,16 @@ def prepare(self, onlymod=None, silent=False, loadmod=True, rpath_filter_dirs=No :param rpath_filter_dirs: extra directories to include in RPATH filter (e.g. build dir, tmpdir, ...) :param rpath_include_dirs: extra directories to include in RPATH """ + + # do all dependencies have a toolchain version? + if deps is None: + deps = [] + self.dependencies = self._check_dependencies(deps) + if not len(deps) == len(self.dependencies): + self.log.debug("dep %s (%s)" % (len(deps), deps)) + self.log.debug("tc.dep %s (%s)" % (len(self.dependencies), self.dependencies)) + raise EasyBuildError('Not all dependencies have a matching toolchain version') + if loadmod: self._load_modules(silent=silent) diff --git a/test/framework/easyblock.py b/test/framework/easyblock.py index 91558326f2..64b5257c98 100644 --- a/test/framework/easyblock.py +++ b/test/framework/easyblock.py @@ -473,6 +473,8 @@ def test_make_module_dep(self): eb.installdir = os.path.join(config.install_path(), 'pi', '3.14') eb.check_readiness_step() + eb.make_builddir() + eb.prepare_step() if get_module_syntax() == 'Tcl': tc_load = '\n'.join([ @@ -717,6 +719,8 @@ def test_make_module_step(self): eb = EasyBlock(ec) eb.installdir = os.path.join(config.install_path(), 'pi', '3.14') eb.check_readiness_step() + eb.make_builddir() + eb.prepare_step() modpath = os.path.join(eb.make_module_step(), name, version) if get_module_syntax() == 'Lua': diff --git a/test/framework/easyconfig.py b/test/framework/easyconfig.py index e942ac4272..e5a00fa207 100644 --- a/test/framework/easyconfig.py +++ b/test/framework/easyconfig.py @@ -1347,8 +1347,7 @@ def test_external_dependencies(self): os.environ['PI_PREFIX'] = '/test/prefix/PI' os.environ['TEST_INC'] = '/test/prefix/test/include' ec.toolchain.dry_run = True - ec.toolchain.add_dependencies(ec.dependencies()) - ec.toolchain.prepare(silent=True) + ec.toolchain.prepare(deps=ec.dependencies(), silent=True) self.assertEqual(os.environ.get('EBROOTBAR'), '/foo/bar') self.assertEqual(os.environ.get('EBROOTFOO'), '/foo/bar') diff --git a/test/framework/toolchain.py b/test/framework/toolchain.py index 8115007a7e..0eb595b490 100644 --- a/test/framework/toolchain.py +++ b/test/framework/toolchain.py @@ -796,8 +796,7 @@ def test_prepare_deps(self): 'build_only': False, }, ] - tc.add_dependencies(deps) - tc.prepare() + tc.prepare(deps=deps) mods = ['GCC/6.4.0-2.28', 'hwloc/1.11.8-GCC-6.4.0-2.28', 'OpenMPI/2.1.2-GCC-6.4.0-2.28'] self.assertTrue([m['mod_name'] for m in self.modtool.list()], mods) @@ -825,8 +824,7 @@ def test_prepare_deps_external(self): } ] tc = self.get_toolchain('GCC', version='6.4.0-2.28') - tc.add_dependencies(deps) - tc.prepare() + tc.prepare(deps=deps) mods = ['GCC/6.4.0-2.28', 'hwloc/1.11.8-GCC-6.4.0-2.28', 'OpenMPI/2.1.2-GCC-6.4.0-2.28', 'toy/0.0'] self.assertTrue([m['mod_name'] for m in self.modtool.list()], mods) self.assertTrue(os.environ['EBROOTTOY'].endswith('software/toy/0.0')) @@ -846,9 +844,8 @@ def test_prepare_deps_external(self): 'build_only': False, } tc = self.get_toolchain('GCC', version='6.4.0-2.28') - tc.add_dependencies(deps) os.environ['FOOBAR_PREFIX'] = '/foo/bar' - tc.prepare() + tc.prepare(deps=deps) mods = ['GCC/6.4.0-2.28', 'hwloc/1.11.8-GCC-6.4.0-2.28', 'OpenMPI/2.1.2-GCC-6.4.0-2.28', 'toy/0.0'] self.assertTrue([m['mod_name'] for m in self.modtool.list()], mods) self.assertEqual(os.environ['EBROOTTOY'], '/foo/bar')