concretizer: don't require a provider for virtual deps if spec is external

This commit introduces a new rule:

real_node(Package) :- not external(Package), node(Package).

that permits to distinguish between an external node and a
real node that shouldn't trim dependency. It solves the
case of concretizing ninja with an external Python.
This commit is contained in:
Massimiliano Culpo 2020-11-11 19:21:27 +01:00 committed by Todd Gamblin
parent 44aa94a210
commit 9a03fd2834
5 changed files with 33 additions and 3 deletions

View file

@ -938,13 +938,13 @@ def package_dependencies_rules(self, pkg, tests):
# add constraints on the dependency from dep spec. # add constraints on the dependency from dep spec.
if spack.repo.path.is_virtual(dep.spec.name): if spack.repo.path.is_virtual(dep.spec.name):
self.virtual_constraints.add(str(dep.spec)) self.virtual_constraints.add(str(dep.spec))
conditions = ([fn.real_node(pkg.name)] +
self.spec_clauses(named_cond, body=True))
self.gen.rule( self.gen.rule(
head=fn.single_provider_for( head=fn.single_provider_for(
str(dep.spec.name), str(dep.spec.versions) str(dep.spec.name), str(dep.spec.versions)
), ),
body=self.gen._and( body=self.gen._and(*conditions)
*self.spec_clauses(named_cond, body=True)
)
) )
else: else:
clauses = self.spec_clauses(dep.spec) clauses = self.spec_clauses(dep.spec)

View file

@ -144,6 +144,9 @@ version_declared(Package, Version, Weight) :- external_version_declared(Package,
% if a package is not buildable (external_only), only externals are allowed % if a package is not buildable (external_only), only externals are allowed
external(Package) :- external_only(Package), node(Package). external(Package) :- external_only(Package), node(Package).
% a package is a real_node if it is not external
real_node(Package) :- node(Package), not external(Package).
% if an external version is selected, the package is external and % if an external version is selected, the package is external and
% we are using the corresponding spec % we are using the corresponding spec
external(Package) :- external(Package) :-

View file

@ -866,3 +866,9 @@ def test_external_packages_have_consistent_hash(self):
assert s.dag_hash() == t.dag_hash() assert s.dag_hash() == t.dag_hash()
assert s.build_hash() == t.build_hash() assert s.build_hash() == t.build_hash()
assert s.full_hash() == t.full_hash() assert s.full_hash() == t.full_hash()
def test_external_that_would_require_a_virtual_dependency(self):
s = Spec('requires-virtual').concretized()
assert s.external
assert 'stuff' not in s

View file

@ -22,3 +22,8 @@ packages:
- spec: externalmodule@1.0%gcc@4.5.0 - spec: externalmodule@1.0%gcc@4.5.0
modules: modules:
- external-module - external-module
'requires-virtual':
buildable: False
externals:
- spec: requires-virtual@2.0
prefix: /usr

View file

@ -0,0 +1,16 @@
# Copyright 2013-2020 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)
class RequiresVirtual(Package):
"""Package that requires a virtual dependency and is registered
as an external.
"""
homepage = "http://www.example.com"
url = "http://www.example.com/a-1.0.tar.gz"
version('2.0', '2.0_a_hash')
depends_on('stuff')