1#!/usr/bin/env bash 2 3((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "$0: Error: Please upgrade Bash."; exit 1; } 4 5set -euxo pipefail 6 7readonly appdir="$1" # input path (Audacity install directory) 8readonly appimage="$2" # output path to use for created AppImage 9 10#============================================================================ 11# Helper functions 12#============================================================================ 13 14function download_github_release() 15{ 16 local -r repo_slug="$1" release_tag="$2" file="$3" 17 wget -q --show-progress "https://github.com/${repo_slug}/releases/download/${release_tag}/${file}" 18 chmod +x "${file}" 19} 20 21function extract_appimage() 22{ 23 # Extract AppImage so we can run it without having to install FUSE 24 local -r image="$1" binary_name="$2" 25 local -r dir="${image%.AppImage}.AppDir" 26 "./${image}" --appimage-extract >/dev/null # dest folder "squashfs-root" 27 mv squashfs-root "${dir}" # rename folder to avoid collisions 28 ln -s "${dir}/AppRun" "${binary_name}" # symlink for convenience 29 rm -f "${image}" 30} 31 32function download_appimage_release() 33{ 34 local -r github_repo_slug="$1" binary_name="$2" tag="$3" 35 local -r image="${binary_name}-x86_64.AppImage" 36 download_github_release "${github_repo_slug}" "${tag}" "${image}" 37 extract_appimage "${image}" "${binary_name}" 38} 39 40function download_linuxdeploy_component() 41{ 42 local -r component="$1" tag="$2" 43 download_appimage_release "linuxdeploy/$1" "$1" "$2" 44} 45 46function create_path() 47{ 48 local -r path="$1" 49 if [[ -d "${path}" ]]; then 50 return 1 # already exists 51 fi 52 mkdir -p "${path}" 53} 54 55#============================================================================ 56# Fetch AppImage packaging tools 57#============================================================================ 58 59if create_path "appimagetool"; then 60( 61 cd "appimagetool" 62 download_appimage_release AppImage/AppImageKit appimagetool continuous 63) 64fi 65export PATH="${PWD%/}/appimagetool:${PATH}" 66appimagetool --version 67 68if create_path "linuxdeploy"; then 69( 70 cd "linuxdeploy" 71 download_linuxdeploy_component linuxdeploy continuous 72) 73fi 74 75export PATH="${PWD%/}/linuxdeploy:${PATH}" 76linuxdeploy --list-plugins 77 78#============================================================================ 79# Create symlinks 80#============================================================================ 81 82ln -sf --no-dereference . "${appdir}/usr" 83ln -sf share/applications/audacity.desktop "${appdir}/audacity.desktop" 84ln -sf share/icons/hicolor/scalable/apps/audacity.svg "${appdir}/audacity.svg" 85ln -sf share/icons/hicolor/scalable/apps/audacity.svg "${appdir}/.DirIcon" 86 87#============================================================================ 88# Bundle dependencies 89#============================================================================ 90 91# HACK: Some wxWidget libraries depend on themselves. Add 92# them to LD_LIBRARY_PATH so that linuxdeploy can find them. 93export LD_LIBRARY_PATH="${appdir}/usr/lib:${appdir}/usr/lib/audacity:${LD_LIBRARY_PATH-}" 94 95# Prevent linuxdeploy setting RUNPATH in binaries that shouldn't have it 96mv "${appdir}/bin/findlib" "${appdir}/../findlib" 97 98linuxdeploy --appdir "${appdir}" # add all shared library dependencies 99rm -R "${appdir}/lib/audacity" 100 101# Put the non-RUNPATH binaries back 102mv "${appdir}/../findlib" "${appdir}/bin/findlib" 103 104########################################################################## 105# BUNDLE REMAINING DEPENDENCIES MANUALLY 106########################################################################## 107 108function find_library() 109{ 110 # Print full path to a library or return exit status 1 if not found 111 "${appdir}/bin/findlib" "$@" 112} 113 114function fallback_library() 115{ 116 # Copy a library into a special fallback directory inside the AppDir. 117 # Fallback libraries are not loaded at runtime by default, but they can 118 # be loaded if it is found that the application would crash otherwise. 119 local library="$1" 120 local full_path="$(find_library "$1")" 121 local new_path="${appdir}/fallback/${library}" 122 mkdir -p "${new_path}" # directory has the same name as the library 123 cp -L "${full_path}" "${new_path}/${library}" 124 rm -f "${appdir}/lib/${library}" 125 # Use the AppRun script to check at runtime whether the user has a copy of 126 # this library. If not then add our copy's directory to $LD_LIBRARY_PATH. 127} 128 129unwanted_files=( 130 lib/libQt5Core.so.5 131 lib/libQt5Gui.so.5 132 lib/libQt5Widgets.so.5 133) 134 135fallback_libraries=( 136 libatk-1.0.so.0 # This will possibly prevent browser from opening 137 libatk-bridge-2.0.so.0 138 libcairo.so.2 # This breaks FFmpeg support 139 libcairo-gobject.so.2 140 libjack.so.0 # https://github.com/LMMS/lmms/pull/3958 141 libportaudio.so # This is required to enable system PortAudio (so Jack is enabled!) 142 libgmodule-2.0.so.0 # Otherwise - Manjaro/Arch will crash, because of libgio mismatch 143 # But if gmodule is present - glib2 is too 144 # Some ot the GTK libraries are balcklisted from being included 145 # libgio-2.0.so.0 146 # libglib-2.0.so.0 147 # libgobject-2.0.so.0 148 libgthread-2.0.so.0 149) 150 151for file in "${unwanted_files[@]}"; do 152 rm -f "${appdir}/${file}" 153done 154 155for fb_lib in "${fallback_libraries[@]}"; do 156 fallback_library "${fb_lib}" 157done 158 159#============================================================================ 160# Build AppImage 161#============================================================================ 162 163appimagetool_args=( 164 # none 165) 166 167if [[ "${AUDACITY_UPDATE_INFO-}" ]]; then 168 # Enable updates. See https://github.com/AppImage/AppImageSpec/blob/master/draft.md#update-information 169 appimagetool_args+=( --updateinformation="${AUDACITY_UPDATE_INFO}" ) 170else 171 echo >&2 "$0: Automatic updates disabled" 172fi 173 174# Create AppImage 175cd "$(dirname "${appimage}")" # otherwise zsync created in wrong directory 176appimagetool "${appimagetool_args[@]}" "${appdir}" "${appimage}" 177