summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/spack/defaults/concretizer.yaml5
-rw-r--r--lib/spack/spack/schema/concretizer.py1
-rw-r--r--lib/spack/spack/solver/asp.py10
-rw-r--r--lib/spack/spack/solver/concretize.lp3
-rw-r--r--lib/spack/spack/test/concretize.py19
5 files changed, 37 insertions, 1 deletions
diff --git a/etc/spack/defaults/concretizer.yaml b/etc/spack/defaults/concretizer.yaml
index edefa552ce..5512cde24d 100644
--- a/etc/spack/defaults/concretizer.yaml
+++ b/etc/spack/defaults/concretizer.yaml
@@ -42,3 +42,8 @@ concretizer:
# "minimal": allows the duplication of 'build-tools' nodes only (e.g. py-setuptools, cmake etc.)
# "full" (experimental): allows separation of the entire build-tool stack (e.g. the entire "cmake" subDAG)
strategy: minimal
+ # Option to specify compatiblity between operating systems for reuse of compilers and packages
+ # Specified as a key: [list] where the key is the os that is being targeted, and the list contains the OS's
+ # it can reuse. Note this is a directional compatibility so mutual compatibility between two OS's
+ # requires two entries i.e. os_compatible: {sonoma: [monterey], monterey: [sonoma]}
+ os_compatible: {}
diff --git a/lib/spack/spack/schema/concretizer.py b/lib/spack/spack/schema/concretizer.py
index bc9253cb25..329f777f19 100644
--- a/lib/spack/spack/schema/concretizer.py
+++ b/lib/spack/spack/schema/concretizer.py
@@ -34,6 +34,7 @@ properties: Dict[str, Any] = {
"strategy": {"type": "string", "enum": ["none", "minimal", "full"]}
},
},
+ "os_compatible": {"type": "object", "additionalProperties": {"type": "array"}},
},
}
}
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index b0ee0d0297..ea2c9ddcfe 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -1050,6 +1050,15 @@ class SpackSolverSetup:
self.gen.fact(fn.pkg_fact(pkg.name, fn.language(condition_id, language)))
self.gen.newline()
+ def config_compatible_os(self):
+ """Facts about compatible os's specified in configs"""
+ self.gen.h2("Compatible OS from concretizer config file")
+ os_data = spack.config.get("concretizer:os_compatible", {})
+ for recent, reusable in os_data.items():
+ for old in reusable:
+ self.gen.fact(fn.os_compatible(recent, old))
+ self.gen.newline()
+
def compiler_facts(self):
"""Facts about available compilers."""
@@ -2358,6 +2367,7 @@ class SpackSolverSetup:
self.gen.newline()
self.gen.h1("General Constraints")
+ self.config_compatible_os()
self.compiler_facts()
# architecture defaults
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index 00be3e94db..dd2a5afe02 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -1186,7 +1186,8 @@ error(100, "{0} compiler '%{1}@{2}' incompatible with 'os={3}'", Package, Compil
node_compiler(node(X, Package), CompilerID),
compiler_name(CompilerID, Compiler),
compiler_version(CompilerID, Version),
- not compiler_os(CompilerID, OS),
+ compiler_os(CompilerID, CompilerOS),
+ not os_compatible(CompilerOS, OS),
not allow_compiler(Compiler, Version),
build(node(X, Package)).
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index ad11009b08..f2a104afbb 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1876,6 +1876,25 @@ class TestConcretize:
assert concrete_spec.satisfies("%{}".format(s.compiler))
assert concrete_spec.satisfies("os={}".format(s.architecture.os))
+ @pytest.mark.only_clingo("Use case not supported by the original concretizer")
+ def test_reuse_succeeds_with_config_compatible_os(self):
+ root_spec = Spec("b")
+ s = root_spec.concretized()
+ other_os = s.copy()
+ mock_os = "ubuntu2204"
+ other_os.architecture = spack.spec.ArchSpec(
+ "test-{os}-{target}".format(os=mock_os, target=str(s.architecture.target))
+ )
+ reusable_specs = [other_os]
+ overrides = {"concretizer": {"reuse": True, "os_compatible": {s.os: [mock_os]}}}
+ custom_scope = spack.config.InternalConfigScope("concretize_override", overrides)
+ with spack.config.override(custom_scope):
+ solver = spack.solver.asp.Solver()
+ setup = spack.solver.asp.SpackSolverSetup()
+ result, _, _ = solver.driver.solve(setup, [root_spec], reuse=reusable_specs)
+ concrete_spec = result.specs[0]
+ assert concrete_spec.satisfies("os={}".format(other_os.architecture.os))
+
def test_git_hash_assigned_version_is_preferred(self):
hash = "a" * 40
s = Spec("develop-branch-version@%s=develop" % hash)