package_linux.sh.in 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. if [[ "@CMAKE_BUILD_TYPE@" == *"Deb"* ]]; then
  17. STRIP="-no-strip"
  18. fi
  19. # Console colors
  20. RED="\\x1B[1;31m"
  21. GREEN="\\x1B[1;32m"
  22. YELLOW="\\x1B[1;33m"
  23. PLAIN="\\x1B[0m"
  24. function error {
  25. echo -e " ${PLAIN}[${RED}error${PLAIN}] ${1}"
  26. return 1
  27. }
  28. function success {
  29. echo -e " ${PLAIN}[${GREEN}success${PLAIN}] ${1}"
  30. }
  31. function skipped {
  32. echo -e " ${PLAIN}[${YELLOW}skipped${PLAIN}] ${1}"
  33. }
  34. # Blindly assume system arch is appimage arch
  35. ARCH=$(arch)
  36. export ARCH
  37. # Check for problematic install locations
  38. INSTALL=$(echo "@CMAKE_INSTALL_PREFIX@" | sed 's/\/*$//g')
  39. if [ "$INSTALL" == "/usr/local" ] || [ "$INSTALL" == "/usr" ] ; then
  40. error "Incompatible CMAKE_INSTALL_PREFIX for creating AppImage: @CMAKE_INSTALL_PREFIX@"
  41. fi
  42. echo -e "\nWriting verbose output to \"${LOGFILE}\""
  43. # Ensure linuxdeployqt uses the same qmake version as cmake
  44. export PATH="$(pwd -P)/squashfs-root/usr/bin:$(dirname "@QT_QMAKE_EXECUTABLE@")":$PATH
  45. # Fetch portable linuxdeployqt if cache is older than $DAYSOLD
  46. APPIMAGETOOL="squashfs-root/usr/bin/appimagetool"
  47. echo -e "\nDownloading linuxdeployqt to ${LINUXDEPLOYQT}..."
  48. mkdir -p "$HOME/bin"
  49. DAYSOLD=2
  50. if env -i which linuxdeployqt > /dev/null 2>&1; then
  51. skipped "System already provides this utility"
  52. elif ! find "$LINUXDEPLOYQT" -mtime -$DAYSOLD 2>/dev/null|grep -q "." > /dev/null 2>&1; then
  53. url="https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-$(uname -p).AppImage"
  54. echo " [.......] Couldn't find linuxdeployqt newer than $DAYSOLD days old"
  55. echo " [.......] Downloading ($(uname -p)): ${url}"
  56. wget "$url" -O "$LINUXDEPLOYQT" -q || (rm "$LINUXDEPLOYQT" && false)
  57. chmod +x "$LINUXDEPLOYQT"
  58. touch "$LINUXDEPLOYQT"
  59. success "Downloaded $LINUXDEPLOYQT"
  60. "$LINUXDEPLOYQT" --appimage-extract > /dev/null 2>&1
  61. # We need to set LD_LIBRARY_PATH, but linuxdepoyqt's AppRun unsets it
  62. # See https://github.com/probonopd/linuxdeployqt/pull/370/
  63. LINUXDEPLOYQT="squashfs-root/usr/bin/linuxdeployqt"
  64. success "Extracted $APPIMAGETOOL"
  65. else
  66. skipped "$LINUXDEPLOYQT is less than $DAYSOLD days old"
  67. fi
  68. # Make skeleton AppDir
  69. echo -e "\nCreating ${APPDIR}..."
  70. rm -rf "${APPDIR}"
  71. mkdir -p "${APPDIR}usr"
  72. success "Created ${APPDIR}"
  73. # Clone install to AppDir
  74. echo -e "\nCopying @CMAKE_INSTALL_PREFIX@ to ${APPDIR}..."
  75. cp -R "@CMAKE_INSTALL_PREFIX@/." "${APPDIR}usr"
  76. rm -rf "${APPDIR}usr/include"
  77. success "${APPDIR}"
  78. # Copy rawwaves directory for stk/mallets
  79. mkdir -p "${APPDIR}usr/share/stk/"
  80. cp -R /usr/share/stk/rawwaves/ "${APPDIR}usr/share/stk/"
  81. # Create a wrapper script which calls the lmms executable
  82. mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real"
  83. cp "@CMAKE_CURRENT_SOURCE_DIR@/launch_lmms.sh" "${APPDIR}usr/bin/lmms"
  84. chmod +x "${APPDIR}usr/bin/lmms"
  85. # Per https://github.com/probonopd/linuxdeployqt/issues/129
  86. unset LD_LIBRARY_PATH
  87. # Ensure linuxdeployqt can find shared objects
  88. export LD_LIBRARY_PATH="${APPDIR}usr/lib/lmms/":"${APPDIR}usr/lib/lmms/optional":$LD_LIBRARY_PATH
  89. # Handle wine linking
  90. if [ -d "@WINE_LIBRARY_FIX@" ]; then
  91. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_LIBRARY_FIX@:@WINE_LIBRARY_FIX@wine/
  92. fi
  93. # Move executables so linuxdeployqt can find them
  94. ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx"
  95. VSTLIB="${APPDIR}usr/lib/lmms/RemoteVstPlugin.exe.so"
  96. ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx"
  97. VSTBIN="${APPDIR}usr/bin/RemoteVstPlugin.exe.so"
  98. mv "$ZYNLIB" "$ZYNBIN"
  99. mv "$VSTLIB" "$VSTBIN" || true
  100. # Patch the desktop file
  101. sed -i 's/.*Exec=.*/Exec=lmms.real/' "$DESKTOPFILE"
  102. # Fix linking for soft-linked plugins
  103. for file in "${APPDIR}usr/lib/lmms/"*.so; do
  104. thisfile="${APPDIR}usr/lib/lmms/${file##*/}"
  105. executables="${executables} -executable=$thisfile"
  106. done
  107. executables="${executables} -executable=${ZYNBIN}"
  108. executables="${executables} -executable=${VSTBIN}"
  109. executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imp_1199.so"
  110. executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/imbeq_1197.so"
  111. executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1193.so"
  112. executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale_1194.so"
  113. # Bundle both qt and non-qt dependencies into appimage format
  114. echo -e "\nBundling and relinking system dependencies..."
  115. echo -e ">>>>> linuxdeployqt" > "$LOGFILE"
  116. # shellcheck disable=SC2086
  117. "$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1
  118. success "Bundled and relinked dependencies"
  119. # Link to original location so lmms can find them
  120. ln -sr "$ZYNBIN" "$ZYNLIB"
  121. ln -sr "$VSTBIN" "$VSTLIB" || true
  122. # Remove wine library conflict
  123. rm -f "${APPDIR}/usr/lib/libwine.so.1"
  124. # Use system-provided carla
  125. rm -f "${APPDIR}usr/lib/"libcarla*.so
  126. rm -f "${APPDIR}usr/lib/lmms/optional/"libcarla*.so
  127. # Remove bundled jack in LD_LIBRARY_PATH if exists
  128. if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then
  129. rm "${APPDIR}/usr/lib/libjack.so.0"
  130. fi
  131. # Bundle jack out of LD_LIBRARY_PATH
  132. JACK_LIB=$(ldd "${APPDIR}/usr/bin/lmms.real" | sed -n 's/\tlibjack\.so\.0 => \(.\+\) (0x[0-9a-f]\+)/\1/p')
  133. if [ -e "$JACK_LIB" ]; then
  134. mkdir -p "${APPDIR}usr/lib/lmms/optional/"
  135. cp "$JACK_LIB" "${APPDIR}usr/lib/lmms/optional/"
  136. fi
  137. # Point the AppRun to the shim launcher
  138. rm -f "${APPDIR}/AppRun"
  139. ln -sr "${APPDIR}/usr/bin/lmms" "${APPDIR}/AppRun"
  140. # Create AppImage
  141. echo -e "\nFinishing the AppImage..."
  142. echo -e "\n\n>>>>> appimagetool" >> "$LOGFILE"
  143. "$APPIMAGETOOL" "${APPDIR}" "@APPIMAGE_FILE@" >> "$LOGFILE" 2>&1
  144. success "Created @APPIMAGE_FILE@"
  145. echo -e "\nFinished"