Skip to content

Commit

Permalink
Quick fix for relocation issues.
Browse files Browse the repository at this point in the history
  • Loading branch information
tgamblin authored and JBlaschke committed Jun 1, 2020
1 parent 0ae8239 commit 1eabd32
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 20 deletions.
70 changes: 50 additions & 20 deletions lib/spack/spack/binary_distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@
from spack.util.gpg import Gpg
import spack.architecture as architecture

_build_cache_relative_path = 'build_cache'
_relocation_blacklist = (".spack", "man")


class NoOverwriteException(Exception):
pass

BUILD_CACHE_INDEX_TEMPLATE = '''
<html>
Expand Down Expand Up @@ -146,25 +150,14 @@ def read_buildinfo_file(prefix):
return buildinfo


def write_buildinfo_file(spec, workdir, rel=False):
"""
Create a cache file containing information
required for the relocation
"""
prefix = spec.prefix
def _find_relocations(prefix):
text_to_relocate = []
binary_to_relocate = []
link_to_relocate = []
blacklist = (".spack", "man")
prefix_to_hash = dict()
prefix_to_hash[str(spec.package.prefix)] = spec.dag_hash()
deps = spack.build_environment.get_rpath_deps(spec.package)
for d in deps:
prefix_to_hash[str(d.prefix)] = d.dag_hash()
# Do this at during tarball creation to save time when tarball unpacked.
# Used by make_package_relative to determine binaries to change.
for root, dirs, files in os.walk(prefix, topdown=True):
dirs[:] = [d for d in dirs if d not in blacklist]
dirs[:] = [d for d in dirs if d not in _relocation_blacklist]

for filename in files:
path_name = os.path.join(root, filename)
m_type, m_subtype = relocate.mime_type(path_name)
Expand All @@ -189,6 +182,16 @@ def write_buildinfo_file(spec, workdir, rel=False):
rel_path_name = os.path.relpath(path_name, prefix)
text_to_relocate.append(rel_path_name)

return text_to_relocate, binary_to_relocate


def write_buildinfo_file(prefix, rel=False):
"""
Create a cache file containing information
required for the relocation
"""
text_to_relocate, binary_to_relocate = _find_relocations(prefix)

# Create buildinfo data and write it to disk
buildinfo = {}
buildinfo['relative_rpaths'] = rel
Expand Down Expand Up @@ -528,11 +531,38 @@ def check_package_relocatable(workdir, spec, allow_root):
Check if package binaries are relocatable.
Change links to placeholder links.
"""
buildinfo = read_buildinfo_file(workdir)
cur_path_names = list()
for filename in buildinfo['relocate_binaries']:
cur_path_names.append(os.path.join(workdir, filename))
relocate.raise_if_not_relocatable(cur_path_names, allow_root)
buildinfo = read_buildinfo_file(prefix)
new_path = spack.store.layout.root
old_path = buildinfo['buildpath']
rel = buildinfo.get('relative_rpaths', False)
if new_path == old_path and not rel:
return

text_relocs = buildinfo['relocate_textfiles']
binary_relocs = buildinfo['relocate_binaries']

# if there are no relocations, search for them instead
# TODO: revisit this in a 0.11 point release
if not text_relocs or not binary_relocs:
text_relocs, binary_relocs = _find_relocations(prefix)
rel = False

tty.msg("Relocating package from",
"%s to %s." % (old_path, new_path))
path_names = set()
for filename in text_relocs:
path_name = os.path.join(prefix, filename)
path_names.add(path_name)
relocate.relocate_text(path_names, old_path, new_path)

# If the binary files in the package were not edited to use
# relative RPATHs, then the RPATHs need to be relocated
if not rel:
path_names = set()
for filename in binary_relocs:
path_name = os.path.join(prefix, filename)
path_names.add(path_name)
relocate.relocate_binary(path_names, old_path, new_path)


def relocate_package(spec, allow_root):
Expand Down
12 changes: 12 additions & 0 deletions lib/spack/spack/relocate.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,18 @@ def relocate_macho_binaries(path_names, old_layout_root, new_layout_root,
prefixes to hashes and the dictionary mapping hashes to the new layout
prefixes.
"""
retval = False
if "relocatable" in filetype:
return False
if "symbolic link" in filetype:
return False
if platform.system() == 'Darwin':
return ('Mach-O' in filetype)
elif platform.system() == 'Linux':
return ('ELF' in filetype)
else:
tty.die("Relocation not implemented for %s" % platform.system())
return retval

for path_name in path_names:
# Corner case where macho object file ended up in the path name list
Expand Down

0 comments on commit 1eabd32

Please sign in to comment.