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 collections import defaultdict
|
||||||
from enum import Flag, auto
|
from enum import Flag, auto
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import List, Set, Tuple
|
from typing import Dict, List, Set, Tuple
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.string import plural
|
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)
|
return compiler(*compiler_args, output=compiler_output)
|
||||||
|
|
||||||
|
|
||||||
def get_rpath_deps(pkg):
|
def _get_rpath_deps_from_spec(
|
||||||
"""Return immediate or transitive RPATHs depending on the package."""
|
spec: spack.spec.Spec, transitive_rpaths: bool
|
||||||
if pkg.transitive_rpaths:
|
) -> List[spack.spec.Spec]:
|
||||||
return [d for d in pkg.spec.traverse(root=False, deptype=("link"))]
|
if not transitive_rpaths:
|
||||||
else:
|
return spec.dependencies(deptype=dt.LINK)
|
||||||
return pkg.spec.dependencies(deptype="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):
|
def get_rpaths(pkg):
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
import spack.build_environment
|
import spack.build_environment
|
||||||
import spack.config
|
import spack.config
|
||||||
|
import spack.deptypes as dt
|
||||||
import spack.package_base
|
import spack.package_base
|
||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.util.spack_yaml as syaml
|
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 depth, spec in root.traverse(depth=True, root=True):
|
||||||
for variable in build_variables:
|
for variable in build_variables:
|
||||||
assert hasattr(spec.package.module, variable) == should_be_set(depth)
|
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