package_linux.sh.in 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #!/usr/bin/env bash
  2. # Creates Linux ".AppImage" for @PROJECT_NAME_UCASE@
  3. #
  4. # Depends: linuxdeployqt
  5. #
  6. # Notes: Will attempt to fetch linuxdeployqt automatically (x86_64 only)
  7. # See Also: https://github.com/probonopd/linuxdeployqt/blob/master/BUILDING.md
  8. set -e
  9. LINUXDEPLOYQT="@CMAKE_BINARY_DIR@/linuxdeployqt"
  10. VERBOSITY=2 # 3=debug
  11. LOGFILE="@CMAKE_BINARY_DIR@/appimage.log"
  12. APPDIR="@CMAKE_BINARY_DIR@/@PROJECT_NAME_UCASE@.AppDir/"
  13. DESKTOPFILE="${APPDIR}usr/share/applications/lmms.desktop"
  14. STRIP=""
  15. # Don't strip for Debug|RelWithDebInfo builds
  16. # shellcheck disable=SC2193
  17. if [[ "@CMAKE_BUILD_TYPE@" == *"Deb"* ]]; then
  18. STRIP="-no-strip"
  19. fi
  20. # Console colors
  21. RED="\\x1B[1;31m"
  22. GREEN="\\x1B[1;32m"
  23. YELLOW="\\x1B[1;33m"
  24. PLAIN="\\x1B[0m"
  25. function error {
  26. echo -e " ${PLAIN}[${RED}error${PLAIN}] ${1}"
  27. return 1
  28. }
  29. function success {
  30. echo -e " ${PLAIN}[${GREEN}success${PLAIN}] ${1}"
  31. }
  32. function skipped {
  33. echo -e " ${PLAIN}[${YELLOW}skipped${PLAIN}] ${1}"
  34. }
  35. # Blindly assume system arch is appimage arch
  36. ARCH=$(arch)
  37. export ARCH
  38. # Check for problematic install locations
  39. INSTALL=$(echo "@CMAKE_INSTALL_PREFIX@" | sed 's/\/*$//g')
  40. if [ "$INSTALL" == "/usr/local" ] || [ "$INSTALL" == "/usr" ] ; then
  41. error "Incompatible CMAKE_INSTALL_PREFIX for creating AppImage: @CMAKE_INSTALL_PREFIX@"
  42. fi
  43. echo -e "\nWriting verbose output to \"${LOGFILE}\""
  44. # Ensure linuxdeployqt uses the same qmake version as cmake
  45. PATH="$(pwd -P)/squashfs-root/usr/bin:$(dirname "@QT_QMAKE_EXECUTABLE@")":$PATH
  46. export PATH
  47. # Fetch portable linuxdeployqt if not in PATH
  48. APPIMAGETOOL="squashfs-root/usr/bin/appimagetool"
  49. echo -e "\nDownloading linuxdeployqt to ${LINUXDEPLOYQT}..."
  50. if env -i which linuxdeployqt > /dev/null 2>&1; then
  51. skipped "System already provides this utility"
  52. else
  53. filename="linuxdeployqt-continuous-$(uname -p).AppImage"
  54. url="https://github.com/probonopd/linuxdeployqt/releases/download/continuous/$filename"
  55. down_file="$(pwd)/$filename"
  56. if [ ! -f "$LINUXDEPLOYQT" ]; then
  57. ln -s "$down_file" "$LINUXDEPLOYQT"
  58. fi
  59. echo " [.......] Downloading ($(uname -p)): ${url}"
  60. wget -N -q "$url" || (rm "$filename" && false)
  61. chmod +x "$LINUXDEPLOYQT"
  62. success "Downloaded $LINUXDEPLOYQT"
  63. # Extract AppImage and replace LINUXDEPLOYQT variable with extracted binary
  64. # to support systems without fuse
  65. "$LINUXDEPLOYQT" --appimage-extract > /dev/null 2>&1
  66. LINUXDEPLOYQT="squashfs-root/AppRun"
  67. success "Extracted $APPIMAGETOOL"
  68. fi
  69. # Make skeleton AppDir
  70. echo -e "\nCreating ${APPDIR}..."
  71. rm -rf "${APPDIR}"
  72. mkdir -p "${APPDIR}usr"
  73. success "Created ${APPDIR}"
  74. # Clone install to AppDir
  75. echo -e "\nCopying @CMAKE_INSTALL_PREFIX@ to ${APPDIR}..."
  76. cp -R "@CMAKE_INSTALL_PREFIX@/." "${APPDIR}usr"
  77. rm -rf "${APPDIR}usr/include"
  78. success "${APPDIR}"
  79. # Copy rawwaves directory for stk/mallets
  80. mkdir -p "${APPDIR}usr/share/stk/"
  81. cp -R /usr/share/stk/rawwaves/ "${APPDIR}usr/share/stk/"
  82. # Create a wrapper script which calls the lmms executable
  83. mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real"
  84. # shellcheck disable=SC1083
  85. cat >"${APPDIR}usr/bin/lmms" <<EOL
  86. #!/usr/bin/env bash
  87. DIR="\$( cd "\$( dirname "\${BASH_SOURCE[0]}" )" && pwd )"
  88. if which carla > /dev/null 2>&1; then
  89. CARLAPATH="$(which carla)"
  90. CARLAPREFIX="\${CARLAPATH%/bin*}"
  91. echo "Carla appears to be installed on this system at \$CARLAPREFIX/lib[64]/carla so we'll use it."
  92. export LD_LIBRARY_PATH=\$CARLAPREFIX/lib/carla:\$CARLAPREFIX/lib64/carla:\$LD_LIBRARY_PATH
  93. else
  94. echo "Carla does not appear to be installed. That's OK, please ignore any related library errors."
  95. fi
  96. export LD_LIBRARY_PATH=\$DIR/usr/lib/:\$DIR/usr/lib/lmms:\$LD_LIBRARY_PATH
  97. # Prevent segfault on VirualBox
  98. if lsmod |grep vboxguest > /dev/null 2>&1; then
  99. echo "VirtualBox detected. Forcing libgl software rendering."
  100. export LIBGL_ALWAYS_SOFTWARE=1;
  101. fi
  102. if ldconfig -p | grep libjack.so.0 > /dev/null 2>&1; then
  103. echo "Jack appears to be installed on this system, so we'll use it."
  104. else
  105. echo "Jack does not appear to be installed. That's OK, we'll use a dummy version instead."
  106. export LD_LIBRARY_PATH=\$DIR/usr/lib/lmms/optional:\$LD_LIBRARY_PATH
  107. fi
  108. QT_X11_NO_NATIVE_MENUBAR=1 \$DIR/usr/bin/lmms.real "\$@"
  109. EOL
  110. chmod +x "${APPDIR}usr/bin/lmms"
  111. # Per https://github.com/probonopd/linuxdeployqt/issues/129
  112. unset LD_LIBRARY_PATH
  113. # Ensure linuxdeployqt can find shared objects
  114. export LD_LIBRARY_PATH="${APPDIR}usr/lib/lmms/":$LD_LIBRARY_PATH
  115. # Handle wine linking
  116. if [ -d "@WINE_32_LIBRARY_DIR@" ]; then
  117. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_32_LIBRARY_DIR@:@WINE_32_LIBRARY_DIR@wine/
  118. fi
  119. if [ -d "@WINE_64_LIBRARY_DIR@" ]; then
  120. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_64_LIBRARY_DIR@:@WINE_64_LIBRARY_DIR@wine/
  121. fi
  122. # Move executables so linuxdeployqt can find them
  123. ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx"
  124. VSTLIB32="${APPDIR}usr/lib/lmms/RemoteVstPlugin32.exe.so"
  125. VSTLIB64="${APPDIR}usr/lib/lmms/RemoteVstPlugin64.exe.so"
  126. ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx"
  127. VSTBIN32="${APPDIR}usr/bin/RemoteVstPlugin32.exe.so"
  128. VSTBIN64="${APPDIR}usr/bin/RemoteVstPlugin64.exe.so"
  129. mv "$ZYNLIB" "$ZYNBIN"
  130. mv "$VSTLIB32" "$VSTBIN32"
  131. mv "$VSTLIB64" "$VSTBIN64"
  132. # Patch the desktop file
  133. sed -i 's/.*Exec=.*/Exec=lmms.real/' "$DESKTOPFILE"
  134. # Fix linking for soft-linked plugins
  135. for file in "${APPDIR}usr/lib/lmms/"*.so; do
  136. thisfile="${APPDIR}usr/lib/lmms/${file##*/}"
  137. executables="${executables} -executable=$thisfile"
  138. done
  139. executables="${executables} -executable=${ZYNBIN}"
  140. executables="${executables} -executable=${VSTBIN32}"
  141. executables="${executables} -executable=${VSTBIN64}"
  142. executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imp_1199.so"
  143. executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imbeq_1197.so"
  144. executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1193.so"
  145. executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1194.so"
  146. # Bundle both qt and non-qt dependencies into appimage format
  147. echo -e "\nBundling and relinking system dependencies..."
  148. echo -e ">>>>> linuxdeployqt" > "$LOGFILE"
  149. # shellcheck disable=SC2086
  150. "$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1
  151. success "Bundled and relinked dependencies"
  152. # Link to original location so lmms can find them
  153. ln -sr "$ZYNBIN" "$ZYNLIB"
  154. ln -sr "$VSTBIN32" "$VSTLIB32"
  155. ln -sr "$VSTBIN64" "$VSTLIB64"
  156. # Remove wine library conflict
  157. rm -f "${APPDIR}/usr/lib/libwine.so.1"
  158. # Use system-provided carla
  159. rm -f "${APPDIR}usr/lib/"libcarla*.so
  160. # Move jack out of LD_LIBRARY_PATH
  161. if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then
  162. mkdir -p "${APPDIR}usr/lib/lmms/optional/"
  163. mv "${APPDIR}/usr/lib/libjack.so.0" "${APPDIR}usr/lib/lmms/optional/"
  164. fi
  165. # Point the AppRun to the shim launcher
  166. rm -f "${APPDIR}/AppRun"
  167. ln -sr "${APPDIR}/usr/bin/lmms" "${APPDIR}/AppRun"
  168. # Create AppImage
  169. echo -e "\nFinishing the AppImage..."
  170. echo -e "\n\n>>>>> appimagetool" >> "$LOGFILE"
  171. "$APPIMAGETOOL" "${APPDIR}" "@APPIMAGE_FILE@" >> "$LOGFILE" 2>&1
  172. success "Created @APPIMAGE_FILE@"
  173. echo -e "\nFinished"