build_environment.py: deal with rpathing identical packages (#44219)
When multiple gcc-runtime packages exist in the same link sub-dag, only rpath the latest.
This commit is contained in:
parent
47af0159dc
commit
97369776f0
2 changed files with 42 additions and 7 deletions
|
@ -43,7 +43,7 @@
|
|||
from collections import defaultdict
|
||||
from enum import Flag, auto
|
||||
from itertools import chain
|
||||
from typing import List, Set, Tuple
|
||||
from typing import Dict, List, Set, Tuple
|
||||
|
||||
import llnl.util.tty as tty
|
||||
from llnl.string import plural
|
||||
|
@ -730,12 +730,28 @@ def _static_to_shared_library(arch, compiler, static_lib, shared_lib=None, **kwa
|
|||
return compiler(*compiler_args, output=compiler_output)
|
||||
|
||||
|
||||
def get_rpath_deps(pkg):
|
||||
"""Return immediate or transitive RPATHs depending on the package."""
|
||||
if pkg.transitive_rpaths:
|
||||
return [d for d in pkg.spec.traverse(root=False, deptype=("link"))]
|
||||
else:
|
||||
return pkg.spec.dependencies(deptype="link")
|
||||
def _get_rpath_deps_from_spec(
|
||||
spec: spack.spec.Spec, transitive_rpaths: bool
|
||||
) -> List[spack.spec.Spec]:
|
||||
if not transitive_rpaths:
|
||||
return spec.dependencies(deptype=dt.LINK)
|
||||
|
||||
by_name: Dict[str, spack.spec.Spec] = {}
|
||||
|
||||
for dep in spec.traverse(root=False, deptype=dt.LINK):
|
||||
lookup = by_name.get(dep.name)
|
||||
if lookup is None:
|
||||
by_name[dep.name] = dep
|
||||
elif lookup.version < dep.version:
|
||||
by_name[dep.name] = dep
|
||||
|
||||
return list(by_name.values())
|
||||
|
||||
|
||||
def get_rpath_deps(pkg: spack.package_base.PackageBase) -> List[spack.spec.Spec]:
|
||||
"""Return immediate or transitive dependencies (depending on the package) that need to be
|
||||
rpath'ed. If a package occurs multiple times, the newest version is kept."""
|
||||
return _get_rpath_deps_from_spec(pkg.spec, pkg.transitive_rpaths)
|
||||
|
||||
|
||||
def get_rpaths(pkg):
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import spack.build_environment
|
||||
import spack.config
|
||||
import spack.deptypes as dt
|
||||
import spack.package_base
|
||||
import spack.spec
|
||||
import spack.util.spack_yaml as syaml
|
||||
|
@ -716,3 +717,21 @@ def test_build_system_globals_only_set_on_root_during_build(default_mock_concret
|
|||
for depth, spec in root.traverse(depth=True, root=True):
|
||||
for variable in build_variables:
|
||||
assert hasattr(spec.package.module, variable) == should_be_set(depth)
|
||||
|
||||
|
||||
def test_rpath_with_duplicate_link_deps():
|
||||
"""If we have two instances of one package in the same link sub-dag, only the newest version is
|
||||
rpath'ed. This is for runtime support without splicing."""
|
||||
runtime_1 = spack.spec.Spec("runtime@=1.0")
|
||||
runtime_2 = spack.spec.Spec("runtime@=2.0")
|
||||
child = spack.spec.Spec("child@=1.0")
|
||||
root = spack.spec.Spec("root@=1.0")
|
||||
|
||||
root.add_dependency_edge(child, depflag=dt.LINK, virtuals=())
|
||||
root.add_dependency_edge(runtime_2, depflag=dt.LINK, virtuals=())
|
||||
child.add_dependency_edge(runtime_1, depflag=dt.LINK, virtuals=())
|
||||
|
||||
rpath_deps = spack.build_environment._get_rpath_deps_from_spec(root, transitive_rpaths=True)
|
||||
assert child in rpath_deps
|
||||
assert runtime_2 in rpath_deps
|
||||
assert runtime_1 not in rpath_deps
|
||||
|
|
Loading…
Reference in a new issue