mirror of
https://github.com/pyenv/pyenv.git
synced 2026-10-03 07:51:06 +09:00
pyenv-binary: record direct system dependencies in Linux/FreeBSD (#3520)
This commit is contained in:
parent
0f16606e4f
commit
50fbc8c6cc
@ -92,12 +92,16 @@ fi
|
|||||||
if [ "$os" = "Linux" ]; then
|
if [ "$os" = "Linux" ]; then
|
||||||
libc="$(getconf GNU_LIBC_VERSION 2>/dev/null || true)"
|
libc="$(getconf GNU_LIBC_VERSION 2>/dev/null || true)"
|
||||||
fi
|
fi
|
||||||
|
if [ "$os" != "Darwin" ] && ! LC_ALL=C readelf --version &>/dev/null; then
|
||||||
|
echo "pyenv-binary: need readelf to inspect shared libraries" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# List the external shared libraries the install links against: those that
|
# List the external shared libraries the install links against: those that
|
||||||
# resolve outside its own prefix, so they must already exist on the target.
|
# resolve outside its own prefix, so they must already exist on the target.
|
||||||
# The interpreter plus every bundled shared object are inspected.
|
# The interpreter plus every bundled shared object are inspected.
|
||||||
system_deps() {
|
system_deps() {
|
||||||
local f
|
local f needed
|
||||||
{
|
{
|
||||||
for f in "${prefix}"/bin/python*; do
|
for f in "${prefix}"/bin/python*; do
|
||||||
[ -e "$f" ] && printf '%s\n' "$f"
|
[ -e "$f" ] && printf '%s\n' "$f"
|
||||||
@ -111,8 +115,19 @@ system_deps() {
|
|||||||
otool -L "$f" 2>/dev/null | tail -n +2 | awk -v pfx="${prefix}/" \
|
otool -L "$f" 2>/dev/null | tail -n +2 | awk -v pfx="${prefix}/" \
|
||||||
'$1 !~ /^@/ && substr($1, 1, length(pfx)) != pfx { print $1 }'
|
'$1 !~ /^@/ && substr($1, 1, length(pfx)) != pfx { print $1 }'
|
||||||
else
|
else
|
||||||
ldd "$f" 2>/dev/null | awk -v pfx="${prefix}/" \
|
# GNU binutils 2.44 writes "(NEEDED) ... [name]"; FreeBSD 15.1 writes
|
||||||
'$2 == "=>" && $3 ~ /^\// && substr($3, 1, length(pfx)) != pfx { print $1 }'
|
# "NEEDED ... [name]". readelf(1) documents -d, not its text format.
|
||||||
|
needed="$(LC_ALL=C readelf -dW "$f" 2>/dev/null | awk \
|
||||||
|
'$2 == "(NEEDED)" || $2 == "NEEDED" { sub(/^.*\[/, ""); sub(/\].*$/, ""); print }' | tr '\n' ' ')"
|
||||||
|
# Linux and FreeBSD ldd write resolved libraries as
|
||||||
|
# "name => /absolute/path (address)"; entries without "=>" are ignored.
|
||||||
|
LC_ALL=C ldd "$f" 2>/dev/null | awk -v needed="$needed" -v pfx="${prefix}/" '
|
||||||
|
BEGIN {
|
||||||
|
split(needed, deps, " ")
|
||||||
|
for (i in deps) direct[deps[i]] = 1
|
||||||
|
}
|
||||||
|
$1 in direct && $2 == "=>" && $3 ~ /^\// && substr($3, 1, length(pfx)) != pfx { print $1 }
|
||||||
|
'
|
||||||
fi
|
fi
|
||||||
done | sort -u
|
done | sort -u
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ stub_build_environment() {
|
|||||||
create_stub pyenv-latest 'while (($#)); do case "$1" in -f|-k);; *)break;; esac; shift; done; echo "$*"'
|
create_stub pyenv-latest 'while (($#)); do case "$1" in -f|-k);; *)break;; esac; shift; done; echo "$*"'
|
||||||
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
||||||
create_stub getconf 'echo "glibc 2.17"'
|
create_stub getconf 'echo "glibc 2.17"'
|
||||||
|
create_stub readelf true
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "-v|--verbose runs pyenv install verbosely" {
|
@test "-v|--verbose runs pyenv install verbosely" {
|
||||||
|
|||||||
@ -79,7 +79,16 @@ platform() {
|
|||||||
assert_line "archive=3.12.7-$(platform).tar.gz"
|
assert_line "archive=3.12.7-$(platform).tar.gz"
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "records only the libraries ldd resolves outside the prefix" {
|
@test "fails when readelf is not available" {
|
||||||
|
create_version "3.12.7"
|
||||||
|
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
|
||||||
|
|
||||||
|
PATH="$(path_without readelf)" run pyenv-binary-save "3.12.7" "${BATS_TEST_TMPDIR}/dist"
|
||||||
|
assert_failure "pyenv-binary: need readelf to inspect shared libraries"
|
||||||
|
assert [ ! -e "${BATS_TEST_TMPDIR}/dist/3.12.7-$(platform).tar.gz" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "records only direct libraries resolved outside the prefix" {
|
||||||
create_version "3.12.7"
|
create_version "3.12.7"
|
||||||
touch "${PYENV_ROOT}/versions/3.12.7/bin/python3.12"
|
touch "${PYENV_ROOT}/versions/3.12.7/bin/python3.12"
|
||||||
create_path_executable uname <<'STUB'
|
create_path_executable uname <<'STUB'
|
||||||
@ -97,13 +106,18 @@ cat <<EOF
|
|||||||
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a3b800000)
|
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a3b800000)
|
||||||
/lib64/ld-linux-x86-64.so.2 (0x00007f4a3c200000)
|
/lib64/ld-linux-x86-64.so.2 (0x00007f4a3c200000)
|
||||||
EOF
|
EOF
|
||||||
|
STUB
|
||||||
|
create_path_executable readelf <<'STUB'
|
||||||
|
cat <<EOF
|
||||||
|
0x0000000000000001 (NEEDED) Shared library: [libpython3.12.so.1.0]
|
||||||
|
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
|
||||||
|
EOF
|
||||||
STUB
|
STUB
|
||||||
|
|
||||||
run pyenv-binary-save "3.12.7" "${BATS_TEST_TMPDIR}/dist"
|
run pyenv-binary-save "3.12.7" "${BATS_TEST_TMPDIR}/dist"
|
||||||
assert_success
|
assert_success
|
||||||
run grep '^dep=' "${BATS_TEST_TMPDIR}/dist/"*.meta
|
run grep '^dep=' "${BATS_TEST_TMPDIR}/dist/"*.meta
|
||||||
assert_output "dep=libc.so.6
|
assert_output "dep=libm.so.6"
|
||||||
dep=libm.so.6"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "records only the libraries otool resolves outside the prefix" {
|
@test "records only the libraries otool resolves outside the prefix" {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ FROM bash:$BASH
|
|||||||
apk add sed coreutils findutils \
|
apk add sed coreutils findutils \
|
||||||
;fi
|
;fi
|
||||||
# Bats
|
# Bats
|
||||||
RUN apk add --update parallel ncurses git \
|
RUN apk add --update parallel ncurses git binutils \
|
||||||
&& mkdir -p ~/.parallel \
|
&& mkdir -p ~/.parallel \
|
||||||
&& touch ~/.parallel/will-cite
|
&& touch ~/.parallel/will-cite
|
||||||
COPY --from=bats /root/bats-core /root/bats-core
|
COPY --from=bats /root/bats-core /root/bats-core
|
||||||
|
|||||||
@ -165,7 +165,7 @@ path_without() {
|
|||||||
if [ "$found" != "${PYENV_ROOT}/shims" ]; then
|
if [ "$found" != "${PYENV_ROOT}/shims" ]; then
|
||||||
alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')"
|
alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')"
|
||||||
mkdir -p "$alt"
|
mkdir -p "$alt"
|
||||||
for util in bash head cut readlink greadlink tr sed xargs basename sort; do
|
for util in basename bash cut dirname find greadlink gzip head mkdir readlink sed sort tar tr xargs; do
|
||||||
if [ -x "${found}/$util" ]; then
|
if [ -x "${found}/$util" ]; then
|
||||||
ln -s "${found}/$util" "${alt}/$util"
|
ln -s "${found}/$util" "${alt}/$util"
|
||||||
fi
|
fi
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user