#!/usr/bin/env bash # Creates Linux ".AppImage" for @PROJECT_NAME_UCASE@ # # Depends: linuxdeployqt # # Notes: Will attempt to fetch linuxdeployqt automatically (x86_64 only) # See Also: https://github.com/probonopd/linuxdeployqt/blob/master/BUILDING.md set -e LINUXDEPLOYQT="@CMAKE_BINARY_DIR@/linuxdeployqt" VERBOSITY=2 # 3=debug LOGFILE="@CMAKE_BINARY_DIR@/appimage.log" APPDIR="@CMAKE_BINARY_DIR@/@PROJECT_NAME_UCASE@.AppDir/" DESKTOPFILE="${APPDIR}usr/share/applications/lmms.desktop" STRIP="" # Don't strip for Debug|RelWithDebInfo builds if [[ "@CMAKE_BUILD_TYPE@" == *"Deb"* ]]; then STRIP="-no-strip" fi # Console colors RED="\\x1B[1;31m" GREEN="\\x1B[1;32m" YELLOW="\\x1B[1;33m" PLAIN="\\x1B[0m" function error { echo -e " ${PLAIN}[${RED}error${PLAIN}] ${1}" return 1 } function success { echo -e " ${PLAIN}[${GREEN}success${PLAIN}] ${1}" } function skipped { echo -e " ${PLAIN}[${YELLOW}skipped${PLAIN}] ${1}" } # Blindly assume system arch is appimage arch ARCH=$(arch) export ARCH # Check for problematic install locations INSTALL=$(echo "@CMAKE_INSTALL_PREFIX@" | sed 's/\/*$//g') if [ "$INSTALL" == "/usr/local" ] || [ "$INSTALL" == "/usr" ] ; then error "Incompatible CMAKE_INSTALL_PREFIX for creating AppImage: @CMAKE_INSTALL_PREFIX@" fi echo -e "\nWriting verbose output to \"${LOGFILE}\"" # Ensure linuxdeployqt uses the same qmake version as cmake export PATH="$(pwd -P)/squashfs-root/usr/bin:$(dirname "@QT_QMAKE_EXECUTABLE@")":$PATH # Fetch portable linuxdeployqt if cache is older than $DAYSOLD APPIMAGETOOL="squashfs-root/usr/bin/appimagetool" echo -e "\nDownloading linuxdeployqt to ${LINUXDEPLOYQT}..." mkdir -p "$HOME/bin" DAYSOLD=2 if env -i which linuxdeployqt > /dev/null 2>&1; then skipped "System already provides this utility" elif ! find "$LINUXDEPLOYQT" -mtime -$DAYSOLD 2>/dev/null|grep -q "." > /dev/null 2>&1; then url="https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-$(uname -p).AppImage" echo " [.......] Couldn't find linuxdeployqt newer than $DAYSOLD days old" echo " [.......] Downloading ($(uname -p)): ${url}" wget "$url" -O "$LINUXDEPLOYQT" -q || (rm "$LINUXDEPLOYQT" && false) chmod +x "$LINUXDEPLOYQT" touch "$LINUXDEPLOYQT" success "Downloaded $LINUXDEPLOYQT" "$LINUXDEPLOYQT" --appimage-extract > /dev/null 2>&1 success "Extracted $APPIMAGETOOL" else skipped "$LINUXDEPLOYQT is less than $DAYSOLD days old" fi # Make skeleton AppDir echo -e "\nCreating ${APPDIR}..." rm -rf "${APPDIR}" mkdir -p "${APPDIR}usr" success "Created ${APPDIR}" # Clone install to AppDir echo -e "\nCopying @CMAKE_INSTALL_PREFIX@ to ${APPDIR}..." cp -R "@CMAKE_INSTALL_PREFIX@/." "${APPDIR}usr" rm -rf "${APPDIR}usr/include" success "${APPDIR}" # Copy rawwaves directory for stk/mallets mkdir -p "${APPDIR}usr/share/stk/" cp -R /usr/share/stk/rawwaves/ "${APPDIR}usr/share/stk/" # Create a wrapper script which calls the lmms executable mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real" # shellcheck disable=SC1083 cat >"${APPDIR}usr/bin/lmms" < /dev/null 2>&1; then CARLAPATH="$(which carla)" CARLAPREFIX="\${CARLAPATH%/bin*}" echo "Carla appears to be installed on this system at \$CARLAPREFIX/lib[64]/carla so we'll use it." export LD_LIBRARY_PATH=\$CARLAPREFIX/lib/carla:\$CARLAPREFIX/lib64/carla:\$LD_LIBRARY_PATH else echo "Carla does not appear to be installed. That's OK, please ignore any related library errors." fi export LD_LIBRARY_PATH=\$DIR/usr/lib/:\$DIR/usr/lib/lmms:\$LD_LIBRARY_PATH # Prevent segfault on VirualBox if lsmod |grep vboxguest > /dev/null 2>&1; then echo "VirtualBox detected. Forcing libgl software rendering." export LIBGL_ALWAYS_SOFTWARE=1; fi if ldconfig -p | grep libjack.so.0 > /dev/null 2>&1; then echo "Jack appears to be installed on this system, so we'll use it." else echo "Jack does not appear to be installed. That's OK, we'll use a dummy version instead." export LD_LIBRARY_PATH=\$DIR/usr/lib/lmms/optional:\$LD_LIBRARY_PATH fi QT_X11_NO_NATIVE_MENUBAR=1 \$DIR/usr/bin/lmms.real "\$@" EOL chmod +x "${APPDIR}usr/bin/lmms" # Per https://github.com/probonopd/linuxdeployqt/issues/129 unset LD_LIBRARY_PATH # Ensure linuxdeployqt can find shared objects export LD_LIBRARY_PATH="${APPDIR}usr/lib/lmms/":$LD_LIBRARY_PATH # Handle wine linking if [ -d "@WINE_LIBRARY_FIX@" ]; then export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_LIBRARY_FIX@:@WINE_LIBRARY_FIX@wine/ fi # Move executables so linuxdeployqt can find them ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx" VSTLIB="${APPDIR}usr/lib/lmms/RemoteVstPlugin.exe.so" ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx" VSTBIN="${APPDIR}usr/bin/RemoteVstPlugin.exe.so" mv "$ZYNLIB" "$ZYNBIN" mv "$VSTLIB" "$VSTBIN" # Patch the desktop file sed -i 's/.*Exec=.*/Exec=lmms.real/' "$DESKTOPFILE" # Fix linking for soft-linked plugins for file in "${APPDIR}usr/lib/lmms/"*.so; do thisfile="${APPDIR}usr/lib/lmms/${file##*/}" executables="${executables} -executable=$thisfile" done executables="${executables} -executable=${ZYNBIN}" executables="${executables} -executable=${VSTBIN}" executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imp_1199.so" executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imbeq_1197.so" executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1193.so" executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1194.so" # Bundle both qt and non-qt dependencies into appimage format echo -e "\nBundling and relinking system dependencies..." echo -e ">>>>> linuxdeployqt" > "$LOGFILE" # shellcheck disable=SC2086 "$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1 success "Bundled and relinked dependencies" # Link to original location so lmms can find them ln -sr "$ZYNBIN" "$ZYNLIB" ln -sr "$VSTBIN" "$VSTLIB" # Remove wine library conflict rm -f "${APPDIR}/usr/lib/libwine.so.1" # Use system-provided carla rm -f "${APPDIR}usr/lib/"libcarla*.so # Move jack out of LD_LIBRARY_PATH if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then mkdir -p "${APPDIR}usr/lib/lmms/optional/" mv "${APPDIR}/usr/lib/libjack.so.0" "${APPDIR}usr/lib/lmms/optional/" fi # Point the AppRun to the shim launcher rm -f "${APPDIR}/AppRun" ln -sr "${APPDIR}/usr/bin/lmms" "${APPDIR}/AppRun" # Create AppImage echo -e "\nFinishing the AppImage..." echo -e "\n\n>>>>> appimagetool" >> "$LOGFILE" "$APPIMAGETOOL" "${APPDIR}" "@APPIMAGE_FILE@" >> "$LOGFILE" 2>&1 success "Created @APPIMAGE_FILE@" echo -e "\nFinished"