0.1.4
This commit is contained in:
Executable
+137
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build a portable rcalc AppImage.
|
||||
#
|
||||
# The release binary is compiled inside Ubuntu 22.04 (glibc 2.35) so the
|
||||
# AppImage runs on most modern distros — not only on bleeding-edge hosts.
|
||||
# AppImage itself does NOT bundle glibc; the Docker base sets the floor.
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
ARCH="$(uname -m)"
|
||||
OUT_DIR="${ROOT}/dist"
|
||||
APPDIR="${OUT_DIR}/rcalc.AppDir"
|
||||
TOOLS_DIR="${ROOT}/.cache/appimage-tools"
|
||||
VERSION="$(grep -m1 '^version' "${ROOT}/Cargo.toml" | sed 's/.*"\(.*\)".*/\1/')"
|
||||
IMAGE_NAME="rcalc-${VERSION}-${ARCH}.AppImage"
|
||||
|
||||
DOCKER_IMAGE="${DOCKER_IMAGE:-ubuntu:22.04}"
|
||||
# Set SKIP_DOCKER=1 to package the already-built host binary (same glibc floor as host).
|
||||
SKIP_DOCKER="${SKIP_DOCKER:-0}"
|
||||
|
||||
mkdir -p "${OUT_DIR}" "${TOOLS_DIR}"
|
||||
|
||||
need_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || {
|
||||
echo "error: required command not found: $1" >&2
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
download_tool() {
|
||||
local url="$1" dest="$2"
|
||||
if [[ -x "$dest" ]]; then
|
||||
return 0
|
||||
fi
|
||||
echo "Downloading $(basename "$dest")…"
|
||||
curl -fsSL -o "$dest" "$url"
|
||||
chmod +x "$dest"
|
||||
}
|
||||
|
||||
build_binary_docker() {
|
||||
need_cmd docker
|
||||
echo "Building release binary in ${DOCKER_IMAGE} (portable glibc)…"
|
||||
mkdir -p "${HOME}/.cargo/registry" "${HOME}/.cargo/git"
|
||||
docker run --rm \
|
||||
-v "${ROOT}:/src" \
|
||||
-v "${HOME}/.cargo/registry:/root/.cargo/registry" \
|
||||
-v "${HOME}/.cargo/git:/root/.cargo/git" \
|
||||
-w /src \
|
||||
"${DOCKER_IMAGE}" \
|
||||
bash -lc '
|
||||
set -euo pipefail
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq curl build-essential pkg-config libfontconfig1-dev ca-certificates
|
||||
curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
|
||||
# shellcheck disable=SC1091
|
||||
source "$HOME/.cargo/env"
|
||||
export CARGO_TARGET_DIR=/src/target-appimage
|
||||
cargo build --release
|
||||
install -D -m755 /src/target-appimage/release/rcalc /src/dist/rcalc
|
||||
ldd --version | head -1 > /src/dist/.glibc-build.txt
|
||||
# Make artifacts writable by the host user
|
||||
chown -R '"$(id -u):$(id -g)"' /src/dist/rcalc /src/dist/.glibc-build.txt /src/target-appimage || true
|
||||
'
|
||||
}
|
||||
|
||||
ensure_binary() {
|
||||
if [[ "$SKIP_DOCKER" == "1" ]]; then
|
||||
if [[ ! -x "${OUT_DIR}/rcalc" ]]; then
|
||||
echo "Building on host (SKIP_DOCKER=1)…"
|
||||
(cd "${ROOT}" && cargo build --release)
|
||||
install -D -m755 "${ROOT}/target/release/rcalc" "${OUT_DIR}/rcalc"
|
||||
fi
|
||||
ldd --version | head -1 > "${OUT_DIR}/.glibc-build.txt" || true
|
||||
else
|
||||
build_binary_docker
|
||||
fi
|
||||
|
||||
if [[ ! -x "${OUT_DIR}/rcalc" ]]; then
|
||||
echo "error: dist/rcalc missing after build" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
package_appimage() {
|
||||
need_cmd curl
|
||||
|
||||
local linuxdeploy="${TOOLS_DIR}/linuxdeploy-${ARCH}.AppImage"
|
||||
download_tool \
|
||||
"https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-${ARCH}.AppImage" \
|
||||
"${linuxdeploy}"
|
||||
|
||||
rm -rf "${APPDIR}"
|
||||
mkdir -p "${APPDIR}/usr/bin" "${APPDIR}/usr/share/icons/hicolor/256x256/apps"
|
||||
|
||||
install -m755 "${OUT_DIR}/rcalc" "${APPDIR}/usr/bin/rcalc"
|
||||
install -m644 "${ROOT}/assets/icon-256.png" "${APPDIR}/usr/share/icons/hicolor/256x256/apps/rcalc.png"
|
||||
install -m644 "${ROOT}/assets/icon-256.png" "${APPDIR}/rcalc.png"
|
||||
install -m644 "${ROOT}/assets/rcalc-appimage.desktop" "${APPDIR}/rcalc.desktop"
|
||||
|
||||
echo "Bundling libraries with linuxdeploy…"
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
export OUTPUT="${IMAGE_NAME}"
|
||||
(
|
||||
cd "${OUT_DIR}"
|
||||
"${linuxdeploy}" \
|
||||
--appdir "${APPDIR}" \
|
||||
--executable "${APPDIR}/usr/bin/rcalc" \
|
||||
--desktop-file "${APPDIR}/rcalc.desktop" \
|
||||
--icon-file "${APPDIR}/rcalc.png" \
|
||||
--output appimage
|
||||
)
|
||||
|
||||
# linuxdeploy drops the AppImage next to AppDir (dist/)
|
||||
local built
|
||||
built="$(find "${OUT_DIR}" -maxdepth 1 -name '*.AppImage' ! -name 'linuxdeploy*' | head -1)"
|
||||
if [[ -z "$built" ]]; then
|
||||
echo "error: AppImage was not produced" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$(basename "$built")" != "${IMAGE_NAME}" ]]; then
|
||||
mv -f "$built" "${OUT_DIR}/${IMAGE_NAME}"
|
||||
fi
|
||||
|
||||
chmod +x "${OUT_DIR}/${IMAGE_NAME}"
|
||||
}
|
||||
|
||||
ensure_binary
|
||||
package_appimage
|
||||
|
||||
echo
|
||||
echo "OK: ${OUT_DIR}/${IMAGE_NAME}"
|
||||
if [[ -f "${OUT_DIR}/.glibc-build.txt" ]]; then
|
||||
echo "Built against: $(cat "${OUT_DIR}/.glibc-build.txt")"
|
||||
fi
|
||||
echo "Run: ${OUT_DIR}/${IMAGE_NAME}"
|
||||
echo "Tip: on the other PC, chmod +x and execute — no install needed."
|
||||
Reference in New Issue
Block a user