summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2023-08-14 14:24:00 +0200
committerTodd Gamblin <tgamblin@llnl.gov>2023-08-15 15:54:37 -0700
commitd3aca68e8f372ca124e7da2567e8936be23d54d3 (patch)
treed303ea79c0d5ecc7a3eeb3334a58c92f076e1c70
parentfb83f8ef310cac622f119c2ebc4125dabe7f8266 (diff)
downloadspack-d3aca68e8f372ca124e7da2567e8936be23d54d3.tar.gz
spack-d3aca68e8f372ca124e7da2567e8936be23d54d3.tar.bz2
spack-d3aca68e8f372ca124e7da2567e8936be23d54d3.tar.xz
spack-d3aca68e8f372ca124e7da2567e8936be23d54d3.zip
Rework conflicts so that "vendors" is not needed anymore
-rw-r--r--lib/spack/spack/directives.py39
-rw-r--r--lib/spack/spack/solver/asp.py44
-rw-r--r--lib/spack/spack/solver/concretize.lp17
-rw-r--r--lib/spack/spack/test/env.py6
-rw-r--r--var/spack/repos/builtin.mock/packages/vendorsb/package.py5
-rw-r--r--var/spack/repos/builtin/packages/memkind/package.py2
-rw-r--r--var/spack/repos/builtin/packages/palace/package.py4
-rw-r--r--var/spack/repos/builtin/packages/scotch/package.py4
-rw-r--r--var/spack/repos/builtin/packages/votca/package.py6
9 files changed, 39 insertions, 88 deletions
diff --git a/lib/spack/spack/directives.py b/lib/spack/spack/directives.py
index 03f2f38189..acb2af1a62 100644
--- a/lib/spack/spack/directives.py
+++ b/lib/spack/spack/directives.py
@@ -33,7 +33,6 @@ import collections.abc
import functools
import os.path
import re
-import warnings
from typing import Any, Callable, List, Optional, Set, Tuple, Union
import llnl.util.lang
@@ -69,7 +68,6 @@ __all__ = [
"resource",
"build_system",
"requires",
- "vendors",
]
#: These are variant names used by Spack internally; packages can't use them
@@ -520,20 +518,8 @@ def conflicts(conflict_spec, when=None, msg=None):
if not when_spec:
return
- # TODO: (remove after v0.21)
- conflict_key = conflict_spec
- s = spack.spec.Spec(conflict_spec)
- if s.name and s.name != pkg.name:
- warning_msg = (
- f"the conflict in package '{pkg.name}' on '{conflict_spec}' should "
- f"start with a '^' sigil. Not using it is deprecated as of v0.21 and"
- f" will be disallowed in v0.22"
- )
- warnings.warn(warning_msg)
- conflict_key = "^" + conflict_spec
-
# Save in a list the conflicts and the associated custom messages
- when_spec_list = pkg.conflicts.setdefault(conflict_key, [])
+ when_spec_list = pkg.conflicts.setdefault(conflict_spec, [])
msg_with_name = f"{pkg.name}: {msg}" if msg is not None else msg
when_spec_list.append((when_spec, msg_with_name))
@@ -917,29 +903,6 @@ def requires(*requirement_specs, policy="one_of", when=None, msg=None):
return _execute_requires
-@directive("vendors")
-def vendors(spec, when=None):
- """Declares that a package has an internal copy of another package.
-
- Currently, the effect is to forbid having the two packages in the same
- "unification set".
-
- Args:
- spec: spec being vendored
- when: optional constraint that triggers vendoring
- """
-
- def _execute_vendors(pkg):
- when_spec = make_when_spec(when)
- if not when_spec:
- return
-
- when_spec_list = pkg.vendors.setdefault(spec, [])
- when_spec_list.append(when_spec)
-
- return _execute_vendors
-
-
class DirectiveError(spack.error.SpackError):
"""This is raised when something is wrong with a package directive."""
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index f29a22a2b1..3ca4824be1 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -1030,7 +1030,10 @@ class SpackSolverSetup:
no_constraint_msg = "{0}: conflicts with '{1}'"
for trigger, constraints in pkg.conflicts.items():
trigger_msg = "conflict trigger %s" % str(trigger)
- trigger_id = self.condition(spack.spec.Spec(trigger), name=pkg.name, msg=trigger_msg)
+ trigger_spec = spack.spec.Spec(trigger)
+ trigger_id = self.condition(
+ trigger_spec, name=trigger_spec.name or pkg.name, msg=trigger_msg
+ )
for constraint, conflict_msg in constraints:
if conflict_msg is None:
@@ -1045,15 +1048,6 @@ class SpackSolverSetup:
)
self.gen.newline()
- def vendor_rules(self, pkg):
- """Facts about vendored packages."""
- for vendored_spec_str, constraints in pkg.vendors.items():
- vendored_spec = spack.spec.Spec(vendored_spec_str)
- for constraint in constraints:
- constraint_id = self.condition(constraint, name=pkg.name)
- self.gen.fact(fn.pkg_fact(pkg.name, fn.vendors(constraint_id, vendored_spec.name)))
- self.gen.newline()
-
def compiler_facts(self):
"""Facts about available compilers."""
@@ -1203,9 +1197,6 @@ class SpackSolverSetup:
# conflicts
self.conflict_rules(pkg)
- # vendoring
- self.vendor_rules(pkg)
-
# default compilers for this package
self.package_compiler_defaults(pkg)
@@ -1224,19 +1215,20 @@ class SpackSolverSetup:
self.package_requirement_rules(pkg)
# trigger and effect tables
- self.trigger_rules(pkg.name)
+ self.trigger_rules()
self.effect_rules(pkg.name)
- def trigger_rules(self, name):
+ def trigger_rules(self):
self.gen.h2("Trigger conditions")
- cache = self._trigger_cache[name]
- for spec_str, (trigger_id, requirements) in cache.items():
- self.gen.fact(fn.pkg_fact(name, fn.trigger_id(trigger_id)))
- self.gen.fact(fn.pkg_fact(name, fn.trigger_msg(spec_str)))
- for predicate in requirements:
- self.gen.fact(fn.condition_requirement(trigger_id, *predicate.args))
- self.gen.newline()
- cache.clear()
+ for name in self._trigger_cache:
+ cache = self._trigger_cache[name]
+ for spec_str, (trigger_id, requirements) in cache.items():
+ self.gen.fact(fn.pkg_fact(name, fn.trigger_id(trigger_id)))
+ self.gen.fact(fn.pkg_fact(name, fn.trigger_msg(spec_str)))
+ for predicate in requirements:
+ self.gen.fact(fn.condition_requirement(trigger_id, *predicate.args))
+ self.gen.newline()
+ self._trigger_cache.clear()
def effect_rules(self, name):
self.gen.h2("Imposed requirements")
@@ -1488,7 +1480,7 @@ class SpackSolverSetup:
virtual_str, requirements, kind=RequirementKind.VIRTUAL
)
self.emit_facts_from_requirement_rules(rules)
- self.trigger_rules(virtual_str)
+ self.trigger_rules()
self.effect_rules(virtual_str)
def emit_facts_from_requirement_rules(self, rules: List[RequirementRule]):
@@ -1607,7 +1599,7 @@ class SpackSolverSetup:
self.possible_versions[spec.name].add(spec.version)
self.gen.newline()
- self.trigger_rules(pkg_name)
+ self.trigger_rules()
def preferred_variants(self, pkg_name):
"""Facts on concretization preferences, as read from packages.yaml"""
@@ -2434,7 +2426,7 @@ class SpackSolverSetup:
# Inject dev_path from environment
for ds in dev_specs:
self.condition(spack.spec.Spec(ds.name), ds, msg="%s is a develop spec" % ds.name)
- self.trigger_rules(ds.name)
+ self.trigger_rules()
self.effect_rules(ds.name)
self.gen.h1("Spec Constraints")
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index 1fd0966f04..bc24514115 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -441,22 +441,15 @@ error(10, "'{0}' is not a valid dependency for any package in the DAG", Package)
error(1, Msg)
:- attr("node", node(ID, Package)),
pkg_fact(Package, conflict(TriggerID, ConstraintID, Msg)),
- condition_holds(TriggerID, node(ID, Package)),
- condition_holds(ConstraintID, node(ID, Package)),
+ % node(ID1, TriggerPackage) is node(ID2, Package) in most, but not all, cases
+ condition_holds(TriggerID, node(ID1, TriggerPackage)),
+ condition_holds(ConstraintID, node(ID2, Package)),
+ unification_set(X, node(ID2, Package)),
+ unification_set(X, node(ID1, TriggerPackage)),
not external(node(ID, Package)), % ignore conflicts for externals
not attr("hash", node(ID, Package), _). % ignore conflicts for installed packages
%-----------------------------------------------------------------------------
-% Vendoring
-%-----------------------------------------------------------------------------
-error(1, "{0} vendors an internal copy of {1}, so it cannot be in the same unification set as {1}", Package, VendoredPackage)
- :- pkg_fact(Package, vendors(ConditionID, VendoredPackage)),
- attr("node", node(ID, Package)),
- condition_holds(ConditionID, node(ID, Package)),
- unification_set(X, node(ID, Package)),
- unification_set(X, node(_, VendoredPackage)).
-
-%-----------------------------------------------------------------------------
% Virtual dependencies
%-----------------------------------------------------------------------------
diff --git a/lib/spack/spack/test/env.py b/lib/spack/spack/test/env.py
index 23c429de16..203fa72d70 100644
--- a/lib/spack/spack/test/env.py
+++ b/lib/spack/spack/test/env.py
@@ -561,10 +561,12 @@ spack:
("vendorsb@=1.1", True, None),
],
)
-def test_vendors_directive(
+def test_conflicts_with_packages_that_are_not_dependencies(
spec_str, expected_raise, expected_spec, tmp_path, mock_packages, config
):
- """Tests that we cannot concretize two specs together, if one vendors the other."""
+ """Tests that we cannot concretize two specs together, if one conflicts with the other,
+ even though they don't have a dependency relation.
+ """
if spack.config.get("config:concretizer") == "original":
pytest.xfail("Known failure of the original concretizer")
diff --git a/var/spack/repos/builtin.mock/packages/vendorsb/package.py b/var/spack/repos/builtin.mock/packages/vendorsb/package.py
index 73fe9ad1cf..fbf14236a1 100644
--- a/var/spack/repos/builtin.mock/packages/vendorsb/package.py
+++ b/var/spack/repos/builtin.mock/packages/vendorsb/package.py
@@ -7,7 +7,7 @@ from spack.package import *
class Vendorsb(Package):
- """A package that vendors another"""
+ """A package that vendors another, and thus conflicts with it"""
homepage = "http://www.example.com"
url = "http://www.example.com/b-1.0.tar.gz"
@@ -15,4 +15,5 @@ class Vendorsb(Package):
version("1.1", md5="0123456789abcdef0123456789abcdef")
version("1.0", md5="0123456789abcdef0123456789abcdef")
- vendors("b", when="@=1.1")
+ # b is not a dependency
+ conflicts("b", when="@=1.1")
diff --git a/var/spack/repos/builtin/packages/memkind/package.py b/var/spack/repos/builtin/packages/memkind/package.py
index 12a0e18fd6..f51740f48e 100644
--- a/var/spack/repos/builtin/packages/memkind/package.py
+++ b/var/spack/repos/builtin/packages/memkind/package.py
@@ -40,7 +40,7 @@ class Memkind(AutotoolsPackage):
# memkind includes a copy of jemalloc; see
# <https://github.com/memkind/memkind#jemalloc>.
- vendors("jemalloc")
+ conflicts("jemalloc")
# https://github.com/spack/spack/issues/37292
parallel = False
diff --git a/var/spack/repos/builtin/packages/palace/package.py b/var/spack/repos/builtin/packages/palace/package.py
index 6eb8d87936..f7345f168f 100644
--- a/var/spack/repos/builtin/packages/palace/package.py
+++ b/var/spack/repos/builtin/packages/palace/package.py
@@ -95,8 +95,8 @@ class Palace(CMakePackage):
depends_on("arpack-ng~shared", when="~shared")
# Palace always builds its own internal MFEM, GSLIB
- vendors("mfem")
- vendors("gslib")
+ conflicts("mfem")
+ conflicts("gslib")
# More dependency variant conflicts
conflicts("^hypre+int64", msg="Palace uses HYPRE's mixedint option for 64 bit integers")
diff --git a/var/spack/repos/builtin/packages/scotch/package.py b/var/spack/repos/builtin/packages/scotch/package.py
index 3a1e03cbbd..b009aec43d 100644
--- a/var/spack/repos/builtin/packages/scotch/package.py
+++ b/var/spack/repos/builtin/packages/scotch/package.py
@@ -70,8 +70,8 @@ class Scotch(CMakePackage, MakefilePackage):
# Vendored dependency of METIS/ParMETIS conflicts with standard
# installations
- vendors("metis", when="+metis")
- vendors("parmetis", when="+metis")
+ conflicts("metis", when="+metis")
+ conflicts("parmetis", when="+metis")
parallel = False
diff --git a/var/spack/repos/builtin/packages/votca/package.py b/var/spack/repos/builtin/packages/votca/package.py
index 629c9eb0ad..db9d260f86 100644
--- a/var/spack/repos/builtin/packages/votca/package.py
+++ b/var/spack/repos/builtin/packages/votca/package.py
@@ -29,9 +29,9 @@ class Votca(CMakePackage):
)
variant("xtp", default=True, description="Build xtp parts of votca")
- vendors("votca-tools")
- vendors("votca-csg")
- vendors("votca-xtp")
+ conflicts("votca-tools")
+ conflicts("votca-csg")
+ conflicts("votca-xtp")
depends_on("cmake@3.13:", type="build")
depends_on("expat")