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.
This commit is contained in:
parent
94536d2b66
commit
2605aeb072
4 changed files with 52 additions and 6 deletions
|
@ -1939,6 +1939,11 @@ def _spec_clauses(
|
||||||
for virtual in virtuals:
|
for virtual in virtuals:
|
||||||
clauses.append(fn.attr("virtual_on_incoming_edges", spec.name, virtual))
|
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
|
# add all clauses from dependencies
|
||||||
if transitive:
|
if transitive:
|
||||||
# TODO: Eventually distinguish 2 deps on the same pkg (build and link)
|
# TODO: Eventually distinguish 2 deps on the same pkg (build and link)
|
||||||
|
|
|
@ -10,12 +10,13 @@
|
||||||
%=============================================================================
|
%=============================================================================
|
||||||
|
|
||||||
% A package cannot be reused if the libc is not compatible with it
|
% A package cannot be reused if the libc is not compatible with it
|
||||||
:- provider(node(X, LibcPackage), node(0, "libc")),
|
error(100, "Cannot reuse {0} since we cannot determine libc compatibility", ReusedPackage)
|
||||||
attr("version", node(X, LibcPackage), LibcVersion),
|
:- provider(node(X, LibcPackage), node(0, "libc")),
|
||||||
attr("hash", node(R, ReusedPackage), Hash),
|
attr("version", node(X, LibcPackage), LibcVersion),
|
||||||
% Libc packages can be reused without the "compatible_libc" attribute
|
attr("hash", node(R, ReusedPackage), Hash),
|
||||||
ReusedPackage != LibcPackage,
|
% Libc packages can be reused without the "compatible_libc" attribute
|
||||||
not attr("compatible_libc", node(R, ReusedPackage), LibcPackage, LibcVersion).
|
ReusedPackage != LibcPackage,
|
||||||
|
not attr("compatible_libc", node(R, ReusedPackage), LibcPackage, LibcVersion).
|
||||||
|
|
||||||
% Check whether the DAG has any built package
|
% Check whether the DAG has any built package
|
||||||
has_built_packages() :- build(X), not external(X).
|
has_built_packages() :- build(X), not external(X).
|
||||||
|
|
|
@ -2546,6 +2546,30 @@ def test_include_specs_from_externals_and_libcs(
|
||||||
|
|
||||||
assert result["deprecated-versions"].satisfies("@1.0.0")
|
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()
|
@pytest.fixture()
|
||||||
def duplicates_test_repository():
|
def duplicates_test_repository():
|
||||||
|
|
16
var/spack/repos/builtin.mock/packages/sombrero/package.py
Normal file
16
var/spack/repos/builtin.mock/packages/sombrero/package.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
|
||||||
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
from spack.package import *
|
||||||
|
|
||||||
|
|
||||||
|
class Sombrero(Package):
|
||||||
|
"""Simple package with a dependency on an external spec."""
|
||||||
|
|
||||||
|
homepage = "http://www.example.com"
|
||||||
|
url = "http://www.example.com/b-1.0.tar.gz"
|
||||||
|
|
||||||
|
version("1.0", md5="0123456789abcdef0123456789abcdef")
|
||||||
|
depends_on("externaltool")
|
Loading…
Reference in a new issue