Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions news/zipapp-absolute-source-symlinks.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(zipapp) Shared libraries that a {obj}`py_zipapp_binary` reaches through
Bazel's `_solib` symlinks are stored as files again, instead of as symlinks to
absolute paths in the build machine's output base that dangle wherever the
zipapp runs.
30 changes: 30 additions & 0 deletions tests/tools/zipapp/zipper_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,36 @@ def test_create_zip_with_sandboxed_source_symlink(tmp_path):
assert_zip_file_content(zf, "runfiles/my_ws/bin/python3.14", content="python")


def test_create_zip_with_sandboxed_absolute_source_symlink(tmp_path):
# Bazel's _solib entries are absolute symlinks into the output base. Their
# target only exists on the build machine, so the file must be stored.
manifest_path = tmp_path / "manifest.txt"
output_zip = tmp_path / "output.zip"

library_dir = tmp_path / "external"
library_dir.mkdir()
library = library_dir / "libfoo.so"
library.write_text("library")

solib_dir = tmp_path / "solib"
solib_dir.mkdir()
solib_link = solib_dir / "libfoo.so"
solib_link.symlink_to(library)

sandbox_dir = tmp_path / "sandbox"
sandbox_dir.mkdir()
sandbox_link = sandbox_dir / "libfoo.so"
sandbox_link.symlink_to(solib_link)
manifest_path.write_text(f"rf-file|0|_solib/libfoo.so|{sandbox_link}")

create_zip(manifest_path, output_zip)

with zipfile.ZipFile(output_zip, "r") as zf:
assert_zip_file_content(
zf, "runfiles/my_ws/_solib/libfoo.so", content="library"
)


def test_pathsep_normalization(tmp_path):
manifest_path = tmp_path / "manifest.txt"
output_zip = tmp_path / "output.zip"
Expand Down
7 changes: 6 additions & 1 deletion tools/zipapp/zipper.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,13 @@ def _source_symlink_target(content_path, is_symlink_str):

# Bazel sandboxes expose regular inputs as absolute symlinks. Look through
# that indirection to detect whether the original source is also a symlink.
# Only a relative link can be kept: an absolute one points into this
# machine's Bazel output base (e.g. the _solib links Bazel creates for shared
# libraries) and would dangle wherever the zipapp runs, so store the file.
if os.path.islink(target):
return os.readlink(target)
source_target = os.readlink(target)
if not os.path.isabs(source_target):
return source_target
return None


Expand Down
Loading