build(package): trim bundled runtime libraries

This commit is contained in:
Aethersailor
2026-06-01 18:56:10 +08:00
parent 9b65b07710
commit b9e8dea1b0
5 changed files with 142 additions and 40 deletions

View File

@@ -162,29 +162,14 @@ RUN set -xe && \
# 收集 glibc 运行时依赖(动态探测,避免固定版本)
RUN set -xe && \
mkdir -p /runtime-libs && \
ldd /src/subconverter /usr/lib/libmihomo.so | \
awk '{for (i=1; i<=NF; i++) if ($i ~ "^/") print $i}' | \
sort -u | \
while read -r lib; do \
if [ -e "$lib" ]; then \
mkdir -p "/runtime-libs$(dirname "$lib")" && \
cp -aL "$lib" "/runtime-libs$lib"; \
fi; \
done && \
for loader in /lib64/ld-linux-x86-64.so.2 /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /lib/ld-linux-aarch64.so.1 /lib/aarch64-linux-gnu/ld-linux-aarch64.so.1; do \
if [ -e "$loader" ]; then \
mkdir -p "/runtime-libs$(dirname "$loader")" && \
cp -aL "$loader" "/runtime-libs$loader"; \
fi; \
done && \
libc_path="$(ldd /src/subconverter | awk '$1 == "libc.so.6" {print $3; exit}')" && \
libc_dir="$(dirname "${libc_path:-/lib/x86_64-linux-gnu/libc.so.6}")" && \
for extra in libnss_dns.so.2 libnss_files.so.2 libnss_compat.so.2 libresolv.so.2; do \
if [ -e "$libc_dir/$extra" ]; then \
mkdir -p "/runtime-libs$libc_dir" && \
cp -aL "$libc_dir/$extra" "/runtime-libs$libc_dir/$extra"; \
fi; \
done && \
ELF_LIBRARY_PATH="/usr/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/lib/aarch64-linux-gnu:/usr/lib/aarch64-linux-gnu:/lib64" \
bash /src/scripts/ci/copy-elf-runtime-deps.sh /runtime-libs \
/src/subconverter \
/usr/lib/libmihomo.so \
libnss_dns.so.2 \
libnss_files.so.2 \
libnss_compat.so.2 \
libresolv.so.2 && \
if [ -f /etc/nsswitch.conf ]; then \
mkdir -p /runtime-libs/etc && \
cp -aL /etc/nsswitch.conf /runtime-libs/etc/nsswitch.conf; \
@@ -215,9 +200,7 @@ RUN apk add --no-cache ca-certificates tzdata && \
COPY --from=builder /src/subconverter /usr/bin/subconverter
COPY --from=builder /src/base /base/
COPY --from=builder /usr/lib/libmihomo.so /usr/lib/
COPY --from=builder /runtime-libs/ /
COPY --from=builder /etc/nsswitch.conf /etc/nsswitch.conf
# 确保二进制和库可执行
RUN chmod +x /usr/bin/subconverter && chmod +x /usr/lib/libmihomo.so

View File

@@ -184,15 +184,14 @@ RUN set -xe && \
ln -snf /usr/share/zoneinfo/Asia/Shanghai /runtime-root/etc/localtime && \
echo Asia/Shanghai > /runtime-root/etc/timezone && \
if [ -f /etc/nsswitch.conf ]; then cp -aL /etc/nsswitch.conf /runtime-root/etc/nsswitch.conf; fi && \
for dir in /lib/arm-linux-gnueabihf /usr/lib/arm-linux-gnueabihf /usr/arm-linux-gnueabihf/lib; do \
if [ -d "$dir" ]; then \
find "$dir" -maxdepth 1 \( -name '*.so' -o -name '*.so.*' \) -print | \
while read -r lib; do \
dest="/runtime-root/usr/lib/arm-linux-gnueabihf/$(basename "$lib")"; \
cp -aL "$lib" "$dest"; \
done; \
fi; \
done
READELF=arm-linux-gnueabihf-readelf \
ELF_LIBRARY_PATH="/usr/lib/arm-linux-gnueabihf:/lib/arm-linux-gnueabihf:/usr/arm-linux-gnueabihf/lib:/usr/lib:/lib" \
bash /src/scripts/ci/copy-elf-runtime-deps.sh /runtime-root \
/src/subconverter \
libnss_dns.so.2 \
libnss_files.so.2 \
libnss_compat.so.2 \
libresolv.so.2
# ========== FINAL STAGE ==========
FROM --platform=$TARGETPLATFORM mirror.gcr.io/library/debian:trixie-slim

View File

@@ -0,0 +1,126 @@
#!/usr/bin/env bash
set -euo pipefail
DEST_ROOT="${1:?destination root is required}"
shift
READELF="${READELF:-readelf}"
ELF_LIBRARY_PATH="${ELF_LIBRARY_PATH:-}"
declare -a SEARCH_DIRS=()
if [ -n "${ELF_LIBRARY_PATH}" ]; then
IFS=':' read -r -a SEARCH_DIRS <<< "${ELF_LIBRARY_PATH}"
fi
SEARCH_DIRS+=(
/lib
/usr/lib
/lib64
/usr/lib64
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
/lib/aarch64-linux-gnu
/usr/lib/aarch64-linux-gnu
/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabihf
/usr/arm-linux-gnueabihf/lib
)
declare -A COPIED=()
declare -A SCANNED=()
declare -a QUEUE=()
canonical_path() {
local path="$1"
if command -v realpath >/dev/null 2>&1; then
realpath "$path"
else
readlink -f "$path"
fi
}
copy_runtime_file() {
local source="$1"
local logical="$source"
local resolved
resolved="$(canonical_path "$source")"
if [ -n "${COPIED[$logical]:-}" ]; then
return
fi
local dest="${DEST_ROOT}${logical}"
mkdir -p "$(dirname "$dest")"
cp -aL "$source" "$dest"
COPIED["$logical"]=1
QUEUE+=("$resolved")
}
resolve_soname() {
local soname="$1"
if [[ "$soname" == */* ]] && [ -e "$soname" ]; then
printf '%s\n' "$soname"
return 0
fi
local dir candidate
for dir in "${SEARCH_DIRS[@]}"; do
[ -n "$dir" ] || continue
candidate="${dir}/${soname}"
if [ -e "$candidate" ]; then
printf '%s\n' "$candidate"
return 0
fi
done
return 1
}
copy_needed_by() {
local elf="$1"
if [ -n "${SCANNED[$elf]:-}" ]; then
return
fi
SCANNED["$elf"]=1
if ! "$READELF" -h "$elf" >/dev/null 2>&1; then
return
fi
local interp
interp="$("$READELF" -l "$elf" 2>/dev/null | sed -n 's/.*Requesting program interpreter: \(.*\)\]/\1/p' | head -n 1)"
if [ -n "$interp" ] && [ -e "$interp" ]; then
copy_runtime_file "$interp"
fi
local needed resolved
while IFS= read -r needed; do
[ -n "$needed" ] || continue
if resolved="$(resolve_soname "$needed")"; then
copy_runtime_file "$resolved"
else
echo "warning: could not resolve ELF dependency '$needed' required by $elf" >&2
fi
done < <("$READELF" -d "$elf" 2>/dev/null | sed -n 's/.*Shared library: \[\(.*\)\].*/\1/p')
}
for input in "$@"; do
if [ -e "$input" ]; then
case "$(basename "$input")" in
*.so|*.so.*|ld-*.so*|ld-linux*.so*) copy_runtime_file "$input" ;;
esac
copy_needed_by "$(canonical_path "$input")"
elif resolved="$(resolve_soname "$input")"; then
copy_runtime_file "$resolved"
else
echo "warning: could not resolve requested runtime file '$input'" >&2
fi
done
while [ "${#QUEUE[@]}" -gt 0 ]; do
current="${QUEUE[0]}"
QUEUE=("${QUEUE[@]:1}")
copy_needed_by "$current"
done

View File

@@ -25,7 +25,6 @@ chmod +x ./subconverter
case "${MODE}" in
shared)
docker cp "${CID}:/runtime-libs" ./runtime-libs
docker cp "${CID}:/usr/lib/libmihomo.so" ./libmihomo.so
;;
root)
docker cp "${CID}:/runtime-root" ./runtime-root

View File

@@ -27,11 +27,6 @@ mkdir -p "${PACKAGE_DIR}"
install -m755 subconverter "${PACKAGE_DIR}/subconverter"
cp -a base "${PACKAGE_DIR}/"
if [ -f libmihomo.so ]; then
mkdir -p "${PACKAGE_DIR}/usr/lib"
install -m755 libmihomo.so "${PACKAGE_DIR}/usr/lib/libmihomo.so"
fi
copy_dir_contents runtime-libs
copy_dir_contents runtime-root