diff options
author | Peter Scheibel <scheibel1@llnl.gov> | 2021-06-24 16:13:46 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-24 16:13:46 -0700 |
commit | 916cdfbb56b2abfc380ce1b4cac0d6494b7f2628 (patch) | |
tree | 68f2417af733227274d4a228c30509fbea1462e9 | |
parent | d7405ddd3908f328d052d1de7520620924825b7b (diff) | |
download | spack-916cdfbb56b2abfc380ce1b4cac0d6494b7f2628.tar.gz spack-916cdfbb56b2abfc380ce1b4cac0d6494b7f2628.tar.bz2 spack-916cdfbb56b2abfc380ce1b4cac0d6494b7f2628.tar.xz spack-916cdfbb56b2abfc380ce1b4cac0d6494b7f2628.zip |
Environment modifications: de-prioritize external packages (#23824)
Prior to any Spack build, Spack modifies PATH etc. to help the build
find the dependencies it needs. It also allows any package to define
custom environment modifications (and furthermore a package can
specify environment modifications to apply when it is used as a
dependency). If an external package defines custom environment
modifications that alter PATH, and the external package is in a merged
or system prefix, then that prefix could "override" the Spack-built
packages.
This commit reorders environment modifications so that PrependPath
actions which expose Spack-built packages override PrependPath actions
for custom environment modifications of external packages.
In more detail, the original order of environment modifications is:
* Modules
* Compiler flag variables
* PATH, CMAKE_PREFIX_PATH, and PKG_CONFIG_PATH for dependencies
* Custom package.py modifications in the following order:
* dependencies
* root
This commit changes the order:
* Modules
* Compiler flag variables
* For each external dependency
* PATH, CMAKE_PREFIX_PATH, and PKG_CONFIG_PATH modifications
* Custom modifications
* For each Spack-built dependency
* PATH, CMAKE_PREFIX_PATH, and PKG_CONFIG_PATH modifications
* Custom modifications
-rw-r--r-- | lib/spack/spack/build_environment.py | 410 | ||||
-rw-r--r-- | lib/spack/spack/test/build_environment.py | 10 | ||||
-rw-r--r-- | lib/spack/spack/util/environment.py | 19 | ||||
-rw-r--r-- | lib/spack/spack/util/module_cmd.py | 1 |
4 files changed, 270 insertions, 170 deletions
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py index 70571570a9..a79a678825 100644 --- a/lib/spack/spack/build_environment.py +++ b/lib/spack/spack/build_environment.py @@ -78,7 +78,7 @@ SPACK_NO_PARALLEL_MAKE = 'SPACK_NO_PARALLEL_MAKE' # # These environment variables are set by -# set_build_environment_variables and used to pass parameters to +# set_wrapper_variables and used to pass parameters to # Spack's compiler wrappers. # SPACK_ENV_PATH = 'SPACK_ENV_PATH' @@ -159,6 +159,8 @@ def clean_environment(): env.unset('CPLUS_INCLUDE_PATH') env.unset('OBJC_INCLUDE_PATH') + env.unset('CMAKE_PREFIX_PATH') + # Avoid that libraries of build dependencies get hijacked. env.unset('LD_PRELOAD') env.unset('DYLD_INSERT_LIBRARIES') @@ -310,111 +312,20 @@ def set_compiler_environment_variables(pkg, env): return env -def _place_externals_last(spec_container): - """ - For a (possibly unordered) container of specs, return an ordered list - where all external specs are at the end of the list. External packages - may be installed in merged prefixes with other packages, and so - they should be deprioritized for any search order (i.e. in PATH, or - for a set of -L entries in a compiler invocation). - """ - # Establish an arbitrary but fixed ordering of specs so that resulting - # environment variable values are stable - spec_container = sorted(spec_container, key=lambda x: x.name) - first = list(x for x in spec_container if not x.external) - second = list(x for x in spec_container if x.external) - return first + second - +def set_wrapper_variables(pkg, env): + """Set environment variables used by the Spack compiler wrapper + (which have the prefix `SPACK_`) and also add the compiler wrappers + to PATH. -def set_build_environment_variables(pkg, env, dirty): - """Ensure a clean install environment when we build packages. - - This involves unsetting pesky environment variables that may - affect the build. It also involves setting environment variables - used by Spack's compiler wrappers. - - Args: - pkg: The package we are building - env: The build environment - dirty (bool): Skip unsetting the user's environment settings + This determines the injected -L/-I/-rpath options; each + of these specifies a search order and this function computes these + options in a manner that is intended to match the DAG traversal order + in `modifications_from_dependencies`: that method uses a post-order + traversal so that `PrependPath` actions from dependencies take lower + precedence; we use a post-order traversal here to match the visitation + order of `modifications_from_dependencies` (so we are visiting the + lowest priority packages first). """ - # Gather information about various types of dependencies - build_deps = set(pkg.spec.dependencies(deptype=('build', 'test'))) - link_deps = set(pkg.spec.traverse(root=False, deptype=('link'))) - build_link_deps = build_deps | link_deps - rpath_deps = get_rpath_deps(pkg) - # This includes all build dependencies and any other dependencies that - # should be added to PATH (e.g. supporting executables run by build - # dependencies) - build_and_supporting_deps = set() - for build_dep in build_deps: - build_and_supporting_deps.update(build_dep.traverse(deptype='run')) - - # External packages may be installed in a prefix which contains many other - # package installs. To avoid having those installations override - # Spack-installed packages, they are placed at the end of search paths. - # System prefixes are removed entirely later on since they are already - # searched. - build_deps = _place_externals_last(build_deps) - link_deps = _place_externals_last(link_deps) - build_link_deps = _place_externals_last(build_link_deps) - rpath_deps = _place_externals_last(rpath_deps) - build_and_supporting_deps = _place_externals_last( - build_and_supporting_deps) - - link_dirs = [] - include_dirs = [] - rpath_dirs = [] - - # The top-level package is always RPATHed. It hasn't been installed yet - # so the RPATHs are added unconditionally (e.g. even though lib64/ may - # not be created for the install). - for libdir in ['lib', 'lib64']: - lib_path = os.path.join(pkg.prefix, libdir) - rpath_dirs.append(lib_path) - - # Set up link, include, RPATH directories that are passed to the - # compiler wrapper - for dep in link_deps: - if is_system_path(dep.prefix): - continue - query = pkg.spec[dep.name] - dep_link_dirs = list() - try: - dep_link_dirs.extend(query.libs.directories) - except NoLibrariesError: - tty.debug("No libraries found for {0}".format(dep.name)) - - for default_lib_dir in ['lib', 'lib64']: - default_lib_prefix = os.path.join(dep.prefix, default_lib_dir) - if os.path.isdir(default_lib_prefix): - dep_link_dirs.append(default_lib_prefix) - - link_dirs.extend(dep_link_dirs) - if dep in rpath_deps: - rpath_dirs.extend(dep_link_dirs) - - try: - include_dirs.extend(query.headers.directories) - except NoHeadersError: - tty.debug("No headers found for {0}".format(dep.name)) - - link_dirs = list(dedupe(filter_system_paths(link_dirs))) - include_dirs = list(dedupe(filter_system_paths(include_dirs))) - rpath_dirs = list(dedupe(filter_system_paths(rpath_dirs))) - - env.set(SPACK_LINK_DIRS, ':'.join(link_dirs)) - env.set(SPACK_INCLUDE_DIRS, ':'.join(include_dirs)) - env.set(SPACK_RPATH_DIRS, ':'.join(rpath_dirs)) - - build_and_supporting_prefixes = filter_system_paths( - x.prefix for x in build_and_supporting_deps) - build_link_prefixes = filter_system_paths( - x.prefix for x in build_link_deps) - - # Add dependencies to CMAKE_PREFIX_PATH - env.set_path('CMAKE_PREFIX_PATH', get_cmake_prefix_path(pkg)) - # Set environment variables if specified for # the given compiler compiler = pkg.compiler @@ -424,16 +335,6 @@ def set_build_environment_variables(pkg, env, dirty): extra_rpaths = ':'.join(compiler.extra_rpaths) env.set('SPACK_COMPILER_EXTRA_RPATHS', extra_rpaths) - # Add bin directories from dependencies to the PATH for the build. - # These directories are added to the beginning of the search path, and in - # the order given by 'build_and_supporting_prefixes' (the iteration order - # is reversed because each entry is prepended) - for prefix in reversed(build_and_supporting_prefixes): - for dirname in ['bin', 'bin64']: - bin_dir = os.path.join(prefix, dirname) - if os.path.isdir(bin_dir): - env.prepend_path('PATH', bin_dir) - # Add spack build environment path with compiler wrappers first in # the path. We add the compiler wrapper path, which includes default # wrappers (cc, c++, f77, f90), AND a subdirectory containing @@ -453,6 +354,7 @@ def set_build_environment_variables(pkg, env, dirty): if os.path.isdir(ci): env_paths.append(ci) + tty.debug("Adding compiler bin/ paths: " + " ".join(env_paths)) for item in env_paths: env.prepend_path('PATH', item) env.set_path(SPACK_ENV_PATH, env_paths) @@ -471,14 +373,69 @@ def set_build_environment_variables(pkg, env, dirty): raise RuntimeError("No ccache binary found in PATH") env.set(SPACK_CCACHE_BINARY, ccache) - # Add any pkgconfig directories to PKG_CONFIG_PATH - for prefix in reversed(build_link_prefixes): - for directory in ('lib', 'lib64', 'share'): - pcdir = os.path.join(prefix, directory, 'pkgconfig') - if os.path.isdir(pcdir): - env.prepend_path('PKG_CONFIG_PATH', pcdir) + # Gather information about various types of dependencies + link_deps = set(pkg.spec.traverse(root=False, deptype=('link'))) + rpath_deps = get_rpath_deps(pkg) - return env + link_dirs = [] + include_dirs = [] + rpath_dirs = [] + + def _prepend_all(list_to_modify, items_to_add): + # Update the original list (creating a new list would be faster but + # may not be convenient) + for item in reversed(list(items_to_add)): + list_to_modify.insert(0, item) + + def update_compiler_args_for_dep(dep): + if dep in link_deps and (not is_system_path(dep.prefix)): + query = pkg.spec[dep.name] + dep_link_dirs = list() + try: + dep_link_dirs.extend(query.libs.directories) + except NoLibrariesError: + tty.debug("No libraries found for {0}".format(dep.name)) + + for default_lib_dir in ['lib', 'lib64']: + default_lib_prefix = os.path.join( + dep.prefix, default_lib_dir) + if os.path.isdir(default_lib_prefix): + dep_link_dirs.append(default_lib_prefix) + + _prepend_all(link_dirs, dep_link_dirs) + if dep in rpath_deps: + _prepend_all(rpath_dirs, dep_link_dirs) + + try: + _prepend_all(include_dirs, query.headers.directories) + except NoHeadersError: + tty.debug("No headers found for {0}".format(dep.name)) + + for dspec in pkg.spec.traverse(root=False, order='post'): + if dspec.external: + update_compiler_args_for_dep(dspec) + + # Just above, we prepended entries for -L/-rpath for externals. We + # now do this for non-external packages so that Spack-built packages + # are searched first for libraries etc. + for dspec in pkg.spec.traverse(root=False, order='post'): + if not dspec.external: + update_compiler_args_for_dep(dspec) + + # The top-level package is always RPATHed. It hasn't been installed yet + # so the RPATHs are added unconditionally (e.g. even though lib64/ may + # not be created for the install). + for libdir in ['lib64', 'lib']: + lib_path = os.path.join(pkg.prefix, libdir) + rpath_dirs.insert(0, lib_path) + + link_dirs = list(dedupe(filter_system_paths(link_dirs))) + include_dirs = list(dedupe(filter_system_paths(include_dirs))) + rpath_dirs = list(dedupe(filter_system_paths(rpath_dirs))) + + env.set(SPACK_LINK_DIRS, ':'.join(link_dirs)) + env.set(SPACK_INCLUDE_DIRS, ':'.join(include_dirs)) + env.set(SPACK_RPATH_DIRS, ':'.join(rpath_dirs)) def determine_number_of_jobs( @@ -716,15 +673,6 @@ def get_rpaths(pkg): return list(dedupe(filter_system_paths(rpaths))) -def get_cmake_prefix_path(pkg): - build_deps = set(pkg.spec.dependencies(deptype=('build', 'test'))) - link_deps = set(pkg.spec.traverse(root=False, deptype=('link'))) - build_link_deps = build_deps | link_deps - build_link_deps = _place_externals_last(build_link_deps) - build_link_prefixes = filter_system_paths(x.prefix for x in build_link_deps) - return build_link_prefixes - - def get_std_cmake_args(pkg): """List of standard arguments used if a package is a CMakePackage. @@ -792,42 +740,40 @@ def load_external_modules(pkg): def setup_package(pkg, dirty, context='build'): """Execute all environment setup routines.""" + if context not in ['build', 'test']: + raise ValueError( + "'context' must be one of ['build', 'test'] - got: {0}" + .format(context)) + + set_module_variables_for_package(pkg) + env = EnvironmentModifications() if not dirty: clean_environment() - # setup compilers and build tools for build contexts + # setup compilers for build contexts need_compiler = context == 'build' or (context == 'test' and pkg.test_requires_compiler) if need_compiler: set_compiler_environment_variables(pkg, env) - set_build_environment_variables(pkg, env, dirty) + set_wrapper_variables(pkg, env) + + env.extend(modifications_from_dependencies( + pkg.spec, context, custom_mods_only=False)) # architecture specific setup pkg.architecture.platform.setup_platform_environment(pkg, env) if context == 'build': - # recursive post-order dependency information - env.extend( - modifications_from_dependencies(pkg.spec, context=context) - ) + pkg.setup_build_environment(env) if (not dirty) and (not env.is_unset('CPATH')): tty.debug("A dependency has updated CPATH, this may lead pkg-" "config to assume that the package is part of the system" " includes and omit it when invoked with '--cflags'.") - - # setup package itself - set_module_variables_for_package(pkg) - pkg.setup_build_environment(env) elif context == 'test': - import spack.user_environment as uenv # avoid circular import - env.extend(uenv.environment_modifications_for_spec(pkg.spec)) - env.extend( - modifications_from_dependencies(pkg.spec, context=context) - ) - set_module_variables_for_package(pkg) + pkg.setup_run_environment(env) env.prepend_path('PATH', '.') # Loading modules, in particular if they are meant to be used outside @@ -869,39 +815,173 @@ def setup_package(pkg, dirty, context='build'): env.apply_modifications() -def modifications_from_dependencies(spec, context): +def _make_runnable(pkg, env): + # Helper method which prepends a Package's bin/ prefix to the PATH + # environment variable + prefix = pkg.prefix + + for dirname in ['bin', 'bin64']: + bin_dir = os.path.join(prefix, dirname) + if os.path.isdir(bin_dir): + env.prepend_path('PATH', bin_dir) + + +def modifications_from_dependencies(spec, context, custom_mods_only=True): """Returns the environment modifications that are required by the dependencies of a spec and also applies modifications to this spec's package at module scope, if need be. + Environment modifications include: + + - Updating PATH so that executables can be found + - Updating CMAKE_PREFIX_PATH and PKG_CONFIG_PATH so that their respective + tools can find Spack-built dependencies + - Running custom package environment modifications + + Custom package modifications can conflict with the default PATH changes + we make (specifically for the PATH, CMAKE_PREFIX_PATH, and PKG_CONFIG_PATH + environment variables), so this applies changes in a fixed order: + + - All modifications (custom and default) from external deps first + - All modifications from non-external deps afterwards + + With that order, `PrependPath` actions from non-external default + environment modifications will take precedence over custom modifications + from external packages. + + A secondary constraint is that custom and default modifications are + grouped on a per-package basis: combined with the post-order traversal this + means that default modifications of dependents can override custom + modifications of dependencies (again, this would only occur for PATH, + CMAKE_PREFIX_PATH, or PKG_CONFIG_PATH). + Args: spec (Spec): spec for which we want the modifications context (str): either 'build' for build-time modifications or 'run' for run-time modifications """ + if context not in ['build', 'run', 'test']: + raise ValueError( + "Expecting context to be one of ['build', 'run', 'test'], " + "got: {0}".format(context)) + env = EnvironmentModifications() - pkg = spec.package - - # Maps the context to deptype and method to be called - deptype_and_method = { - 'build': (('build', 'link', 'test'), - 'setup_dependent_build_environment'), - 'run': (('link', 'run'), 'setup_dependent_run_environment'), - 'test': (('link', 'run', 'test'), 'setup_dependent_run_environment') - } - deptype, method = deptype_and_method[context] - - root = context == 'test' - for dspec in spec.traverse(order='post', root=root, deptype=deptype): - dpkg = dspec.package - set_module_variables_for_package(dpkg) - # Allow dependencies to modify the module - dpkg.setup_dependent_package(pkg.module, spec) - getattr(dpkg, method)(env, spec) + + # Note: see computation of 'custom_mod_deps' and 'exe_deps' later in this + # function; these sets form the building blocks of those collections. + build_deps = set(spec.dependencies(deptype=('build', 'test'))) + link_deps = set(spec.traverse(root=False, deptype='link')) + build_link_deps = build_deps | link_deps + build_and_supporting_deps = set() + for build_dep in build_deps: + build_and_supporting_deps.update(build_dep.traverse(deptype='run')) + run_and_supporting_deps = set( + spec.traverse(root=False, deptype=('run', 'link'))) + test_and_supporting_deps = set() + for test_dep in set(spec.dependencies(deptype='test')): + test_and_supporting_deps.update(test_dep.traverse(deptype='run')) + + # All dependencies that might have environment modifications to apply + custom_mod_deps = set() + if context == 'build': + custom_mod_deps.update(build_and_supporting_deps) + # Tests may be performed after build + custom_mod_deps.update(test_and_supporting_deps) + else: + # test/run context + custom_mod_deps.update(run_and_supporting_deps) + if context == 'test': + custom_mod_deps.update(test_and_supporting_deps) + custom_mod_deps.update(link_deps) + + # Determine 'exe_deps': the set of packages with binaries we want to use + if context == 'build': + exe_deps = build_and_supporting_deps | test_and_supporting_deps + elif context == 'run': + exe_deps = set(spec.traverse(deptype='run')) + elif context == 'test': + exe_deps = test_and_supporting_deps + + def default_modifications_for_dep(dep): + if (dep in build_link_deps and + not is_system_path(dep.prefix) and + context == 'build'): + prefix = dep.prefix + + env.prepend_path('CMAKE_PREFIX_PATH', prefix) + + for directory in ('lib', 'lib64', 'share'): + pcdir = os.path.join(prefix, directory, 'pkgconfig') + if os.path.isdir(pcdir): + env.prepend_path('PKG_CONFIG_PATH', pcdir) + + if dep in exe_deps and not is_system_path(dep.prefix): + _make_runnable(dep, env) + + def add_modifications_for_dep(dep): + # Some callers of this function only want the custom modifications. + # For callers that want both custom and default modifications, we want + # to perform the default modifications here (this groups custom + # and default modifications together on a per-package basis). + if not custom_mods_only: + default_modifications_for_dep(dep) + + # Perform custom modifications here (PrependPath actions performed in + # the custom method override the default environment modifications + # we do to help the build, namely for PATH, CMAKE_PREFIX_PATH, and + # PKG_CONFIG_PATH) + if dep in custom_mod_deps: + dpkg = dep.package + set_module_variables_for_package(dpkg) + # Allow dependencies to modify the module + dpkg.setup_dependent_package(spec.package.module, spec) + if context == 'build': + dpkg.setup_dependent_build_environment(env, spec) + else: + dpkg.setup_dependent_run_environment(env, spec) + + # Note that we want to perform environment modifications in a fixed order. + # The Spec.traverse method provides this: i.e. in addition to + # the post-order semantics, it also guarantees a fixed traversal order + # among dependencies which are not constrained by post-order semantics. + for dspec in spec.traverse(root=False, order='post'): + if dspec.external: + add_modifications_for_dep(dspec) + + for dspec in spec.traverse(root=False, order='post'): + # Default env modifications for non-external packages can override + # custom modifications of external packages (this can only occur + # for modifications to PATH, CMAKE_PREFIX_PATH, and PKG_CONFIG_PATH) + if not dspec.external: + add_modifications_for_dep(dspec) return env +def get_cmake_prefix_path(pkg): + # Note that unlike modifications_from_dependencies, this does not include + # any edits to CMAKE_PREFIX_PATH defined in custom + # setup_dependent_build_environment implementations of dependency packages + build_deps = set(pkg.spec.dependencies(deptype=('build', 'test'))) + link_deps = set(pkg.spec.traverse(root=False, deptype=('link'))) + build_link_deps = build_deps | link_deps + spack_built = [] + externals = [] + # modifications_from_dependencies updates CMAKE_PREFIX_PATH by first + # prepending all externals and then all non-externals + for dspec in pkg.spec.traverse(root=False, order='post'): + if dspec in build_link_deps: + if dspec.external: + externals.insert(0, dspec) + else: + spack_built.insert(0, dspec) + + ordered_build_link_deps = spack_built + externals + build_link_prefixes = filter_system_paths( + x.prefix for x in ordered_build_link_deps) + return build_link_prefixes + + def _setup_pkg_and_run(serialized_pkg, function, kwargs, child_pipe, input_multiprocess_fd): diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index 7aca1dea59..a179dda650 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -225,7 +225,7 @@ def test_package_inheritance_module_setup(config, mock_packages, working_env): assert os.environ['TEST_MODULE_VAR'] == 'test_module_variable' -def test_set_build_environment_variables( +def test_wrapper_variables( config, mock_packages, working_env, monkeypatch, installation_dir_with_headers ): @@ -264,8 +264,8 @@ def test_set_build_environment_variables( try: pkg = root.package env_mods = EnvironmentModifications() - spack.build_environment.set_build_environment_variables( - pkg, env_mods, dirty=False) + spack.build_environment.set_wrapper_variables( + pkg, env_mods) env_mods.apply_modifications() @@ -324,8 +324,8 @@ dt-diamond-left: ) env_mods = EnvironmentModifications() - spack.build_environment.set_build_environment_variables( - top.package, env_mods, False) + spack.build_environment.set_wrapper_variables( + top.package, env_mods) env_mods.apply_modifications() link_dir_var = os.environ['SPACK_LINK_DIRS'] diff --git a/lib/spack/spack/util/environment.py b/lib/spack/spack/util/environment.py index 04158c119b..d015ee4e97 100644 --- a/lib/spack/spack/util/environment.py +++ b/lib/spack/spack/util/environment.py @@ -245,12 +245,16 @@ class NameValueModifier(object): class SetEnv(NameValueModifier): def execute(self, env): + tty.debug("SetEnv: {0}={1}".format(self.name, str(self.value)), + level=3) env[self.name] = str(self.value) class AppendFlagsEnv(NameValueModifier): def execute(self, env): + tty.debug("AppendFlagsEnv: {0}={1}".format(self.name, str(self.value)), + level=3) if self.name in env and env[self.name]: env[self.name] += self.separator + str(self.value) else: @@ -260,6 +264,7 @@ class AppendFlagsEnv(NameValueModifier): class UnsetEnv(NameModifier): def execute(self, env): + tty.debug("UnsetEnv: {0}".format(self.name), level=3) # Avoid throwing if the variable was not set env.pop(self.name, None) @@ -267,6 +272,8 @@ class UnsetEnv(NameModifier): class RemoveFlagsEnv(NameValueModifier): def execute(self, env): + tty.debug("RemoveFlagsEnv: {0}-{1}".format(self.name, str(self.value)), + level=3) environment_value = env.get(self.name, '') flags = environment_value.split( self.separator) if environment_value else [] @@ -278,12 +285,15 @@ class SetPath(NameValueModifier): def execute(self, env): string_path = concatenate_paths(self.value, separator=self.separator) + tty.debug("SetPath: {0}={1}".format(self.name, string_path), level=3) env[self.name] = string_path class AppendPath(NameValueModifier): def execute(self, env): + tty.debug("AppendPath: {0}+{1}".format(self.name, str(self.value)), + level=3) environment_value = env.get(self.name, '') directories = environment_value.split( self.separator) if environment_value else [] @@ -294,6 +304,8 @@ class AppendPath(NameValueModifier): class PrependPath(NameValueModifier): def execute(self, env): + tty.debug("PrependPath: {0}+{1}".format(self.name, str(self.value)), + level=3) environment_value = env.get(self.name, '') directories = environment_value.split( self.separator) if environment_value else [] @@ -304,6 +316,8 @@ class PrependPath(NameValueModifier): class RemovePath(NameValueModifier): def execute(self, env): + tty.debug("RemovePath: {0}-{1}".format(self.name, str(self.value)), + level=3) environment_value = env.get(self.name, '') directories = environment_value.split( self.separator) if environment_value else [] @@ -315,6 +329,7 @@ class RemovePath(NameValueModifier): class DeprioritizeSystemPaths(NameModifier): def execute(self, env): + tty.debug("DeprioritizeSystemPaths: {0}".format(self.name), level=3) environment_value = env.get(self.name, '') directories = environment_value.split( self.separator) if environment_value else [] @@ -326,6 +341,8 @@ class DeprioritizeSystemPaths(NameModifier): class PruneDuplicatePaths(NameModifier): def execute(self, env): + tty.debug("PruneDuplicatePaths: {0}".format(self.name), + level=3) environment_value = env.get(self.name, '') directories = environment_value.split( self.separator) if environment_value else [] @@ -624,6 +641,8 @@ class EnvironmentModifications(object): clean (bool): in addition to removing empty entries, also remove duplicate entries (default: False). """ + tty.debug("EnvironmentModifications.from_sourcing_file: {0}" + .format(filename)) # Check if the file actually exists if not os.path.isfile(filename): msg = 'Trying to source non-existing file: {0}'.format(filename) diff --git a/lib/spack/spack/util/module_cmd.py b/lib/spack/spack/util/module_cmd.py index fa6996fcbd..338e724c51 100644 --- a/lib/spack/spack/util/module_cmd.py +++ b/lib/spack/spack/util/module_cmd.py @@ -95,6 +95,7 @@ def load_module(mod): load that module. It then loads the provided module. Depends on the modulecmd implementation of modules used in cray and lmod. """ + tty.debug("module_cmd.load_module: {0}".format(mod)) # Read the module and remove any conflicting modules # We do this without checking that they are already installed # for ease of programming because unloading a module that is not |