Files
rk1/media/scripts/repack-upstream-deb.sh
T

145 lines
5.9 KiB
Bash
Raw Normal View History

2026-08-17 18:42:29 +00:00
#!/usr/bin/env bash
set -Eeuo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
# shellcheck source=lib.sh
. "${SCRIPT_DIR}/lib.sh"
LOCK_FILE="${RKMEDIA_ROOT}/upstream-deb.lock.json"
WORK_DIR="${RKMEDIA_ROOT}/out/repack-work"
OUTPUT_DIR="${RKMEDIA_ROOT}/out"
CACHE_DIR="${RKMEDIA_ROOT}/out/downloads"
INPUT_DEB=""
PACKAGE_VERSION="20260721.1741+rk1.1"
usage() {
cat <<'EOF'
Usage: repack-upstream-deb.sh [options]
--deb FILE Use an existing upstream .deb instead of downloading
--work-dir DIR Temporary extraction directory
--output-dir DIR Repacked package output directory
--cache-dir DIR Download cache directory
--version VERSION Output Debian package version
EOF
}
while (($#)); do
case "$1" in
--deb) [[ $# -ge 2 ]] || die "--deb requires a file"; INPUT_DEB="$2"; shift 2 ;;
--work-dir) [[ $# -ge 2 ]] || die "--work-dir requires a directory"; WORK_DIR="$2"; shift 2 ;;
--output-dir) [[ $# -ge 2 ]] || die "--output-dir requires a directory"; OUTPUT_DIR="$2"; shift 2 ;;
--cache-dir) [[ $# -ge 2 ]] || die "--cache-dir requires a directory"; CACHE_DIR="$2"; shift 2 ;;
--version) [[ $# -ge 2 ]] || die "--version requires a value"; PACKAGE_VERSION="$2"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) die "unknown argument: $1" ;;
esac
done
for command_name in curl dpkg-deb file jq readelf sha256sum stat; do
need_command "${command_name}"
done
[[ -f "${LOCK_FILE}" ]] || die "upstream asset lock is missing: ${LOCK_FILE}"
jq -e '.schema_version == 1 and (.asset_sha256 | test("^[0-9a-f]{64}$"))' "${LOCK_FILE}" >/dev/null \
|| die "invalid upstream asset lock"
WORK_DIR="$(absolute_path "${WORK_DIR}")"
OUTPUT_DIR="$(absolute_path "${OUTPUT_DIR}")"
CACHE_DIR="$(absolute_path "${CACHE_DIR}")"
mkdir -p -- "${WORK_DIR}" "${OUTPUT_DIR}" "${CACHE_DIR}"
asset_name="$(jq -er '.asset_name' "${LOCK_FILE}")"
asset_url="$(jq -er '.asset_url' "${LOCK_FILE}")"
expected_size="$(jq -er '.asset_size' "${LOCK_FILE}")"
expected_sha256="$(jq -er '.asset_sha256' "${LOCK_FILE}")"
if [[ -z "${INPUT_DEB}" ]]; then
INPUT_DEB="${CACHE_DIR}/${asset_name}"
if [[ ! -f "${INPUT_DEB}" ]]; then
partial="${INPUT_DEB}.partial"
rm -f -- "${partial}"
log "downloading pinned upstream Kodi package"
curl -L --fail --show-error --output "${partial}" "${asset_url}"
mv -- "${partial}" "${INPUT_DEB}"
fi
fi
INPUT_DEB="$(absolute_path "${INPUT_DEB}")"
[[ -f "${INPUT_DEB}" ]] || die "upstream package not found: ${INPUT_DEB}"
actual_size="$(stat -c '%s' "${INPUT_DEB}")"
actual_sha256="$(sha256sum "${INPUT_DEB}" | awk '{print $1}')"
[[ "${actual_size}" == "${expected_size}" ]] || die "upstream package size mismatch"
[[ "${actual_sha256}" == "${expected_sha256}" ]] || die "upstream package SHA-256 mismatch"
[[ "$(dpkg-deb --field "${INPUT_DEB}" Package)" == "$(jq -er '.package' "${LOCK_FILE}")" ]] \
|| die "upstream package name mismatch"
[[ "$(dpkg-deb --field "${INPUT_DEB}" Version)" == "$(jq -er '.package_version' "${LOCK_FILE}")" ]] \
|| die "upstream package version mismatch"
[[ "$(dpkg-deb --field "${INPUT_DEB}" Architecture)" == "arm64" ]] \
|| die "upstream package is not arm64"
STAGE_DIR="${WORK_DIR}/stage"
reset_child_dir "${WORK_DIR}" "${STAGE_DIR}"
dpkg-deb --extract "${INPUT_DEB}" "${STAGE_DIR}"
local_bin="${STAGE_DIR}/usr/local/bin"
local_lib="${STAGE_DIR}/usr/local/lib"
runtime_bin="${STAGE_DIR}/opt/rkmedia/bin"
runtime_lib="${STAGE_DIR}/opt/rkmedia/lib"
mkdir -p -- "${runtime_bin}" "${runtime_lib}"
for program in ffmpeg ffprobe; do
[[ -x "${local_bin}/${program}" ]] || die "upstream package is missing ${program}"
mv -- "${local_bin}/${program}" "${runtime_bin}/${program}"
done
if [[ -x "${local_bin}/di-edid-decode" ]]; then
mv -- "${local_bin}/di-edid-decode" "${runtime_bin}/di-edid-decode"
fi
shopt -s nullglob
runtime_libraries=(
"${local_lib}"/libdav1d.so*
"${local_lib}"/librga.so*
"${local_lib}"/librockchip_mpp.so*
"${local_lib}"/librockchip_vpu.so*
"${local_lib}"/aarch64-linux-gnu/libdisplay-info.so*
)
((${#runtime_libraries[@]} > 0)) || die "no Rockchip runtime libraries found in upstream package"
mv -- "${runtime_libraries[@]}" "${runtime_lib}/"
shopt -u nullglob
find "${local_lib}" -type f \( -name '*.a' -o -name '*.la' \) -delete
rm -rf -- "${local_lib}/pkgconfig" "${local_lib}/aarch64-linux-gnu/pkgconfig"
rm -f -- \
"${STAGE_DIR}/usr/lib/systemd/system/kodi.service" \
"${STAGE_DIR}/usr/lib/systemd/system/kodi-pulse.service" \
"${STAGE_DIR}/usr/lib/systemd/system/pulseaudio.service"
cp -a -- "${RKMEDIA_ROOT}/packaging/rootfs/." "${STAGE_DIR}/"
mkdir -p -- "${STAGE_DIR}/usr/bin" "${STAGE_DIR}/usr/share/doc/rk1-media-stack"
ln -sfn /opt/rkmedia/bin/ffmpeg-rk "${STAGE_DIR}/usr/bin/ffmpeg-rk"
ln -sfn /opt/rkmedia/bin/ffprobe-rk "${STAGE_DIR}/usr/bin/ffprobe-rk"
ln -sfn /opt/rkmedia/bin/kodi-rk "${STAGE_DIR}/usr/bin/kodi-rk"
install -m 0644 "${LOCK_FILE}" "${STAGE_DIR}/usr/share/doc/rk1-media-stack/upstream-deb.lock.json"
[[ -x "${STAGE_DIR}/usr/local/bin/kodi" ]] || die "Kodi launcher was not retained at its compiled prefix"
[[ -x "${STAGE_DIR}/usr/local/lib/kodi/kodi-gbm" ]] || die "Kodi GBM binary is missing"
for soname in librga.so.2 libdav1d.so.7 librockchip_mpp.so.1 libdisplay-info.so.4; do
[[ -e "${runtime_lib}/${soname}" ]] || die "relocated runtime is missing ${soname}"
readelf -d "${STAGE_DIR}/usr/local/lib/kodi/kodi-gbm" | grep -Fq "Shared library: [${soname}]" \
|| die "Kodi binary does not declare expected dependency ${soname}"
done
if find "${STAGE_DIR}" -type f -name '*.a' -print -quit | grep -q .; then
die "static library remained after repack"
fi
if find "${STAGE_DIR}/usr/local/lib" -type d -name pkgconfig -print -quit | grep -q .; then
die "pkg-config development directory remained after repack"
fi
"${SCRIPT_DIR}/package-media.sh" \
--stage "${STAGE_DIR}" \
--output-dir "${OUTPUT_DIR}" \
--version "${PACKAGE_VERSION}" \
--depends-from-deb "${INPUT_DEB}"
log "repack complete; authoritative input SHA-256: ${actual_sha256}"