From 56761649a281d6281b82c9da5902edd2d5771279 Mon Sep 17 00:00:00 2001 From: Greg Becker Date: Mon, 18 Dec 2023 20:24:15 -0800 Subject: environment modifications for externals (#41723) * allow externals to configure environment modifications * docs for external env modification --------- Co-authored-by: becker33 --- lib/spack/docs/packages_yaml.rst | 29 +++++++++++++++++++++++++++++ lib/spack/spack/build_environment.py | 5 +++++ lib/spack/spack/schema/packages.py | 9 ++++++++- lib/spack/spack/test/build_environment.py | 18 ++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/lib/spack/docs/packages_yaml.rst b/lib/spack/docs/packages_yaml.rst index af0acf0f9a..0567421054 100644 --- a/lib/spack/docs/packages_yaml.rst +++ b/lib/spack/docs/packages_yaml.rst @@ -97,6 +97,35 @@ Each package version and compiler listed in an external should have entries in Spack's packages and compiler configuration, even though the package and compiler may not ever be built. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Extra attributes for external packages +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Sometimes external packages require additional attributes to be used +effectively. This information can be defined on a per-package basis +and stored in the ``extra_attributes`` section of the external package +configuration. In addition to per-package information, this section +can be used to define environment modifications to be performed +whenever the package is used. For example, if an external package is +built without ``rpath`` support, it may require ``LD_LIBRARY_PATH`` +settings to find its dependencies. This could be configured as +follows: + +.. code-block:: yaml + + packages: + mpich: + externals: + - spec: mpich@3.3 %clang@12.0.0 +hwloc + prefix: /path/to/mpich + extra_attributes: + environment: + prepend_path: + LD_LIBRARY_PATH: /path/to/hwloc/lib64 + +See :ref:`configuration_environment_variables` for more information on +how to configure environment modifications in Spack config files. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prevent packages from being built from sources ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py index 20d8e75f9b..eb12463b1a 100644 --- a/lib/spack/spack/build_environment.py +++ b/lib/spack/spack/build_environment.py @@ -1032,6 +1032,11 @@ class SetupContext: if id(spec) in self.nodes_in_subdag: pkg.setup_dependent_run_environment(run_env_mods, spec) pkg.setup_run_environment(run_env_mods) + + external_env = (dspec.extra_attributes or {}).get("environment", {}) + if external_env: + run_env_mods.extend(spack.schema.environment.parse(external_env)) + if self.context == Context.BUILD: # Don't let the runtime environment of comiler like dependencies leak into the # build env diff --git a/lib/spack/spack/schema/packages.py b/lib/spack/spack/schema/packages.py index 2802f89529..82c3c9b552 100644 --- a/lib/spack/spack/schema/packages.py +++ b/lib/spack/spack/schema/packages.py @@ -7,6 +7,7 @@ .. literalinclude:: _spack_root/lib/spack/spack/schema/packages.py :lines: 13- """ +import spack.schema.environment permissions = { "type": "object", @@ -155,7 +156,13 @@ properties = { "spec": {"type": "string"}, "prefix": {"type": "string"}, "modules": {"type": "array", "items": {"type": "string"}}, - "extra_attributes": {"type": "object"}, + "extra_attributes": { + "type": "object", + "additionalProperties": True, + "properties": { + "environment": spack.schema.environment.definition + }, + }, }, "additionalProperties": True, "required": ["spec"], diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index cbccbc429e..8e13a5f13a 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -285,6 +285,24 @@ def test_compiler_config_modifications( assert name not in os.environ +def test_external_config_env(mock_packages, mutable_config, working_env): + cmake_config = { + "externals": [ + { + "spec": "cmake@1.0", + "prefix": "/fake/path", + "extra_attributes": {"environment": {"set": {"TEST_ENV_VAR_SET": "yes it's set"}}}, + } + ] + } + spack.config.set("packages:cmake", cmake_config) + + cmake_client = spack.spec.Spec("cmake-client").concretized() + spack.build_environment.setup_package(cmake_client.package, False) + + assert os.environ["TEST_ENV_VAR_SET"] == "yes it's set" + + @pytest.mark.regression("9107") def test_spack_paths_before_module_paths(config, mock_packages, monkeypatch, working_env): s = spack.spec.Spec("cmake") -- cgit v1.2.3-60-g2f50