From 4ee37c37de98c67e61ad9cba028cfd8d54136d3a Mon Sep 17 00:00:00 2001 From: Paul Ferrell <51765748+Paul-Ferrell@users.noreply.github.com> Date: Thu, 28 Oct 2021 06:34:31 -0600 Subject: buildcaches: fix directory link relocation (#26948) When relocating a binary distribution, Spack only checks files to see if they are a link that needs to be relocated. Directories can be such links as well, however, and need to undergo the same checks and potential relocation. --- lib/spack/spack/binary_distribution.py | 10 +++++ lib/spack/spack/test/bindist.py | 10 +++-- .../repos/builtin.mock/packages/symly/package.py | 45 ++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 var/spack/repos/builtin.mock/packages/symly/package.py diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py index 165ba219b3..0cf254b582 100644 --- a/lib/spack/spack/binary_distribution.py +++ b/lib/spack/spack/binary_distribution.py @@ -608,6 +608,16 @@ def get_buildfile_manifest(spec): # Used by make_package_relative to determine binaries to change. for root, dirs, files in os.walk(spec.prefix, topdown=True): dirs[:] = [d for d in dirs if d not in blacklist] + + # Directories may need to be relocated too. + for directory in dirs: + dir_path_name = os.path.join(root, directory) + rel_path_name = os.path.relpath(dir_path_name, spec.prefix) + if os.path.islink(dir_path_name): + link = os.readlink(dir_path_name) + if os.path.isabs(link) and link.startswith(spack.store.layout.root): + data['link_to_relocate'].append(rel_path_name) + for filename in files: path_name = os.path.join(root, filename) m_type, m_subtype = relocate.mime_type(path_name) diff --git a/lib/spack/spack/test/bindist.py b/lib/spack/spack/test/bindist.py index dbcf0d8ea6..8dc0cb68d6 100644 --- a/lib/spack/spack/test/bindist.py +++ b/lib/spack/spack/test/bindist.py @@ -200,12 +200,14 @@ def test_default_rpaths_create_install_default_layout(mirror_dir): into the default directory layout scheme. """ gspec, cspec = Spec('garply').concretized(), Spec('corge').concretized() + sy_spec = Spec('symly').concretized() # Install 'corge' without using a cache install_cmd('--no-cache', cspec.name) + install_cmd('--no-cache', sy_spec.name) # Create a buildache - buildcache_cmd('create', '-au', '-d', mirror_dir, cspec.name) + buildcache_cmd('create', '-au', '-d', mirror_dir, cspec.name, sy_spec.name) # Test force overwrite create buildcache (-f option) buildcache_cmd('create', '-auf', '-d', mirror_dir, cspec.name) @@ -219,7 +221,7 @@ def test_default_rpaths_create_install_default_layout(mirror_dir): uninstall_cmd('-y', '--dependents', gspec.name) # Test installing from build caches - buildcache_cmd('install', '-au', cspec.name) + buildcache_cmd('install', '-au', cspec.name, sy_spec.name) # This gives warning that spec is already installed buildcache_cmd('install', '-au', cspec.name) @@ -247,10 +249,12 @@ def test_default_rpaths_install_nondefault_layout(mirror_dir): into the non-default directory layout scheme. """ cspec = Spec('corge').concretized() + # This guy tests for symlink relocation + sy_spec = Spec('symly').concretized() # Install some packages with dependent packages # test install in non-default install path scheme - buildcache_cmd('install', '-au', cspec.name) + buildcache_cmd('install', '-au', cspec.name, sy_spec.name) # Test force install in non-default install path scheme buildcache_cmd('install', '-auf', cspec.name) diff --git a/var/spack/repos/builtin.mock/packages/symly/package.py b/var/spack/repos/builtin.mock/packages/symly/package.py new file mode 100644 index 0000000000..a22e3cef09 --- /dev/null +++ b/var/spack/repos/builtin.mock/packages/symly/package.py @@ -0,0 +1,45 @@ +# Copyright 2013-2021 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) + + +import os +import sys + +from spack import * + + +class Symly(Package): + """A toy package full of symlinks.""" + + homepage = "https://www.example.com" + has_code = False + version('3.0.0') + + def install(self, spec, prefix): + symly_c = ''' +#include + +int main() { + printf("I'm just here to give the build system something to do..."); + return 0; +} +''' + mkdirp('%s/symly' % self.stage.source_path) + with open('%s/symly/symly.c' % self.stage.source_path, 'w') as f: + f.write(symly_c) + gcc = which('/usr/bin/gcc') + if sys.platform == 'darwin': + gcc = which('/usr/bin/clang') + mkdirp(prefix.bin) + mkdirp(prefix.lib64) + gcc('-o', 'symly.bin', + 'symly/symly.c') + print("prefix.bin", prefix.bin) + copy('symly.bin', '%s/symly' % prefix.bin) + # create a symlinked file. + os.symlink('%s/symly' % prefix.bin, + '%s/symly' % prefix.lib64) + # Create a symlinked directory. + os.symlink(prefix.bin, prefix.include) -- cgit v1.2.3-70-g09d2