Exemplo n.º 1
0
def relocate_package(workdir, spec, allow_root):
    """
    Relocate the given package
    """
    buildinfo = read_buildinfo_file(workdir)
    new_path = str(spack.store.layout.root)
    new_prefix = str(spack.paths.prefix)
    old_path = str(buildinfo['buildpath'])
    old_prefix = str(
        buildinfo.get('spackprefix', '/not/in/buildinfo/dictionary'))
    rel = buildinfo.get('relative_rpaths', False)
    if rel:
        return

    tty.msg("Relocating package from", "%s to %s." % (old_path, new_path))
    path_names = set()
    for filename in buildinfo['relocate_textfiles']:
        path_name = os.path.join(workdir, filename)
        # Don't add backup files generated by filter_file during install step.
        if not path_name.endswith('~'):
            path_names.add(path_name)
    relocate.relocate_text(path_names,
                           oldpath=old_path,
                           newpath=new_path,
                           oldprefix=old_prefix,
                           newprefix=new_prefix)
    # If the binary files in the package were not edited to use
    # relative RPATHs, then the RPATHs need to be relocated
    if rel:
        if old_path != new_path:
            files_to_relocate = list(
                filter(
                    lambda pathname: not relocate.file_is_relocatable(
                        pathname, paths_to_relocate=[old_path, old_prefix]),
                    map(lambda filename: os.path.join(workdir, filename),
                        buildinfo['relocate_binaries'])))

            if len(old_path) < len(new_path) and files_to_relocate:
                tty.debug('Cannot do a binary string replacement with padding '
                          'for package because %s is longer than %s.' %
                          (new_path, old_path))
            else:
                for path_name in files_to_relocate:
                    relocate.replace_prefix_bin(path_name, old_path, new_path)
    else:
        path_names = set()
        for filename in buildinfo['relocate_binaries']:
            path_name = os.path.join(workdir, filename)
            path_names.add(path_name)
        if spec.architecture.platform == 'darwin':
            relocate.relocate_macho_binaries(path_names, old_path, new_path,
                                             allow_root)
        else:
            relocate.relocate_elf_binaries(path_names, old_path, new_path,
                                           allow_root)
        path_names = set()
        for filename in buildinfo.get('relocate_links', []):
            path_name = os.path.join(workdir, filename)
            path_names.add(path_name)
        relocate.relocate_links(path_names, old_path, new_path)
Exemplo n.º 2
0
def relocate_package(workdir, spec, allow_root):
    """
    Relocate the given package
    """
    buildinfo = read_buildinfo_file(workdir)
    new_path = spack.store.layout.root
    new_prefix = spack.paths.prefix
    old_path = buildinfo['buildpath']
    old_prefix = buildinfo.get('spackprefix', '/not/in/buildinfo/dictionary')
    rel = buildinfo.get('relative_rpaths', False)
    if rel:
        return

    tty.msg("Relocating package from",
            "%s to %s." % (old_path, new_path))
    path_names = set()
    for filename in buildinfo['relocate_textfiles']:
        path_name = os.path.join(workdir, filename)
        # Don't add backup files generated by filter_file during install step.
        if not path_name.endswith('~'):
            path_names.add(path_name)
    relocate.relocate_text(path_names, oldpath=old_path,
                           newpath=new_path, oldprefix=old_prefix,
                           newprefix=new_prefix)
    # 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 buildinfo['relocate_binaries']:
            path_name = os.path.join(workdir, filename)
            path_names.add(path_name)
        if spec.architecture.platform == 'darwin':
            relocate.relocate_macho_binaries(path_names, old_path,
                                             new_path, allow_root)
        else:
            relocate.relocate_elf_binaries(path_names, old_path,
                                           new_path, allow_root)
        path_names = set()
        for filename in buildinfo.get('relocate_links', []):
            path_name = os.path.join(workdir, filename)
            path_names.add(path_name)
        relocate.relocate_links(path_names, old_path, new_path)
Exemplo n.º 3
0
def rewire_node(spec, explicit):
    """This function rewires a single node, worrying only about references to
    its subgraph. Binaries, text, and links are all changed in accordance with
    the splice. The resulting package is then 'installed.'"""
    tempdir = tempfile.mkdtemp()
    # copy anything installed to a temporary directory
    shutil.copytree(spec.build_spec.prefix,
                    os.path.join(tempdir, spec.dag_hash()))

    spack.hooks.pre_install(spec)
    # compute prefix-to-prefix for every node from the build spec to the spliced
    # spec
    prefix_to_prefix = OrderedDict({spec.build_spec.prefix: spec.prefix})
    for build_dep in spec.build_spec.traverse(root=False):
        prefix_to_prefix[build_dep.prefix] = spec[build_dep.name].prefix

    manifest = bindist.get_buildfile_manifest(spec.build_spec)
    platform = spack.platforms.by_name(spec.platform)

    text_to_relocate = [
        os.path.join(tempdir, spec.dag_hash(), rel_path)
        for rel_path in manifest.get('text_to_relocate', [])
    ]
    if text_to_relocate:
        relocate.relocate_text(files=text_to_relocate,
                               prefixes=prefix_to_prefix)

    bins_to_relocate = [
        os.path.join(tempdir, spec.dag_hash(), rel_path)
        for rel_path in manifest.get('binary_to_relocate', [])
    ]
    if bins_to_relocate:
        if 'macho' in platform.binary_formats:
            relocate.relocate_macho_binaries(bins_to_relocate,
                                             str(spack.store.layout.root),
                                             str(spack.store.layout.root),
                                             prefix_to_prefix, False,
                                             spec.build_spec.prefix,
                                             spec.prefix)
        if 'elf' in platform.binary_formats:
            relocate.relocate_elf_binaries(bins_to_relocate,
                                           str(spack.store.layout.root),
                                           str(spack.store.layout.root),
                                           prefix_to_prefix, False,
                                           spec.build_spec.prefix, spec.prefix)
        relocate.relocate_text_bin(binaries=bins_to_relocate,
                                   prefixes=prefix_to_prefix)
    # Copy package into place, except for spec.json (because spec.json
    # describes the old spec and not the new spliced spec).
    shutil.copytree(os.path.join(tempdir, spec.dag_hash()),
                    spec.prefix,
                    ignore=shutil.ignore_patterns('spec.json',
                                                  'install_manifest.json'))
    if manifest.get('link_to_relocate'):
        _relocate_spliced_links(manifest.get('link_to_relocate'),
                                spec.build_spec.prefix, spec.prefix)
    shutil.rmtree(tempdir)
    # Above, we did not copy spec.json: instead, here we write the new
    # (spliced) spec into spec.json, without this, Database.add would fail on
    # the next line (because it checks the spec.json in the prefix against the
    # spec being added to look for mismatches)
    spack.store.layout.write_spec(spec,
                                  spack.store.layout.spec_file_path(spec))
    # add to database, not sure about explicit
    spack.store.db.add(spec, spack.store.layout, explicit=explicit)

    # run post install hooks
    spack.hooks.post_install(spec)
Exemplo n.º 4
0
def relocate_package(spec, allow_root):
    """
    Relocate the given package
    """
    workdir = str(spec.prefix)
    buildinfo = read_buildinfo_file(workdir)
    new_layout_root = str(spack.store.layout.root)
    new_prefix = str(spec.prefix)
    new_rel_prefix = str(os.path.relpath(new_prefix, new_layout_root))
    new_spack_prefix = str(spack.paths.prefix)
    old_layout_root = str(buildinfo['buildpath'])
    old_spack_prefix = str(buildinfo.get('spackprefix'))
    old_rel_prefix = buildinfo.get('relative_prefix')
    old_prefix = os.path.join(old_layout_root, old_rel_prefix)
    rel = buildinfo.get('relative_rpaths')
    prefix_to_hash = buildinfo.get('prefix_to_hash', None)
    if (old_rel_prefix != new_rel_prefix and not prefix_to_hash):
        msg = "Package tarball was created from an install "
        msg += "prefix with a different directory layout and an older "
        msg += "buildcache create implementation. It cannot be relocated."
        raise NewLayoutException(msg)
    # older buildcaches do not have the prefix_to_hash dictionary
    # need to set an empty dictionary and add one entry to
    # prefix_to_prefix to reproduce the old behavior
    if not prefix_to_hash:
        prefix_to_hash = dict()
    hash_to_prefix = dict()
    hash_to_prefix[spec.format('{hash}')] = str(spec.package.prefix)
    new_deps = spack.build_environment.get_rpath_deps(spec.package)
    for d in new_deps:
        hash_to_prefix[d.format('{hash}')] = str(d.prefix)
    prefix_to_prefix = dict()
    for orig_prefix, hash in prefix_to_hash.items():
        prefix_to_prefix[orig_prefix] = hash_to_prefix.get(hash, None)
    prefix_to_prefix[old_prefix] = new_prefix
    prefix_to_prefix[old_layout_root] = new_layout_root

    tty.debug("Relocating package from",
              "%s to %s." % (old_layout_root, new_layout_root))

    def is_backup_file(file):
        return file.endswith('~')

    # Text files containing the prefix text
    text_names = list()
    for filename in buildinfo['relocate_textfiles']:
        text_name = os.path.join(workdir, filename)
        # Don't add backup files generated by filter_file during install step.
        if not is_backup_file(text_name):
            text_names.append(text_name)

# If we are not installing back to the same install tree do the relocation
    if old_layout_root != new_layout_root:
        files_to_relocate = [
            os.path.join(workdir, filename)
            for filename in buildinfo.get('relocate_binaries')
        ]
        # If the buildcache was not created with relativized rpaths
        # do the relocation of path in binaries
        if (spec.architecture.platform == 'darwin'
                or spec.architecture.platform == 'test'
                and platform.system().lower() == 'darwin'):
            relocate.relocate_macho_binaries(files_to_relocate,
                                             old_layout_root, new_layout_root,
                                             prefix_to_prefix, rel, old_prefix,
                                             new_prefix)
        if (spec.architecture.platform == 'linux'
                or spec.architecture.platform == 'test'
                and platform.system().lower() == 'linux'):
            relocate.relocate_elf_binaries(files_to_relocate, old_layout_root,
                                           new_layout_root, prefix_to_prefix,
                                           rel, old_prefix, new_prefix)
            # Relocate links to the new install prefix
            links = [link for link in buildinfo.get('relocate_links', [])]
            relocate.relocate_links(links, old_layout_root, old_prefix,
                                    new_prefix)

        # For all buildcaches
        # relocate the install prefixes in text files including dependencies
        relocate.relocate_text(text_names, old_layout_root, new_layout_root,
                               old_prefix, new_prefix, old_spack_prefix,
                               new_spack_prefix, prefix_to_prefix)

        paths_to_relocate = [old_prefix, old_layout_root]
        paths_to_relocate.extend(prefix_to_hash.keys())
        files_to_relocate = list(
            filter(
                lambda pathname: not relocate.file_is_relocatable(
                    pathname, paths_to_relocate=paths_to_relocate),
                map(lambda filename: os.path.join(workdir, filename),
                    buildinfo['relocate_binaries'])))
        # relocate the install prefixes in binary files including dependencies
        relocate.relocate_text_bin(files_to_relocate, old_prefix, new_prefix,
                                   old_spack_prefix, new_spack_prefix,
                                   prefix_to_prefix)


# If we are installing back to the same location
# relocate the sbang location if the spack directory changed
    else:
        if old_spack_prefix != new_spack_prefix:
            relocate.relocate_text(text_names, old_layout_root,
                                   new_layout_root, old_prefix, new_prefix,
                                   old_spack_prefix, new_spack_prefix,
                                   prefix_to_prefix)