forked from streamlink/streamlink-twitch-gui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
build: rewrite appimage build config
resolves streamlink#798 - build inside ghcr.io/streamlink/appimage-buildenv-{x86_64,i686} containers and copy missing libraries from the centos7 base image, except those being a dependency of gtk3 or being part of the appimage exclusion list - remove custom appimagekit grunt task - remove custom squashfs-tools build script - refactor appimage build task configs and clean up related configs - rewrite build script and split into two
- Loading branch information
1 parent
9771757
commit e90f843
Showing
13 changed files
with
307 additions
and
323 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#!/usr/bin/env bash | ||
set -e | ||
|
||
APPDIR="${1}" | ||
INSTALLDIR="${2}" | ||
VERSION="${3}" | ||
ARCH="${4}" | ||
LIBDIR="${APPDIR}/${INSTALLDIR}/lib" | ||
|
||
declare -A excludepackages=( | ||
[gtk3]=true | ||
) | ||
|
||
|
||
# ---- | ||
|
||
|
||
SELF=$(basename "$(readlink -f "${0}")") | ||
log() { | ||
echo "[${SELF}] $@" | ||
} | ||
err() { | ||
log >&2 "$@" | ||
exit 1 | ||
} | ||
|
||
[[ $# == 4 ]] || err "Invalid arguments" | ||
[[ -f /.dockerenv ]] || err "This script is supposed to be run from build.sh inside a docker container" | ||
|
||
for pkg in $(repoquery --queryformat="%{name}" --requires --recursive --resolve "${!excludepackages[@]}" | sort -u); do | ||
excludepackages["${pkg}"]=true | ||
done | ||
|
||
declare -A excludelibraries | ||
for lib in $(sed -e '/#.*/d; /^[[:space:]]*|[[:space:]]*$/d; /^$/d' /usr/local/share/appimage/excludelist); do | ||
excludelibraries["${lib}"]=true | ||
done | ||
|
||
|
||
find_dependencies() { | ||
log "Finding missing dependencies for: $@" | ||
declare -A libs | ||
for file in "$@"; do | ||
[[ -f "${file}" && -x "${file}" ]] || err "File does not exist or is not executable: ${file}" | ||
for lib in $(LD_LIBRARY_PATH=$(dirname "${file}") ldd "${file}" | awk '/ => not found/ {print $1}'); do | ||
# don't check a lib more than once | ||
[[ -n "${excludelibraries["${lib}"]}" ]] && continue | ||
excludelibraries["${lib}"]=true | ||
# find the lib's package | ||
local package=$(repoquery --queryformat="%{name}" --file "${lib}" | head -n1) | ||
[[ -z "${package}" ]] && err "Missing package for: ${lib}" | ||
[[ -n "${excludepackages["${package}"]}" ]] && continue | ||
libs["${lib}"]="${package}" | ||
done | ||
done | ||
|
||
[[ ${#libs[@]} == 0 ]] && return | ||
|
||
log "Installing packages: ${libs[@]}" | ||
yum install -y --setopt=tsflags= "${libs[@]}" | ||
log "Copying libraries" | ||
for lib in "${!libs[@]}"; do | ||
for path in $(repoquery --list --archlist "${ARCH}" "${libs["${lib}"]}"); do | ||
if [[ "$(basename -- "${path}")" == "${lib}" ]]; then | ||
( set -x; install -m755 -t "${LIBDIR}" "${path}" ) | ||
fi | ||
if echo "${path}" | grep -Ei '^/usr/share/(doc|licenses)/.*(copying|licen[cs]e|readme|terms).*'; then | ||
( set -x; install -Dm644 -t "${APPDIR}${path}" "${path}" ) | ||
fi | ||
done | ||
done | ||
|
||
find_dependencies $(echo "${!libs[@]}" | tr ' ' '\n' | while read -r lib; do echo "${LIBDIR}/${lib}"; done) | ||
} | ||
build_appimage() { | ||
log "Building appimage" | ||
[ "${SOURCE_DATE_EPOCH}" ] && mtime="@${SOURCE_DATE_EPOCH}" || mtime=now | ||
find "${APPDIR}" -exec touch --no-dereference "--date=${mtime}" '{}' '+' | ||
VERSION="${VERSION}" ARCH="${ARCH}" /usr/local/bin/appimagetool \ | ||
--verbose \ | ||
--comp gzip \ | ||
--no-appstream \ | ||
"${APPDIR}" \ | ||
output | ||
} | ||
build() { | ||
find_dependencies $(find "${APPDIR}/${INSTALLDIR}" -type f -exec sh -c 'readelf -h {} >/dev/null 2>&1' \; -print) | ||
build_appimage | ||
} | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
#!/usr/bin/env bash | ||
set -e | ||
|
||
# this build script is meant to be run by the dist:appimage_linux{32,64} grunt tasks | ||
# don't run it directly unless you know what you're doing | ||
|
||
NAME="${1}" | ||
VERSION="${2}" | ||
ARCH="${3}" | ||
DOCKER_IMAGE="${4}" | ||
DOCKER_DIGEST="${5}" | ||
INPUT="${6}" | ||
OUTPUT="${7}" | ||
|
||
declare -A DEPS=( | ||
[docker]=docker | ||
[appstreamcli]=appstreamcli | ||
[appstream-util]=appstreamutil | ||
) | ||
|
||
|
||
# ---- | ||
|
||
|
||
SELF=$(basename "$(readlink -f "${0}")") | ||
DOCKER_SCRIPT="$(dirname "$(readlink -f "${0}")")/build-docker.sh" | ||
|
||
log() { | ||
echo "[${SELF}] $@" | ||
} | ||
err() { | ||
log >&2 "$@" | ||
exit 1 | ||
} | ||
|
||
[[ $# == 7 ]] || err "Invalid arguments" | ||
|
||
for dep in "${!DEPS[@]}"; do | ||
command -v "${dep}" 2>&1 >/dev/null || err "Missing dependency: ${DEPS["${dep}"]}" | ||
done | ||
|
||
|
||
# ---- | ||
|
||
|
||
tempdir=$(mktemp -d) && trap "rm -rf ${tempdir}" EXIT || exit 255 | ||
cd "${tempdir}" | ||
|
||
appdir="${NAME}.AppDir" | ||
installdir="opt/${NAME}" | ||
|
||
|
||
# ---- | ||
|
||
|
||
get_docker_image() { | ||
log "Getting docker image" | ||
docker image ls --digests "${DOCKER_IMAGE}" | grep "${DOCKER_DIGEST}" 2>&1 >/dev/null \ | ||
|| docker image pull "${DOCKER_IMAGE}@${DOCKER_DIGEST}" | ||
} | ||
|
||
|
||
prepare_appimage() { | ||
log "Installing AppDir files" | ||
|
||
# create AppImage AppDir | ||
mkdir -p "${appdir}/${installdir}" | ||
|
||
# copy app contents | ||
cp -a "${INPUT}/." "${appdir}/${installdir}/" | ||
|
||
# copy licenses | ||
install -Dm644 \ | ||
-t "${appdir}/usr/share/licenses/${NAME}/" \ | ||
"${appdir}/${installdir}/LICENSE.txt" \ | ||
"${appdir}/${installdir}/credits.html" | ||
|
||
# copy appstream metainfo | ||
install -Dm644 \ | ||
-t "${appdir}/usr/share/metainfo/" \ | ||
"${appdir}/${installdir}/${NAME}.appdata.xml" | ||
|
||
# copy icons | ||
for res in 16 32 48 64 128 256; do | ||
install -Dm644 \ | ||
"${appdir}/${installdir}/icons/icon-${res}.png" \ | ||
"${appdir}/usr/share/icons/hicolor/${res}x${res}/apps/${NAME}.png" | ||
done | ||
|
||
# symlink root AppImage icons | ||
for link in "${appdir}/.DirIcon" "${appdir}/${NAME}.png"; do | ||
ln -sr "${appdir}/usr/share/icons/hicolor/256x256/apps/${NAME}.png" "${link}" | ||
done | ||
|
||
# create desktop file | ||
mkdir -p "${appdir}/usr/share/applications/" | ||
cat > "${appdir}/usr/share/applications/${NAME}.desktop" <<EOF | ||
[Desktop Entry] | ||
Type=Application | ||
Name=Streamlink Twitch GUI | ||
GenericName=Twitch.tv browser for Streamlink | ||
Comment=Browse Twitch.tv and watch streams in your videoplayer of choice | ||
Keywords=streamlink;twitch; | ||
Categories=AudioVideo;Network; | ||
Exec=${NAME} | ||
Icon=${NAME} | ||
EOF | ||
|
||
# symlink root AppImage desktop file | ||
ln -sr "${appdir}/usr/share/applications/${NAME}.desktop" "${appdir}/${NAME}.desktop" | ||
|
||
# symlink executable | ||
mkdir -p "${appdir}/usr/bin" | ||
ln -sr "${appdir}/${installdir}/${NAME}" "${appdir}/usr/bin/${NAME}" | ||
|
||
# AppRun | ||
cat > "${appdir}/AppRun" <<EOF | ||
#!/usr/bin/env bash | ||
HERE=\$(dirname "\$(readlink -f "\${0}")") | ||
export LD_LIBRARY_PATH="\${HERE}/${installdir}/lib\${LD_LIBRARY_PATH:+":\${LD_LIBRARY_PATH}"}" | ||
"\${HERE}/usr/bin/${NAME}" "\${@}" | ||
EOF | ||
chmod +x "${appdir}/AppRun" | ||
|
||
# remove unneeded stuff | ||
rm -rf \ | ||
"${appdir}/${installdir}/"{add,remove}-menuitem.sh \ | ||
"${appdir}/${installdir}/"{LICENSE.txt,credits.html} \ | ||
"${appdir}/${installdir}/${NAME}.appdata.xml" \ | ||
"${appdir}/${installdir}/icons/" | ||
} | ||
|
||
|
||
verify_appstream() { | ||
log "Verifying appstream data" | ||
appstreamcli validate-tree "${appdir}/usr/share/metainfo/${NAME}.appdata.xml" | ||
appstream-util validate-relax "${appdir}/usr/share/metainfo/${NAME}.appdata.xml" | ||
} | ||
|
||
|
||
build_appimage() { | ||
log "Building appimage inside container" | ||
local target=/build | ||
install -m755 -t "${tempdir}" "${DOCKER_SCRIPT}" | ||
docker run \ | ||
--interactive \ | ||
--rm \ | ||
--env SOURCE_DATE_EPOCH \ | ||
--mount "type=bind,source=${tempdir},target=${target}" \ | ||
--workdir "${target}" \ | ||
"${DOCKER_IMAGE}@${DOCKER_DIGEST}" \ | ||
/usr/bin/bash <<EOF | ||
set -e | ||
trap "chown -R $(id -u):$(id -g) '${target}'" EXIT | ||
"./$(basename -- "${DOCKER_SCRIPT}")" \ | ||
"${appdir}" \ | ||
"${installdir}" \ | ||
"${VERSION}" \ | ||
"${ARCH}" | ||
EOF | ||
install -Dm755 "${tempdir}/output" "${OUTPUT}" | ||
} | ||
|
||
|
||
build() { | ||
prepare_appimage | ||
verify_appstream | ||
get_docker_image | ||
build_appimage | ||
} | ||
|
||
build |
Oops, something went wrong.