Add config option and compiler support to reuse across OS's (#42693)
* Allow compilers to function across compatible OS's * Add documentation in the default yaml Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com> Co-authored-by: Gregory Becker <becker33@llnl.gov>
This commit is contained in:
parent
4cd993070f
commit
27a8eb0f68
@ -42,3 +42,8 @@ concretizer:
|
|||||||
# "minimal": allows the duplication of 'build-tools' nodes only (e.g. py-setuptools, cmake etc.)
|
# "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)
|
# "full" (experimental): allows separation of the entire build-tool stack (e.g. the entire "cmake" subDAG)
|
||||||
strategy: minimal
|
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: {}
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
"strategy": {"type": "string", "enum": ["none", "minimal", "full"]}
|
"strategy": {"type": "string", "enum": ["none", "minimal", "full"]}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"os_compatible": {"type": "object", "additionalProperties": {"type": "array"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,6 +1050,15 @@ def package_languages(self, pkg):
|
|||||||
self.gen.fact(fn.pkg_fact(pkg.name, fn.language(condition_id, language)))
|
self.gen.fact(fn.pkg_fact(pkg.name, fn.language(condition_id, language)))
|
||||||
self.gen.newline()
|
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):
|
def compiler_facts(self):
|
||||||
"""Facts about available compilers."""
|
"""Facts about available compilers."""
|
||||||
|
|
||||||
@ -2358,6 +2367,7 @@ def setup(
|
|||||||
self.gen.newline()
|
self.gen.newline()
|
||||||
|
|
||||||
self.gen.h1("General Constraints")
|
self.gen.h1("General Constraints")
|
||||||
|
self.config_compatible_os()
|
||||||
self.compiler_facts()
|
self.compiler_facts()
|
||||||
|
|
||||||
# architecture defaults
|
# architecture defaults
|
||||||
|
@ -1186,7 +1186,8 @@ error(100, "{0} compiler '%{1}@{2}' incompatible with 'os={3}'", Package, Compil
|
|||||||
node_compiler(node(X, Package), CompilerID),
|
node_compiler(node(X, Package), CompilerID),
|
||||||
compiler_name(CompilerID, Compiler),
|
compiler_name(CompilerID, Compiler),
|
||||||
compiler_version(CompilerID, Version),
|
compiler_version(CompilerID, Version),
|
||||||
not compiler_os(CompilerID, OS),
|
compiler_os(CompilerID, CompilerOS),
|
||||||
|
not os_compatible(CompilerOS, OS),
|
||||||
not allow_compiler(Compiler, Version),
|
not allow_compiler(Compiler, Version),
|
||||||
build(node(X, Package)).
|
build(node(X, Package)).
|
||||||
|
|
||||||
|
@ -1876,6 +1876,25 @@ def test_not_reusing_incompatible_os_or_compiler(self):
|
|||||||
assert concrete_spec.satisfies("%{}".format(s.compiler))
|
assert concrete_spec.satisfies("%{}".format(s.compiler))
|
||||||
assert concrete_spec.satisfies("os={}".format(s.architecture.os))
|
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):
|
def test_git_hash_assigned_version_is_preferred(self):
|
||||||
hash = "a" * 40
|
hash = "a" * 40
|
||||||
s = Spec("develop-branch-version@%s=develop" % hash)
|
s = Spec("develop-branch-version@%s=develop" % hash)
|
||||||
|
Loading…
Reference in New Issue
Block a user