Files
OpenRA/packaging/functions.sh
2024-10-25 11:42:33 +01:00

339 lines
13 KiB
Bash
Executable File

#!/bin/sh
# Helper functions for packaging and installing OpenRA
####
# This file must stay /bin/sh and POSIX compliant for macOS and BSD portability.
# Copy-paste the entire script into https://shellcheck.net to check.
####
# Compile and publish the core engine and specified mod assemblies to the target directory
# Arguments:
# SRC_PATH: Path to the root OpenRA directory
# DEST_PATH: Path to the root of the install destination (will be created if necessary)
# TARGETPLATFORM: Platform type (win-x86, win-x64, osx-x64, osx-arm64, linux-x64, linux-arm64, unix-generic)
# RUNTIME: Runtime type (net6, mono)
# COPY_GENERIC_LAUNCHER: If set to True the OpenRA.exe will also be copied (True, False)
# COPY_CNC_DLL: If set to True the OpenRA.Mods.Cnc.dll will also be copied (True, False)
# COPY_D2K_DLL: If set to True the OpenRA.Mods.D2k.dll will also be copied (True, False)
# Used by:
# Makefile (install target for local installs and downstream packaging)
# Windows packaging
# macOS packaging
# Linux AppImage packaging
# Mod SDK Windows packaging
# Mod SDK macOS packaging
# Mod SDK Linux AppImage packaging
install_assemblies() (
set -o errexit || exit $?
SRC_PATH="${1}"
DEST_PATH="${2}"
TARGETPLATFORM="${3}"
RUNTIME="${4}"
COPY_GENERIC_LAUNCHER="${5}"
COPY_CNC_DLL="${6}"
COPY_D2K_DLL="${7}"
ORIG_PWD=$(pwd)
cd "${SRC_PATH}"
if [ "${RUNTIME}" = "mono" ]; then
echo "Building assemblies"
rm -rf "${SRC_PATH}/OpenRA."*/obj || :
rm -rf "${SRC_PATH:?}/bin" || :
msbuild -verbosity:m -nologo -t:Build -restore -p:Configuration=Release -p:TargetPlatform="${TARGETPLATFORM}"
if [ "${TARGETPLATFORM}" = "unix-generic" ]; then
./configure-system-libraries.sh
fi
if [ "${COPY_GENERIC_LAUNCHER}" != "True" ]; then
rm "${SRC_PATH}/bin/OpenRA.dll"
fi
if [ "${COPY_CNC_DLL}" != "True" ]; then
rm "${SRC_PATH}/bin/OpenRA.Mods.Cnc.dll"
fi
if [ "${COPY_D2K_DLL}" != "True" ]; then
rm "${SRC_PATH}/bin/OpenRA.Mods.D2k.dll"
fi
cd "${ORIG_PWD}"
echo "Installing engine to ${DEST_PATH}"
install -d "${DEST_PATH}"
for LIB in "${SRC_PATH}/bin/"*.dll "${SRC_PATH}/bin/"*.dll.config; do
install -m644 "${LIB}" "${DEST_PATH}"
done
if [ "${TARGETPLATFORM}" = "linux-x64" ] || [ "${TARGETPLATFORM}" = "linux-arm64" ]; then
for LIB in "${SRC_PATH}/bin/"*.so; do
install -m755 "${LIB}" "${DEST_PATH}"
done
fi
if [ "${TARGETPLATFORM}" = "osx-x64" ] || [ "${TARGETPLATFORM}" = "osx-arm64" ]; then
for LIB in "${SRC_PATH}/bin/"*.dylib; do
install -m755 "${LIB}" "${DEST_PATH}"
done
fi
else
dotnet publish -c Release -p:TargetPlatform="${TARGETPLATFORM}" -p:CopyGenericLauncher="${COPY_GENERIC_LAUNCHER}" -p:CopyCncDll="${COPY_CNC_DLL}" -p:CopyD2kDll="${COPY_D2K_DLL}" -r "${TARGETPLATFORM}" -p:PublishDir="${DEST_PATH}" --self-contained true
fi
cd "${ORIG_PWD}"
)
# Copy the core engine and specified mod data to the target directory
# Arguments:
# SRC_PATH: Path to the root OpenRA directory
# DEST_PATH: Path to the root of the install destination (will be created if necessary)
# MOD [MOD...]: One or more mod ids to copy (cnc, d2k, ra)
# Used by:
# Makefile (install target for local installs and downstream packaging)
# Linux AppImage packaging
# macOS packaging
# Windows packaging
# Mod SDK Linux AppImage packaging
# Mod SDK macOS packaging
# Mod SDK Windows packaging
install_data() (
set -o errexit || exit $?
SRC_PATH="${1}"
DEST_PATH="${2}"
shift 2
"${SRC_PATH}"/fetch-geoip.sh
echo "Installing engine files to ${DEST_PATH}"
for FILE in VERSION AUTHORS COPYING IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP "global mix database.dat"; do
install -m644 "${SRC_PATH}/${FILE}" "${DEST_PATH}"
done
cp -r "${SRC_PATH}/glsl" "${DEST_PATH}"
echo "Installing common mod files to ${DEST_PATH}"
install -d "${DEST_PATH}/mods"
cp -r "${SRC_PATH}/mods/common" "${DEST_PATH}/mods/"
while [ -n "${1}" ]; do
MOD_ID="${1}"
if [ "${MOD_ID}" = "ra" ] || [ "${MOD_ID}" = "cnc" ] || [ "${MOD_ID}" = "d2k" ]; then
echo "Installing mod ${MOD_ID} to ${DEST_PATH}"
cp -r "${SRC_PATH}/mods/${MOD_ID}" "${DEST_PATH}/mods/"
cp -r "${SRC_PATH}/mods/common-content" "${DEST_PATH}/mods/"
cp -r "${SRC_PATH}/mods/${MOD_ID}-content" "${DEST_PATH}/mods/"
fi
shift
done
)
# Compile and publish (using Mono) a windows launcher with the specified mod details to the target directory
# Arguments:
# SRC_PATH: Path to the root OpenRA directory
# DEST_PATH: Path to the root of the install destination (will be created if necessary)
# TARGETPLATFORM: Platform type (win-x86, win-x64)
# MOD_ID: Mod id to launch (e.g. "ra")
# LAUNCHER_NAME: Filename (without the .exe extension) for the launcher
# MOD_NAME: Human-readable mod name to show in the crash dialog (e.g. "Red Alert")
# ICON_PATH: Path to a windows .ico file
# FAQ_URL: URL to load when the "View FAQ" button is pressed in the crash dialog (e.g. https://wiki.openra.net/FAQ)
# Used by:
# Windows packaging
# Mod SDK Windows packaging
install_windows_launcher() (
set -o errexit || exit $?
SRC_PATH="${1}"
DEST_PATH="${2}"
TARGETPLATFORM="${3}"
MOD_ID="${4}"
LAUNCHER_NAME="${5}"
MOD_NAME="${6}"
FAQ_URL="${7}"
VERSION="${8}"
rm -rf "${SRC_PATH}/OpenRA.WindowsLauncher/obj" || :
# See https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish for details.
# Unfortunately there doesn't seem to be a way to set FileDescription and it uses the value of -p:LauncherName.
# -p:Product sets the "Product name" field.
# -p:InformationalVersion seems to set the "Product version" field.
# -p:DisplayName doesn't seem to have a visible effect?
dotnet publish "${SRC_PATH}/OpenRA.WindowsLauncher/OpenRA.WindowsLauncher.csproj" -c Release -r "${TARGETPLATFORM}" -p:LauncherName="${LAUNCHER_NAME}",TargetPlatform="${TARGETPLATFORM}",ModID="${MOD_ID}",PublishDir="${DEST_PATH}",FaqUrl="${FAQ_URL}",InformationalVersion="${VERSION}" --self-contained true
# NET 6 is unable to customize the application host for windows when compiling from Linux,
# so we must patch the properties we need in the PE header.
# Setting the application icon requires an external tool, so is left to the calling code
python3 "${SRC_PATH}/packaging/windows/fixlauncher.py" "${DEST_PATH}/${LAUNCHER_NAME}.exe"
)
# Write a version string to the engine VERSION file
# Arguments:
# VERSION: OpenRA version string
# DEST_PATH: Path to the root of the install destination
# Used by:
# Makefile (install target for local installs and downstream packaging)
# Linux AppImage packaging
# macOS packaging
# Windows packaging
# Mod SDK Linux AppImage packaging
# Mod SDK macOS packaging
# Mod SDK Windows packaging
set_engine_version() (
set -o errexit || exit $?
VERSION="${1}"
DEST_PATH="${2}"
echo "${VERSION}" > "${DEST_PATH}/VERSION"
)
# Write a version string to a list of specified mod.yamls
# Arguments:
# VERSION: OpenRA version string
# MOD_YAML_PATH [MOD_YAML_PATH...]: One or more mod.yaml files to update
# Used by:
# Makefile (install target for local installs and downstream packaging)
# Linux AppImage packaging
# macOS packaging
# Windows packaging
# Mod SDK Linux AppImage packaging
# Mod SDK macOS packaging
# Mod SDK Windows packaging
set_mod_version() (
set -o errexit || exit $?
VERSION="${1}"
shift
while [ -n "${1}" ]; do
MOD_YAML_PATH="${1}"
awk -v v="${VERSION}" '{sub("Version:.*$", "Version: " v); print $0}' "${MOD_YAML_PATH}" > "${MOD_YAML_PATH}.tmp"
awk -v v="${VERSION}" '{sub("/[^/]*: User$", "/"v ": User"); print $0}' "${MOD_YAML_PATH}.tmp" > "${MOD_YAML_PATH}"
rm "${MOD_YAML_PATH}.tmp"
shift
done
)
# Copy launch wrappers, application icons, desktop, and MIME files to the target directory
# Arguments:
# SRC_PATH: Path to the root OpenRA directory
# BUILD_PATH: Path to packaging filesystem root (e.g. /tmp/openra-build/ or "" for a local install)
# OPENRA_PATH: Path to the OpenRA installation (e.g. /usr/local/lib/openra)
# BIN_PATH: Path to install wrapper scripts (e.g. /usr/local/bin)
# SHARE_PATH: Parent path to the icons and applications directory (e.g. /usr/local/share)
# VERSION: OpenRA version string
# MOD [MOD...]: One or more mod ids to copy (cnc, d2k, ra)
# Used by:
# Makefile (install-linux-shortcuts target for local installs and downstream packaging)
install_linux_shortcuts() (
set -o errexit || exit $?
SRC_PATH="${1}"
BUILD_PATH="${2}"
OPENRA_PATH="${3}"
BIN_PATH="${4}"
SHARE_PATH="${5}"
VERSION="${6}"
shift 6
while [ -n "${1}" ]; do
MOD_ID="${1}"
if [ "${MOD_ID}" = "ra" ] || [ "${MOD_ID}" = "cnc" ] || [ "${MOD_ID}" = "d2k" ]; then
if [ "${MOD_ID}" = "cnc" ]; then
MOD_NAME="Tiberian Dawn"
fi
if [ "${MOD_ID}" = "d2k" ]; then
MOD_NAME="Dune 2000"
fi
if [ "${MOD_ID}" = "ra" ]; then
MOD_NAME="Red Alert"
fi
# wrapper scripts
install -d "${BUILD_PATH}/${BIN_PATH}"
sed -e 's/{DEBUG}/--debug/' -e "s|{GAME_INSTALL_DIR}|${OPENRA_PATH}|" -e "s|{BIN_DIR}|${BIN_PATH}|" -e "s/{MODID}/${MOD_ID}/g" -e "s/{TAG}/${VERSION}/g" -e "s/{MODNAME}/${MOD_NAME}/g" "${SRC_PATH}/packaging/linux/openra.in" > "${SRC_PATH}/packaging/linux/openra-${MOD_ID}"
sed -e 's/{DEBUG}/--debug/' -e "s|{GAME_INSTALL_DIR}|${OPENRA_PATH}|" -e "s/{MODID}/${MOD_ID}/g" "${SRC_PATH}/packaging/linux/openra-server.in" > "${SRC_PATH}/packaging/linux/openra-${MOD_ID}-server"
install -m755 "${SRC_PATH}/packaging/linux/openra-${MOD_ID}" "${BUILD_PATH}/${BIN_PATH}"
install -m755 "${SRC_PATH}/packaging/linux/openra-${MOD_ID}-server" "${BUILD_PATH}/${BIN_PATH}"
rm "${SRC_PATH}/packaging/linux/openra-${MOD_ID}" "${SRC_PATH}/packaging/linux/openra-${MOD_ID}-server"
# desktop files
install -d "${BUILD_PATH}${SHARE_PATH}/applications"
sed -e "s/{MODID}/${MOD_ID}/g" -e "s/{MODNAME}/${MOD_NAME}/g" -e "s/{TAG}/${VERSION}/g" "${SRC_PATH}/packaging/linux/openra.desktop.in" > "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.desktop"
install -m644 "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.desktop" "${BUILD_PATH}${SHARE_PATH}/applications"
rm "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.desktop"
# icons
for SIZE in 16x16 32x32 48x48 64x64 128x128; do
install -d "${BUILD_PATH}${SHARE_PATH}/icons/hicolor/${SIZE}/apps"
install -m644 "${SRC_PATH}/packaging/artwork/${MOD_ID}_${SIZE}.png" "${BUILD_PATH}${SHARE_PATH}/icons/hicolor/${SIZE}/apps/openra-${MOD_ID}.png"
done
if [ "${MOD_ID}" = "ra" ] || [ "${MOD_ID}" = "cnc" ]; then
install -d "${BUILD_PATH}${SHARE_PATH}/icons/hicolor/scalable/apps"
install -m644 "${SRC_PATH}/packaging/artwork/${MOD_ID}_scalable.svg" "${BUILD_PATH}${SHARE_PATH}/icons/hicolor/scalable/apps/openra-${MOD_ID}.svg"
fi
# MIME info
install -d "${BUILD_PATH}${SHARE_PATH}/mime/packages"
sed -e "s/{MODID}/${MOD_ID}/g" -e "s/{TAG}/${VERSION}/g" "${SRC_PATH}/packaging/linux/openra-mimeinfo.xml.in" > "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.xml"
install -m644 "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.xml" "${BUILD_PATH}${SHARE_PATH}/mime/packages/openra-${MOD_ID}.xml"
rm "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.xml"
fi
shift
done
)
# Copy AppStream metadata to the target directory
# Arguments:
# SRC_PATH: Path to the root OpenRA directory
# BUILD_PATH: Path to packaging filesystem root (e.g. /tmp/openra-build/ or "" for a local install)
# SHARE_PATH: Parent path to the appdata directory (e.g. /usr/local/share)
# MOD [MOD...]: One or more mod ids to copy (cnc, d2k, ra)
# Used by:
# Makefile (install-linux-appdata target for local installs and downstream packaging)
install_linux_appdata() (
set -o errexit || exit $?
SRC_PATH="${1}"
BUILD_PATH="${2}"
SHARE_PATH="${3}"
shift 3
while [ -n "${1}" ]; do
MOD_ID="${1}"
SCREENSHOT_CNC=
SCREENSHOT_D2K=
SCREENSHOT_RA=
if [ "${MOD_ID}" = "ra" ] || [ "${MOD_ID}" = "cnc" ] || [ "${MOD_ID}" = "d2k" ]; then
if [ "${MOD_ID}" = "cnc" ]; then
MOD_NAME="Tiberian Dawn"
SCREENSHOT_CNC=" type=\"default\""
fi
if [ "${MOD_ID}" = "d2k" ]; then
MOD_NAME="Dune 2000"
SCREENSHOT_D2K=" type=\"default\""
fi
if [ "${MOD_ID}" = "ra" ]; then
MOD_NAME="Red Alert"
SCREENSHOT_RA=" type=\"default\""
fi
fi
install -d "${BUILD_PATH}${SHARE_PATH}/metainfo"
sed -e "s/{MODID}/${MOD_ID}/g" -e "s/{MOD_NAME}/${MOD_NAME}/g" -e "s/{SCREENSHOT_RA}/${SCREENSHOT_RA}/g" -e "s/{SCREENSHOT_CNC}/${SCREENSHOT_CNC}/g" -e "s/{SCREENSHOT_D2K}/${SCREENSHOT_D2K}/g" "${SRC_PATH}/packaging/linux/openra.metainfo.xml.in" > "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.metainfo.xml"
install -m644 "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.metainfo.xml" "${BUILD_PATH}${SHARE_PATH}/metainfo"
rm "${SRC_PATH}/packaging/linux/openra-${MOD_ID}.metainfo.xml"
shift
done
)