Allow using compilers from the local store
To do this we introduce a new fact, that is true when a compiler is used as a link dependency. If we don't have this fact, we enforce only run dependencies in the ASP problem.
This commit is contained in:
parent
56c685e374
commit
a8dd481bbf
@ -142,8 +142,7 @@ def _parse_link_paths(string):
|
|||||||
class CompilerPropertyDetector:
|
class CompilerPropertyDetector:
|
||||||
|
|
||||||
def __init__(self, compiler_spec: "spack.spec.Spec"):
|
def __init__(self, compiler_spec: "spack.spec.Spec"):
|
||||||
assert compiler_spec.external, "only external compiler specs are allowed, so far"
|
assert compiler_spec.concrete, "only concrete compiler specs are allowed"
|
||||||
assert compiler_spec.concrete, "only concrete compiler specs are allowed, so far"
|
|
||||||
self.spec = compiler_spec
|
self.spec = compiler_spec
|
||||||
self.cache = COMPILER_CACHE
|
self.cache = COMPILER_CACHE
|
||||||
|
|
||||||
@ -153,6 +152,11 @@ def compiler_environment(self):
|
|||||||
import spack.schema.environment
|
import spack.schema.environment
|
||||||
import spack.util.module_cmd
|
import spack.util.module_cmd
|
||||||
|
|
||||||
|
# No modifications for Spack managed compilers
|
||||||
|
if not self.spec.external:
|
||||||
|
yield
|
||||||
|
return
|
||||||
|
|
||||||
# Avoid modifying os.environ if possible.
|
# Avoid modifying os.environ if possible.
|
||||||
environment = self.spec.extra_attributes.get("environment", {})
|
environment = self.spec.extra_attributes.get("environment", {})
|
||||||
modules = self.spec.external_modules or []
|
modules = self.spec.external_modules or []
|
||||||
@ -178,7 +182,6 @@ def compiler_environment(self):
|
|||||||
os.environ.update(backup_env)
|
os.environ.update(backup_env)
|
||||||
|
|
||||||
def _compile_dummy_c_source(self) -> Optional[str]:
|
def _compile_dummy_c_source(self) -> Optional[str]:
|
||||||
assert self.spec.external, "only external compiler specs are allowed, so far"
|
|
||||||
compiler_pkg = self.spec.package
|
compiler_pkg = self.spec.package
|
||||||
if getattr(compiler_pkg, "cc"):
|
if getattr(compiler_pkg, "cc"):
|
||||||
cc = compiler_pkg.cc
|
cc = compiler_pkg.cc
|
||||||
@ -201,7 +204,7 @@ def _compile_dummy_c_source(self) -> Optional[str]:
|
|||||||
)
|
)
|
||||||
cc_exe = spack.util.executable.Executable(cc)
|
cc_exe = spack.util.executable.Executable(cc)
|
||||||
|
|
||||||
# FIXME (compiler as nodes): this operation should be encapsulated somewhere else
|
if self.spec.external:
|
||||||
compiler_flags = self.spec.extra_attributes.get("flags", {})
|
compiler_flags = self.spec.extra_attributes.get("flags", {})
|
||||||
for flag_type in [
|
for flag_type in [
|
||||||
"cflags" if cc == compiler_pkg.cc else "cxxflags",
|
"cflags" if cc == compiler_pkg.cc else "cxxflags",
|
||||||
@ -253,9 +256,6 @@ def implicit_rpaths(self) -> List[str]:
|
|||||||
link_dirs = parse_non_system_link_dirs(output)
|
link_dirs = parse_non_system_link_dirs(output)
|
||||||
all_required_libs = list(self.spec.package.required_libs) + ["libc", "libc++", "libstdc++"]
|
all_required_libs = list(self.spec.package.required_libs) + ["libc", "libc++", "libstdc++"]
|
||||||
dynamic_linker = self.default_dynamic_linker()
|
dynamic_linker = self.default_dynamic_linker()
|
||||||
# FIXME (compiler as nodes): is this needed ?
|
|
||||||
# if dynamic_linker is None:
|
|
||||||
# return []
|
|
||||||
result = DefaultDynamicLinkerFilter(dynamic_linker)(
|
result = DefaultDynamicLinkerFilter(dynamic_linker)(
|
||||||
paths_containing_libs(link_dirs, all_required_libs)
|
paths_containing_libs(link_dirs, all_required_libs)
|
||||||
)
|
)
|
||||||
|
@ -2987,6 +2987,7 @@ def setup(
|
|||||||
reuse: list of concrete specs that can be reused
|
reuse: list of concrete specs that can be reused
|
||||||
allow_deprecated: if True adds deprecated versions into the solve
|
allow_deprecated: if True adds deprecated versions into the solve
|
||||||
"""
|
"""
|
||||||
|
reuse = reuse or []
|
||||||
check_packages_exist(specs)
|
check_packages_exist(specs)
|
||||||
|
|
||||||
node_counter = create_counter(specs, tests=self.tests, possible_graph=self.possible_graph)
|
node_counter = create_counter(specs, tests=self.tests, possible_graph=self.possible_graph)
|
||||||
@ -3009,6 +3010,7 @@ def setup(
|
|||||||
self.explicitly_required_namespaces[node.name] = node.namespace
|
self.explicitly_required_namespaces[node.name] = node.namespace
|
||||||
|
|
||||||
self.gen = ProblemInstanceBuilder()
|
self.gen = ProblemInstanceBuilder()
|
||||||
|
self.gen.h1("Generic information")
|
||||||
if using_libc_compatibility():
|
if using_libc_compatibility():
|
||||||
for libc in self.libcs:
|
for libc in self.libcs:
|
||||||
self.gen.fact(fn.host_libc(libc.name, libc.version))
|
self.gen.fact(fn.host_libc(libc.name, libc.version))
|
||||||
@ -3016,6 +3018,10 @@ def setup(
|
|||||||
if not allow_deprecated:
|
if not allow_deprecated:
|
||||||
self.gen.fact(fn.deprecated_versions_not_allowed())
|
self.gen.fact(fn.deprecated_versions_not_allowed())
|
||||||
|
|
||||||
|
self.gen.newline()
|
||||||
|
for pkg_name in spack.compilers.config.supported_compilers():
|
||||||
|
self.gen.fact(fn.compiler_package(pkg_name))
|
||||||
|
|
||||||
# Calculate develop specs
|
# Calculate develop specs
|
||||||
# they will be used in addition to command line specs
|
# they will be used in addition to command line specs
|
||||||
# in determining known versions/targets/os
|
# in determining known versions/targets/os
|
||||||
@ -3032,6 +3038,17 @@ def setup(
|
|||||||
|
|
||||||
specs = tuple(specs) # ensure compatible types to add
|
specs = tuple(specs) # ensure compatible types to add
|
||||||
|
|
||||||
|
_ = spack.compilers.config.all_compilers(init_config=True)
|
||||||
|
self.possible_compilers = possible_compilers(configuration=spack.config.CONFIG)
|
||||||
|
for x in self.possible_compilers:
|
||||||
|
if x.external:
|
||||||
|
continue
|
||||||
|
reuse.append(x)
|
||||||
|
for dep in x.traverse(root=False, deptype="run"):
|
||||||
|
reuse.extend(dep.traverse(deptype=("link", "run")))
|
||||||
|
|
||||||
|
# reuse.extend([x for x in self.possible_compilers if not x.external])
|
||||||
|
|
||||||
self.gen.h1("Reusable concrete specs")
|
self.gen.h1("Reusable concrete specs")
|
||||||
self.define_concrete_input_specs(specs, self.pkgs)
|
self.define_concrete_input_specs(specs, self.pkgs)
|
||||||
if reuse:
|
if reuse:
|
||||||
@ -3040,9 +3057,6 @@ def setup(
|
|||||||
self.register_concrete_spec(reusable_spec, self.pkgs)
|
self.register_concrete_spec(reusable_spec, self.pkgs)
|
||||||
self.concrete_specs()
|
self.concrete_specs()
|
||||||
|
|
||||||
_ = spack.compilers.config.all_compilers(init_config=True)
|
|
||||||
self.possible_compilers = possible_compilers(configuration=spack.config.CONFIG)
|
|
||||||
|
|
||||||
self.gen.h1("Generic statements on possible packages")
|
self.gen.h1("Generic statements on possible packages")
|
||||||
node_counter.possible_packages_facts(self.gen, fn)
|
node_counter.possible_packages_facts(self.gen, fn)
|
||||||
|
|
||||||
@ -3391,9 +3405,9 @@ def value(self) -> str:
|
|||||||
|
|
||||||
def possible_compilers(*, configuration) -> List["spack.spec.Spec"]:
|
def possible_compilers(*, configuration) -> List["spack.spec.Spec"]:
|
||||||
result = set()
|
result = set()
|
||||||
for c in spack.compilers.config.all_compilers_from(configuration):
|
|
||||||
# FIXME (compiler as nodes): Discard early specs that are not marked for this target?
|
|
||||||
|
|
||||||
|
# Compilers defined in configuration
|
||||||
|
for c in spack.compilers.config.all_compilers_from(configuration):
|
||||||
if using_libc_compatibility() and not c_compiler_runs(c):
|
if using_libc_compatibility() and not c_compiler_runs(c):
|
||||||
try:
|
try:
|
||||||
compiler = c.extra_attributes["compilers"]["c"]
|
compiler = c.extra_attributes["compilers"]["c"]
|
||||||
@ -3419,6 +3433,10 @@ def possible_compilers(*, configuration) -> List["spack.spec.Spec"]:
|
|||||||
|
|
||||||
result.add(c)
|
result.add(c)
|
||||||
|
|
||||||
|
# Compilers from the local store
|
||||||
|
for pkg_name in spack.compilers.config.supported_compilers():
|
||||||
|
result.update(spack.store.STORE.db.query(pkg_name))
|
||||||
|
|
||||||
result = list(result)
|
result = list(result)
|
||||||
result.sort()
|
result.sort()
|
||||||
return result
|
return result
|
||||||
|
@ -1280,6 +1280,13 @@ attr("node_version_satisfies", node(X, Runtime), VersionRange) :-
|
|||||||
attr("compatible_runtime", PackageNode, Runtime, VersionRange),
|
attr("compatible_runtime", PackageNode, Runtime, VersionRange),
|
||||||
concrete(PackageNode).
|
concrete(PackageNode).
|
||||||
|
|
||||||
|
% If a compiler package is depended on with type link, it's used as a library
|
||||||
|
compiler_used_as_a_library(node(X, Child), Hash) :-
|
||||||
|
concrete(node(X, Child)),
|
||||||
|
attr("hash", node(X, Child), Hash),
|
||||||
|
compiler_package(Child), % Used to restrict grounding for this rule
|
||||||
|
attr("depends_on", _, node(X, Child), "link").
|
||||||
|
|
||||||
%-----------------------------------------------------------------------------
|
%-----------------------------------------------------------------------------
|
||||||
% Runtimes
|
% Runtimes
|
||||||
%-----------------------------------------------------------------------------
|
%-----------------------------------------------------------------------------
|
||||||
@ -1385,11 +1392,11 @@ language("c").
|
|||||||
language("cxx").
|
language("cxx").
|
||||||
language("fortran").
|
language("fortran").
|
||||||
|
|
||||||
% FIXME (compiler as nodes): remove when we lift this constraint
|
error(10, "Only external, or concrete, compilers are allowed for the {0} language", Language)
|
||||||
error(10, "Only external compilers are allowed for the {0} language", Language)
|
|
||||||
:- provider(ProviderNode, node(_, Language)),
|
:- provider(ProviderNode, node(_, Language)),
|
||||||
language(Language),
|
language(Language),
|
||||||
not external(ProviderNode).
|
not external(ProviderNode),
|
||||||
|
not concrete(ProviderNode).
|
||||||
|
|
||||||
error(10, "{0} compiler '{2}@{3}' incompatible with 'target={1}'", Package, Target, Compiler, Version)
|
error(10, "{0} compiler '{2}@{3}' incompatible with 'target={1}'", Package, Target, Compiler, Version)
|
||||||
:- attr("node_target", node(X, Package), Target),
|
:- attr("node_target", node(X, Package), Target),
|
||||||
@ -1467,32 +1474,53 @@ hash_attr(Hash, "node_version_satisfies", PackageName, Constraint) :-
|
|||||||
% This recovers the exact semantics for hash reuse hash and depends_on are where
|
% This recovers the exact semantics for hash reuse hash and depends_on are where
|
||||||
% splices are decided, and virtual_on_edge can result in name-changes, which is
|
% splices are decided, and virtual_on_edge can result in name-changes, which is
|
||||||
% why they are all treated separately.
|
% why they are all treated separately.
|
||||||
imposed_constraint(Hash, Attr, PackageName) :-
|
|
||||||
hash_attr(Hash, Attr, PackageName).
|
imposed_constraint(Hash, Attr, PackageName) :- hash_attr(Hash, Attr, PackageName), Attr != "virtual_node".
|
||||||
imposed_constraint(Hash, Attr, PackageName, A1) :-
|
|
||||||
hash_attr(Hash, Attr, PackageName, A1), Attr != "hash".
|
imposed_constraint(Hash, Attr, PackageName, A1) :- hash_attr(Hash, Attr, PackageName, A1), Attr != "hash".
|
||||||
imposed_constraint(Hash, Attr, PackageName, Arg1, Arg2) :-
|
|
||||||
hash_attr(Hash, Attr, PackageName, Arg1, Arg2),
|
imposed_constraint(Hash, Attr, PackageName, A1, A2) :-
|
||||||
|
hash_attr(Hash, Attr, PackageName, A1, A2),
|
||||||
Attr != "depends_on",
|
Attr != "depends_on",
|
||||||
Attr != "virtual_on_edge".
|
Attr != "virtual_on_edge".
|
||||||
imposed_constraint(Hash, Attr, PackageName, A1, A2, A3) :-
|
|
||||||
hash_attr(Hash, Attr, PackageName, A1, A2, A3).
|
imposed_constraint(Hash, Attr, PackageName, A1, A2, A3) :- hash_attr(Hash, Attr, PackageName, A1, A2, A3).
|
||||||
imposed_constraint(Hash, "hash", PackageName, Hash) :- installed_hash(PackageName, Hash).
|
imposed_constraint(Hash, "hash", PackageName, Hash) :- installed_hash(PackageName, Hash).
|
||||||
|
|
||||||
|
% If a compiler is not used as a library, we just enforce "run" dependency, so we
|
||||||
|
% can get by with a much smaller search space.
|
||||||
|
avoid_compiler_link_dependency(Hash, DepName) :-
|
||||||
|
hash_attr(Hash, "depends_on", PackageName, DepName, "link"),
|
||||||
|
not hash_attr(Hash, "depends_on", PackageName, DepName, "run"),
|
||||||
|
hash_attr(Hash, "hash", DepName, DepHash),
|
||||||
|
compiler_package(PackageName),
|
||||||
|
not compiler_used_as_a_library(node(_, PackageName), Hash).
|
||||||
|
|
||||||
% Without splicing, we simply recover the exact semantics
|
% Without splicing, we simply recover the exact semantics
|
||||||
imposed_constraint(ParentHash, "hash", ChildName, ChildHash) :-
|
imposed_constraint(ParentHash, "hash", ChildName, ChildHash) :-
|
||||||
hash_attr(ParentHash, "hash", ChildName, ChildHash),
|
hash_attr(ParentHash, "hash", ChildName, ChildHash),
|
||||||
ChildHash != ParentHash,
|
ChildHash != ParentHash,
|
||||||
|
not avoid_compiler_link_dependency(ParentHash, ChildName),
|
||||||
not abi_splice_conditions_hold(_, _, ChildName, ChildHash).
|
not abi_splice_conditions_hold(_, _, ChildName, ChildHash).
|
||||||
|
|
||||||
imposed_constraint(Hash, "depends_on", PackageName, DepName, Type) :-
|
imposed_constraint(Hash, "depends_on", PackageName, DepName, Type) :-
|
||||||
hash_attr(Hash, "depends_on", PackageName, DepName, Type),
|
hash_attr(Hash, "depends_on", PackageName, DepName, Type),
|
||||||
hash_attr(Hash, "hash", DepName, DepHash),
|
hash_attr(Hash, "hash", DepName, DepHash),
|
||||||
|
not avoid_compiler_link_dependency(Hash, DepName),
|
||||||
not attr("splice_at_hash", _, _, DepName, DepHash).
|
not attr("splice_at_hash", _, _, DepName, DepHash).
|
||||||
|
|
||||||
imposed_constraint(Hash, "virtual_on_edge", PackageName, DepName, VirtName) :-
|
imposed_constraint(Hash, "virtual_on_edge", PackageName, DepName, VirtName) :-
|
||||||
hash_attr(Hash, "virtual_on_edge", PackageName, DepName, VirtName),
|
hash_attr(Hash, "virtual_on_edge", PackageName, DepName, VirtName),
|
||||||
|
not avoid_compiler_link_dependency(Hash, DepName),
|
||||||
not attr("splice_at_hash", _, _, DepName,_).
|
not attr("splice_at_hash", _, _, DepName,_).
|
||||||
|
|
||||||
|
imposed_constraint(Hash, "virtual_node", VirtName) :-
|
||||||
|
hash_attr(Hash, "virtual_on_edge", PackageName, DepName, VirtName),
|
||||||
|
hash_attr(Hash, "virtual_node", VirtName),
|
||||||
|
not avoid_compiler_link_dependency(Hash, DepName),
|
||||||
|
not attr("splice_at_hash", _, _, DepName,_).
|
||||||
|
|
||||||
|
|
||||||
% Rules pertaining to attr("splice_at_hash") and abi_splice_conditions_hold will
|
% Rules pertaining to attr("splice_at_hash") and abi_splice_conditions_hold will
|
||||||
% be conditionally loaded from splices.lp
|
% be conditionally loaded from splices.lp
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user