diff options
author | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2024-05-23 14:37:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-23 14:37:48 +0200 |
commit | f60e548a0dca17d44c259fa6c873fa7b683921e0 (patch) | |
tree | 62d474e4300ddac2690169894ce9e5a3ba9eaa0f /lib | |
parent | 04dc16a6b1060397a30166f520f4e67c5df36bd2 (diff) | |
download | spack-f60e548a0dca17d44c259fa6c873fa7b683921e0.tar.gz spack-f60e548a0dca17d44c259fa6c873fa7b683921e0.tar.bz2 spack-f60e548a0dca17d44c259fa6c873fa7b683921e0.tar.xz spack-f60e548a0dca17d44c259fa6c873fa7b683921e0.zip |
ASP-based solver: fix reusing externals on linux (#44316)
We need to tell clingo the libc compatibility of external nodes
in buildcaches or stores, to allow reuse.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/solver/asp.py | 5 | ||||
-rw-r--r-- | lib/spack/spack/solver/libc_compatibility.lp | 13 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 24 |
3 files changed, 36 insertions, 6 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 0083dbc070..094ebaf170 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -1939,6 +1939,11 @@ class SpackSolverSetup: for virtual in virtuals: clauses.append(fn.attr("virtual_on_incoming_edges", spec.name, virtual)) + # If the spec is external and concrete, we allow all the libcs on the system + if spec.external and spec.concrete and using_libc_compatibility(): + for libc in self.libcs: + clauses.append(fn.attr("compatible_libc", spec.name, libc.name, libc.version)) + # add all clauses from dependencies if transitive: # TODO: Eventually distinguish 2 deps on the same pkg (build and link) diff --git a/lib/spack/spack/solver/libc_compatibility.lp b/lib/spack/spack/solver/libc_compatibility.lp index 28c7c57fda..3e2c00e372 100644 --- a/lib/spack/spack/solver/libc_compatibility.lp +++ b/lib/spack/spack/solver/libc_compatibility.lp @@ -10,12 +10,13 @@ %============================================================================= % A package cannot be reused if the libc is not compatible with it -:- provider(node(X, LibcPackage), node(0, "libc")), - attr("version", node(X, LibcPackage), LibcVersion), - attr("hash", node(R, ReusedPackage), Hash), - % Libc packages can be reused without the "compatible_libc" attribute - ReusedPackage != LibcPackage, - not attr("compatible_libc", node(R, ReusedPackage), LibcPackage, LibcVersion). +error(100, "Cannot reuse {0} since we cannot determine libc compatibility", ReusedPackage) + :- provider(node(X, LibcPackage), node(0, "libc")), + attr("version", node(X, LibcPackage), LibcVersion), + attr("hash", node(R, ReusedPackage), Hash), + % Libc packages can be reused without the "compatible_libc" attribute + ReusedPackage != LibcPackage, + not attr("compatible_libc", node(R, ReusedPackage), LibcPackage, LibcVersion). % Check whether the DAG has any built package has_built_packages() :- build(X), not external(X). diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 797c865a4f..0b4ce5b42a 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -2546,6 +2546,30 @@ class TestConcretize: assert result["deprecated-versions"].satisfies("@1.0.0") + @pytest.mark.regression("44085") + @pytest.mark.only_clingo("Use case not supported by the original concretizer") + def test_can_reuse_concrete_externals_for_dependents(self, mutable_config, tmp_path): + """Test that external specs that are in the DB can be reused. This means they are + preferred to concretizing another external from packages.yaml + """ + packages_yaml = { + "externaltool": {"externals": [{"spec": "externaltool@2.0", "prefix": "/fake/path"}]} + } + mutable_config.set("packages", packages_yaml) + # Concretize with gcc@9 to get a suboptimal spec, since we have gcc@10 available + external_spec = Spec("externaltool@2 %gcc@9").concretized() + assert external_spec.external + + root_specs = [Spec("sombrero")] + with spack.config.override("concretizer:reuse", True): + solver = spack.solver.asp.Solver() + setup = spack.solver.asp.SpackSolverSetup() + result, _, _ = solver.driver.solve(setup, root_specs, reuse=[external_spec]) + + assert len(result.specs) == 1 + sombrero = result.specs[0] + assert sombrero["externaltool"].dag_hash() == external_spec.dag_hash() + @pytest.fixture() def duplicates_test_repository(): |