Generate AppImage on GitHub Actions
Fixes #695. Supersedes #172. See https://appimage.org/.
This commit is contained in:
parent
2e0e3b4162
commit
de2213ea2c
|
@ -136,6 +136,8 @@ project( Audacity )
|
||||||
# Load our functions/macros
|
# Load our functions/macros
|
||||||
include( AudacityFunctions )
|
include( AudacityFunctions )
|
||||||
|
|
||||||
|
set_from_env(AUDACITY_ARCH_LABEL) # e.g. x86_64
|
||||||
|
|
||||||
# Allow user to globally set the library preference
|
# Allow user to globally set the library preference
|
||||||
cmd_option( ${_OPT}lib_preference
|
cmd_option( ${_OPT}lib_preference
|
||||||
"Library preference [system (if available), local]"
|
"Library preference [system (if available), local]"
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "${AUDACITY_VERSION}") # X
|
set(CPACK_PACKAGE_VERSION_MAJOR "${AUDACITY_VERSION}") # X
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "${AUDACITY_RELEASE}") # Y
|
set(CPACK_PACKAGE_VERSION_MINOR "${AUDACITY_RELEASE}") # Y
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "${AUDACITY_REVISION}") # Z
|
set(CPACK_PACKAGE_VERSION_PATCH "${AUDACITY_REVISION}") # Z
|
||||||
|
@ -13,30 +12,53 @@ if(NOT AUDACITY_BUILD_LEVEL EQUAL 2)
|
||||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}+${GIT_COMMIT_SHORT}")
|
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}+${GIT_COMMIT_SHORT}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Audacity-X.Y.Z-alpha-20210615
|
# Custom variables use CPACK_AUDACITY_ prefix. CPACK_ to expose to CPack,
|
||||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}")
|
# AUDACITY_ to show it is custom and avoid conflicts with other projects.
|
||||||
|
set(CPACK_AUDACITY_SOURCE_DIR "${PROJECT_SOURCE_DIR}")
|
||||||
|
|
||||||
if(NOT "$ENV{AUDACITY_ARCH_LABEL}" STREQUAL "")
|
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||||
# Audacity-X.Y.Z-alpha-20210615-x86_64
|
set(os "win")
|
||||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-$ENV{AUDACITY_ARCH_LABEL}")
|
elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
set(os "macos")
|
||||||
|
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
set(os "linux")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# audacity-linux-X.Y.Z-alpha-20210615
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "audacity-${os}-${CPACK_PACKAGE_VERSION}")
|
||||||
|
set(zsync_name "audacity-${os}-*") # '*' is wildcard (here it means any version)
|
||||||
|
|
||||||
|
if(DEFINED AUDACITY_ARCH_LABEL)
|
||||||
|
# audacity-linux-X.Y.Z-alpha-20210615-x86_64
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${AUDACITY_ARCH_LABEL}")
|
||||||
|
set(zsync_name "${zsync_name}-${AUDACITY_ARCH_LABEL}")
|
||||||
|
set(CPACK_AUDACITY_ARCH_LABEL "${AUDACITY_ARCH_LABEL}")
|
||||||
endif()
|
endif()
|
||||||
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/package")
|
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/package")
|
||||||
|
|
||||||
set(CPACK_GENERATOR ZIP)
|
set(CPACK_GENERATOR "ZIP")
|
||||||
|
|
||||||
if( CMAKE_SYSTEM_NAME STREQUAL "Darwin" )
|
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
set(CPACK_GENERATOR "External")
|
||||||
|
set(CPACK_EXTERNAL_ENABLE_STAGING TRUE)
|
||||||
|
set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${PROJECT_SOURCE_DIR}/linux/package_appimage.cmake")
|
||||||
|
if(AUDACITY_BUILD_LEVEL EQUAL 2)
|
||||||
|
# Enable updates. See https://github.com/AppImage/AppImageSpec/blob/master/draft.md#update-information
|
||||||
|
set(CPACK_AUDACITY_APPIMAGE_UPDATE_INFO "gh-releases-zsync|audacity|audacity|latest|${zsync_name}.AppImage.zsync")
|
||||||
|
endif()
|
||||||
|
elseif( CMAKE_SYSTEM_NAME STREQUAL "Darwin" )
|
||||||
set( CPACK_GENERATOR DragNDrop )
|
set( CPACK_GENERATOR DragNDrop )
|
||||||
|
|
||||||
set( CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/mac/Resources/Audacity-DMG-background.png")
|
set( CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/mac/Resources/Audacity-DMG-background.png")
|
||||||
set( CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_SOURCE_DIR}/scripts/build/macOS/DMGSetup.scpt")
|
set( CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_SOURCE_DIR}/scripts/build/macOS/DMGSetup.scpt")
|
||||||
|
|
||||||
if( ${_OPT}perform_codesign )
|
if( ${_OPT}perform_codesign )
|
||||||
set( CPACK_APPLE_CODESIGN_IDENTITY ${APPLE_CODESIGN_IDENTITY} )
|
set( CPACK_APPLE_CODESIGN_IDENTITY ${APPLE_CODESIGN_IDENTITY} )
|
||||||
set( CPACK_APPLE_NOTARIZATION_USER_NAME ${APPLE_NOTARIZATION_USER_NAME} )
|
set( CPACK_APPLE_NOTARIZATION_USER_NAME ${APPLE_NOTARIZATION_USER_NAME} )
|
||||||
set( CPACK_APPLE_NOTARIZATION_PASSWORD ${APPLE_NOTARIZATION_PASSWORD} )
|
set( CPACK_APPLE_NOTARIZATION_PASSWORD ${APPLE_NOTARIZATION_PASSWORD} )
|
||||||
set( CPACK_APPLE_SIGN_SCRIPTS "${CMAKE_SOURCE_DIR}/scripts/build/macOS" )
|
set( CPACK_APPLE_SIGN_SCRIPTS "${CMAKE_SOURCE_DIR}/scripts/build/macOS" )
|
||||||
set( CPACK_PERFORM_NOTARIZATION ${${_OPT}perform_notarization} )
|
set( CPACK_PERFORM_NOTARIZATION ${${_OPT}perform_notarization} )
|
||||||
|
|
||||||
# CPACK_POST_BUILD_SCRIPTS was added in 3.19, but we only need it on macOS
|
# CPACK_POST_BUILD_SCRIPTS was added in 3.19, but we only need it on macOS
|
||||||
SET( CPACK_POST_BUILD_SCRIPTS "${CMAKE_SOURCE_DIR}/scripts/build/macOS/DMGSign.cmake" )
|
SET( CPACK_POST_BUILD_SCRIPTS "${CMAKE_SOURCE_DIR}/scripts/build/macOS/DMGSign.cmake" )
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -55,6 +55,6 @@ if( NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" )
|
||||||
install( FILES "${_SRCDIR}/audacity.1"
|
install( FILES "${_SRCDIR}/audacity.1"
|
||||||
DESTINATION "${_MANDIR}/man1" )
|
DESTINATION "${_MANDIR}/man1" )
|
||||||
install( FILES "${_SRCDIR}/audacity.appdata.xml"
|
install( FILES "${_SRCDIR}/audacity.appdata.xml"
|
||||||
DESTINATION "${_DATADIR}/appdata" )
|
DESTINATION "${_DATADIR}/metainfo" )
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
<url type="bugtracker">https://bugzilla.audacityteam.org/</url>
|
<url type="bugtracker">https://bugzilla.audacityteam.org/</url>
|
||||||
<url type="faq">https://manual.audacityteam.org/man/faq.html</url>
|
<url type="faq">https://manual.audacityteam.org/man/faq.html</url>
|
||||||
<url type="help">https://manual.audacityteam.org/</url>
|
<url type="help">https://manual.audacityteam.org/</url>
|
||||||
<url type="donation">https://www.audacityteam.org/donate/</url>
|
|
||||||
<url type="translate">https://www.audacityteam.org/community/translators/</url>
|
<url type="translate">https://www.audacityteam.org/community/translators/</url>
|
||||||
<screenshots>
|
<screenshots>
|
||||||
<screenshot type="default">
|
<screenshot type="default">
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# The AppImage runtime sets some special environment variables. We provide
|
||||||
|
# default values here in case the user tries to run this script outside an
|
||||||
|
# AppImage where the variables would otherwise be undefined.
|
||||||
|
if [[ ! "${APPIMAGE}" || ! "${APPDIR}" ]]; then
|
||||||
|
export APPIMAGE="$(readlink -f "${0}")"
|
||||||
|
export APPDIR="$(dirname "${APPIMAGE}")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH="${APPDIR}/lib:${LD_LIBRARY_PATH}"
|
||||||
|
|
||||||
|
function help()
|
||||||
|
{
|
||||||
|
# Normal audacity help
|
||||||
|
"${APPDIR}/bin/audacity" --help
|
||||||
|
# Special options handled by this script
|
||||||
|
cat >&2 <<EOF
|
||||||
|
--readme display README
|
||||||
|
--license display LICENSE
|
||||||
|
--man[ual|page] display audacity(1) manual page
|
||||||
|
--check-dependencies check library dependency fulfillment (developer tool)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
# Blank line then special options handled by the AppImage runtime
|
||||||
|
"${APPIMAGE}" --appimage-help
|
||||||
|
}
|
||||||
|
|
||||||
|
# Intercept command line arguments
|
||||||
|
case "$1" in
|
||||||
|
-h|--help )
|
||||||
|
help
|
||||||
|
;;
|
||||||
|
--readme )
|
||||||
|
exec less "${APPDIR}/share/doc/audacity/README.txt"
|
||||||
|
;;
|
||||||
|
--license )
|
||||||
|
exec less "${APPDIR}/share/doc/audacity/LICENSE.txt"
|
||||||
|
;;
|
||||||
|
--man|--manual|--manpage )
|
||||||
|
exec man "${APPDIR}/share/man/man1/audacity.1"
|
||||||
|
;;
|
||||||
|
--check-depends|--check-dependencies )
|
||||||
|
exec bash "${APPDIR}/bin/check_dependencies"
|
||||||
|
;;
|
||||||
|
* )
|
||||||
|
# Other arguments go to Audacity
|
||||||
|
exec "${APPDIR}/bin/audacity" "$@"
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -0,0 +1,95 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
version="@CPACK_PACKAGE_NAME@ v@CPACK_PACKAGE_VERSION@ @CPACK_AUDACITY_ARCH_LABEL@"
|
||||||
|
|
||||||
|
export LC_ALL=C # Using `sort` a lot. Order depends on locale so override it.
|
||||||
|
|
||||||
|
# PROBLEM: We want to check dependencies provided by the system, but `ldd`
|
||||||
|
# looks in the current directory first so will show other package libraries.
|
||||||
|
# SOLUTION: Copy library to temporary folder and test it there.
|
||||||
|
function check_file()
|
||||||
|
{
|
||||||
|
counter=$(($(cat "$2/.counter")+1))
|
||||||
|
echo ${counter} > "$2/.counter"
|
||||||
|
printf >&2 "Done ${counter} of $3.\r"
|
||||||
|
cp "$1" "$2"
|
||||||
|
file="$(basename "$1")"
|
||||||
|
LANG=C LD_LIBRARY_PATH="" "${APPDIR}/bin/ldd_recursive" -uniq "$2/${file}" 2>/dev/null
|
||||||
|
rm "$2/${file}" # delete library before we test the next one
|
||||||
|
}
|
||||||
|
export -f check_file # make function available in Bash subprocesses
|
||||||
|
|
||||||
|
function prep_result()
|
||||||
|
{
|
||||||
|
sed -n "s|$2||p" "$1" | sort -f | tee "$3" | wc -l
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! which less >/dev/null; then
|
||||||
|
function less() { cat "$@"; } # use `cat` if `less` is unavailable
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmp="$(mktemp -d)"
|
||||||
|
trap "rm -rf '${tmp}'" EXIT
|
||||||
|
|
||||||
|
cd "${APPDIR}"
|
||||||
|
|
||||||
|
find . -executable -type f \! -name "lib*.so*" > "${tmp}/exes.txt"
|
||||||
|
find . -name "lib*.so*" \! -type l > "${tmp}/libs.txt"
|
||||||
|
|
||||||
|
num_exes="$(<"${tmp}/exes.txt" xargs -n1 basename 2>/dev/null | tee "${tmp}/exes2.txt" | wc -l)"
|
||||||
|
num_libs="$(<"${tmp}/libs.txt" xargs -n1 basename 2>/dev/null | tee "${tmp}/libs2.txt" | wc -l)"
|
||||||
|
|
||||||
|
echo >&2 "AppImage contains ${num_exes} executables and ${num_libs} libraries."
|
||||||
|
|
||||||
|
echo >&2 "Checking dependencies for executables and libraries..."
|
||||||
|
include_libs="${tmp}/libs.txt"
|
||||||
|
num_includes="$((${num_libs}+${num_exes}))"
|
||||||
|
|
||||||
|
# Check dependencies against system. See 'check_file' function.
|
||||||
|
echo 0 > "${tmp}/.counter"
|
||||||
|
cat "${tmp}/exes.txt" "${include_libs}" | xargs -n1 -I '%%%' bash -c \
|
||||||
|
'check_file "${0}" "${1}" "${2}"' "%%%" "${tmp}" "${num_includes}" \; \
|
||||||
|
| sort | uniq > "${tmp}/deps.txt"
|
||||||
|
echo >&2 "Processing results."
|
||||||
|
|
||||||
|
mv "${tmp}/libs2.txt" "${tmp}/libs.txt"
|
||||||
|
mv "${tmp}/exes2.txt" "${tmp}/exes.txt"
|
||||||
|
|
||||||
|
# Have only checked system libraries. Now consider those in package:
|
||||||
|
<"${tmp}/libs.txt" xargs -n1 -I '%%%' sed -i 's|^%%% => not found$|%%% => package|' "${tmp}/deps.txt"
|
||||||
|
<"${tmp}/libs.txt" xargs -n1 -I '%%%' sed -i 's|%%%$|%%% => both|' "${tmp}/deps.txt"
|
||||||
|
|
||||||
|
# Remaining dependencies must be system:
|
||||||
|
sed -ri 's/^(.*[^(not found|package|both)])$/\1 => system/' "${tmp}/deps.txt"
|
||||||
|
|
||||||
|
num_package=$(prep_result "${tmp}/deps.txt" ' => package$' "${tmp}/package.txt")
|
||||||
|
num_system=$(prep_result "${tmp}/deps.txt" ' => system$' "${tmp}/system.txt")
|
||||||
|
num_both=$(prep_result "${tmp}/deps.txt" ' => both$' "${tmp}/both.txt")
|
||||||
|
num_neither=$(prep_result "${tmp}/deps.txt" ' => not found$' "${tmp}/neither.txt")
|
||||||
|
|
||||||
|
# Any libraries included in package that don't appear in 'deps.txt' **might**
|
||||||
|
# not actually be needed. Careful: they might be needed by a plugin!
|
||||||
|
num_extra=$(<"${tmp}/libs.txt" xargs -n1 -I '%%%' sh -c \
|
||||||
|
"grep -q '%%%' \"${tmp}/deps.txt\" || echo '%%%'" \
|
||||||
|
| sort -f | tee "${tmp}/extra.txt" | wc -l)
|
||||||
|
|
||||||
|
less <<EOF
|
||||||
|
# Package: ${version}
|
||||||
|
# System: $(uname -srmo)
|
||||||
|
$(cat /etc/*release*)
|
||||||
|
|
||||||
|
# In package only: ${num_package}
|
||||||
|
$(cat "${tmp}/package.txt")
|
||||||
|
|
||||||
|
# System only: ${num_system}
|
||||||
|
$(cat "${tmp}/system.txt")
|
||||||
|
|
||||||
|
# Provided by both: ${num_both}
|
||||||
|
$(cat "${tmp}/both.txt")
|
||||||
|
|
||||||
|
# Provided by neither: ${num_neither}
|
||||||
|
$(cat "${tmp}/neither.txt")
|
||||||
|
|
||||||
|
# Extra: ${num_extra} (In package but unlinked. Possibly needed by plugins.)
|
||||||
|
$(cat "${tmp}/extra.txt")
|
||||||
|
EOF
|
|
@ -0,0 +1,113 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
((${BASH_VERSION%%.*} >= 4)) || { echo >&2 "$0: Error: Please upgrade Bash."; exit 1; }
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
readonly appdir="$1" # input path (Audacity install directory)
|
||||||
|
readonly appimage="$2" # output path to use for created AppImage
|
||||||
|
|
||||||
|
#============================================================================
|
||||||
|
# Helper functions
|
||||||
|
#============================================================================
|
||||||
|
|
||||||
|
function download_github_release()
|
||||||
|
{
|
||||||
|
local -r repo_slug="$1" release_tag="$2" file="$3"
|
||||||
|
wget -q --show-progress "https://github.com/${repo_slug}/releases/download/${release_tag}/${file}"
|
||||||
|
chmod +x "${file}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function extract_appimage()
|
||||||
|
{
|
||||||
|
# Extract AppImage so we can run it without having to install FUSE
|
||||||
|
local -r image="$1" binary_name="$2"
|
||||||
|
local -r dir="${image%.AppImage}.AppDir"
|
||||||
|
"./${image}" --appimage-extract >/dev/null # dest folder "squashfs-root"
|
||||||
|
mv squashfs-root "${dir}" # rename folder to avoid collisions
|
||||||
|
ln -s "${dir}/AppRun" "${binary_name}" # symlink for convenience
|
||||||
|
rm -f "${image}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function download_appimage_release()
|
||||||
|
{
|
||||||
|
local -r github_repo_slug="$1" binary_name="$2" tag="$3"
|
||||||
|
local -r image="${binary_name}-x86_64.AppImage"
|
||||||
|
download_github_release "${github_repo_slug}" "${tag}" "${image}"
|
||||||
|
extract_appimage "${image}" "${binary_name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function download_linuxdeploy_component()
|
||||||
|
{
|
||||||
|
local -r component="$1" tag="$2"
|
||||||
|
download_appimage_release "linuxdeploy/$1" "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_path()
|
||||||
|
{
|
||||||
|
local -r path="$1"
|
||||||
|
if [[ -d "${path}" ]]; then
|
||||||
|
return 1 # already exists
|
||||||
|
fi
|
||||||
|
mkdir -p "${path}"
|
||||||
|
}
|
||||||
|
|
||||||
|
#============================================================================
|
||||||
|
# Fetch AppImage packaging tools
|
||||||
|
#============================================================================
|
||||||
|
|
||||||
|
if create_path "appimagetool"; then
|
||||||
|
(
|
||||||
|
cd "appimagetool"
|
||||||
|
download_appimage_release AppImage/AppImageKit appimagetool continuous
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
export PATH="${PWD%/}/appimagetool:${PATH}"
|
||||||
|
appimagetool --version
|
||||||
|
|
||||||
|
if create_path "linuxdeploy"; then
|
||||||
|
(
|
||||||
|
cd "linuxdeploy"
|
||||||
|
download_linuxdeploy_component linuxdeploy continuous
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
export PATH="${PWD%/}/linuxdeploy:${PATH}"
|
||||||
|
linuxdeploy --list-plugins
|
||||||
|
|
||||||
|
#============================================================================
|
||||||
|
# Create symlinks
|
||||||
|
#============================================================================
|
||||||
|
|
||||||
|
ln -sf --no-dereference . "${appdir}/usr"
|
||||||
|
ln -sf share/applications/audacity.desktop "${appdir}/audacity.desktop"
|
||||||
|
ln -sf share/icons/hicolor/scalable/apps/audacity.svg "${appdir}/audacity.svg"
|
||||||
|
ln -sf share/icons/hicolor/scalable/apps/audacity.svg "${appdir}/.DirIcon"
|
||||||
|
|
||||||
|
#============================================================================
|
||||||
|
# Bundle dependencies
|
||||||
|
#============================================================================
|
||||||
|
|
||||||
|
# HACK: Some wxWidget libraries depend on themselves. Add
|
||||||
|
# them to LD_LIBRARY_PATH so that linuxdeploy can find them.
|
||||||
|
export LD_LIBRARY_PATH="${appdir}/usr/lib/audacity:${LD_LIBRARY_PATH-}"
|
||||||
|
|
||||||
|
linuxdeploy --appdir "${appdir}" # add all shared library dependencies
|
||||||
|
|
||||||
|
#============================================================================
|
||||||
|
# Build AppImage
|
||||||
|
#============================================================================
|
||||||
|
|
||||||
|
appimagetool_args=(
|
||||||
|
# none
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ "${AUDACITY_UPDATE_INFO-}" ]]; then
|
||||||
|
# Enable updates. See https://github.com/AppImage/AppImageSpec/blob/master/draft.md#update-information
|
||||||
|
appimagetool_args+=( --updateinformation="${AUDACITY_UPDATE_INFO}" )
|
||||||
|
else
|
||||||
|
echo >&2 "$0: Automatic updates disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create AppImage
|
||||||
|
cd "$(dirname "${appimage}")" # otherwise zsync created in wrong directory
|
||||||
|
appimagetool "${appimagetool_args[@]}" "${appdir}" "${appimage}"
|
|
@ -0,0 +1,205 @@
|
||||||
|
#!/usr/bin/env perl
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Written by Igor Ljubuncic (igor.ljubuncic@intel.com)
|
||||||
|
# Yuval Nissan (yuval.nissan@intel.com)
|
||||||
|
#
|
||||||
|
# Version 1.0 on Mar 29, 2011
|
||||||
|
#
|
||||||
|
# This program performs recursive ldd checks for binaries and libraries
|
||||||
|
# It recurses through entire ldd tree for every listed binary and library
|
||||||
|
# It completes when no matches found in the current branch
|
||||||
|
# Same limitations to standard ldd apply
|
||||||
|
# ldd cannot check libraries with no permissions
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# /*
|
||||||
|
#
|
||||||
|
# This file is provided under a dual BSD/GPLv2 license. When using or
|
||||||
|
# redistributing this file, you may do so under either license.
|
||||||
|
#
|
||||||
|
# GPL LICENSE SUMMARY
|
||||||
|
#
|
||||||
|
# Copyright(c) 2011 Intel Corporation. All rights reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of version 2 of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
# The full GNU General Public License is included in this distribution
|
||||||
|
# in the file called LICENSE.GPL.
|
||||||
|
#
|
||||||
|
# Contact Information:
|
||||||
|
# Igor Ljubuncic, igor.ljubuncic@intel.com
|
||||||
|
# P.O.B 1659, MATAM, 31015 Haifa, Israel
|
||||||
|
#
|
||||||
|
# BSD LICENSE
|
||||||
|
#
|
||||||
|
# Copyright(c) 2011 Intel Corporation. All rights reserved.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Intel Corporation nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived
|
||||||
|
# from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
# */
|
||||||
|
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use Data::Dumper;
|
||||||
|
use Getopt::Long;
|
||||||
|
|
||||||
|
# global variables
|
||||||
|
# ----------------
|
||||||
|
|
||||||
|
my $result;
|
||||||
|
my @inputs = ();
|
||||||
|
my $helpoption=0;
|
||||||
|
my $debug=0;
|
||||||
|
my $verbose=0;
|
||||||
|
my $sep;
|
||||||
|
my $print_vars;
|
||||||
|
my $uniq;
|
||||||
|
my %uniq;
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
#############################################
|
||||||
|
### ###
|
||||||
|
### FUNCTION MAIN ###
|
||||||
|
### ###
|
||||||
|
#############################################
|
||||||
|
#############################################
|
||||||
|
|
||||||
|
|
||||||
|
GetOptions(
|
||||||
|
'h|help+' => \$helpoption,
|
||||||
|
'debug+' => \$verbose,
|
||||||
|
't=s' => \$sep,
|
||||||
|
'l' => \$print_vars,
|
||||||
|
'uniq' => \$uniq
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($verbose==1) {
|
||||||
|
# Print messages for debug purposes
|
||||||
|
$debug = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($helpoption==1) || ($ARGV[0] eq "")) {
|
||||||
|
print "\nRecursive ldd v1.00\n";
|
||||||
|
print "Written by Igor Ljubuncic (igor.ljubuncic\@intel.com)\n";
|
||||||
|
print "Written by Yuval Nissan (yuval.nissan\@intel.com)\n\n";
|
||||||
|
print "Usage mode:\n\n";
|
||||||
|
print "-d\t\tverbose output\n";
|
||||||
|
print "-h|help\t\tprint help\n";
|
||||||
|
print "-t\t\tdelimiter\n";
|
||||||
|
print "-l\t\tprint env. variables\n";
|
||||||
|
print "-uniq\t\tprint unique values only\n\n";
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sep ||= "\t";
|
||||||
|
|
||||||
|
push @inputs, @ARGV;
|
||||||
|
|
||||||
|
if($print_vars) {
|
||||||
|
print "ldd output can be affected by:\n";
|
||||||
|
print "\$LD_LIBRARY_PATH = '".$ENV{LD_LIBRARY_PATH}."'\n";
|
||||||
|
print "\$LD_PRELOAD = '".$ENV{LD_PRELOAD}."'\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
&recurseLibs($inputs[0], 0);
|
||||||
|
delete $uniq{$inputs[0]};
|
||||||
|
print join("\n", keys(%uniq))."\n" if $uniq;
|
||||||
|
|
||||||
|
exit 0;
|
||||||
|
|
||||||
|
##############################
|
||||||
|
##############################
|
||||||
|
## ##
|
||||||
|
## FUNCTIONS ##
|
||||||
|
## ##
|
||||||
|
##############################
|
||||||
|
##############################
|
||||||
|
|
||||||
|
sub recurseLibs
|
||||||
|
{
|
||||||
|
my $filename=shift;
|
||||||
|
my $depth = shift;
|
||||||
|
print "Working on file: $filename\n" if $debug;
|
||||||
|
print "$sep"x$depth if not $uniq;
|
||||||
|
++$depth;
|
||||||
|
return if $uniq{$filename} and $uniq;
|
||||||
|
$uniq{$filename} = 1;
|
||||||
|
print "$filename\n" if not $uniq;
|
||||||
|
chomp(my @libraries = `/usr/bin/ldd $filename`);
|
||||||
|
print "Libraries:\n@libraries\n" if $debug;
|
||||||
|
|
||||||
|
foreach my $line (@libraries) {
|
||||||
|
next if not $line;
|
||||||
|
$line =~ s/^\s+//g;
|
||||||
|
$line =~ s/\s+$//g;
|
||||||
|
# If static or else
|
||||||
|
if (($line =~ /statically linked/) or ($line =~ /not a dynamic executable/)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elsif($line =~ /not found/) {
|
||||||
|
print "$sep"x$depth if not $uniq;
|
||||||
|
print "$line\n" if not $uniq;
|
||||||
|
$uniq{$line} = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Split and recurse on libraries (third value is the lib path):
|
||||||
|
my @newlibs = split(/\s+/,$line);
|
||||||
|
print Dumper(\@newlibs) if $debug;
|
||||||
|
|
||||||
|
# Skip if no mapped or directly linked
|
||||||
|
# Sane output comes with four elements
|
||||||
|
if (scalar(@newlibs) < 4) {
|
||||||
|
print "$sep"x$depth if not $uniq;
|
||||||
|
print $newlibs[0]."\n" if not $uniq;
|
||||||
|
$uniq{$newlibs[0]} = 1;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
print "\nI'm gonna enter recursion with $newlibs[2].\n\n" if $debug;
|
||||||
|
&recurseLibs($newlibs[2], $depth);
|
||||||
|
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
__END__
|
|
@ -0,0 +1,27 @@
|
||||||
|
if(CPACK_EXTERNAL_ENABLE_STAGING)
|
||||||
|
set(appdir "${CPACK_TEMPORARY_DIRECTORY}")
|
||||||
|
else()
|
||||||
|
set(appdir "${CPACK_INSTALL_PREFIX}")
|
||||||
|
endif()
|
||||||
|
set(appimage "${CPACK_PACKAGE_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}.AppImage")
|
||||||
|
|
||||||
|
set(CPACK_EXTERNAL_BUILT_PACKAGES "${appimage}")
|
||||||
|
|
||||||
|
if(DEFINED CPACK_AUDACITY_APPIMAGE_UPDATE_INFO)
|
||||||
|
set(ENV{AUDACITY_UPDATE_INFO} "${CPACK_AUDACITY_APPIMAGE_UPDATE_INFO}")
|
||||||
|
list(APPEND CPACK_EXTERNAL_BUILT_PACKAGES "${appimage}.zsync")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file("${CPACK_AUDACITY_SOURCE_DIR}/linux/AppRun.sh" "${appdir}/AppRun" ESCAPE_QUOTES @ONLY)
|
||||||
|
configure_file("${CPACK_AUDACITY_SOURCE_DIR}/linux/check_dependencies.sh" "${appdir}/bin/check_dependencies" ESCAPE_QUOTES @ONLY)
|
||||||
|
configure_file("${CPACK_AUDACITY_SOURCE_DIR}/linux/ldd_recursive.pl" "${appdir}/bin/ldd_recursive" COPYONLY)
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND "linux/create_appimage.sh" "${appdir}" "${appimage}"
|
||||||
|
WORKING_DIRECTORY "${CPACK_AUDACITY_SOURCE_DIR}"
|
||||||
|
RESULT_VARIABLE exit_status
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT "${exit_status}" EQUAL "0")
|
||||||
|
message(FATAL_ERROR "Could not create AppImage. See output above for details.")
|
||||||
|
endif()
|
|
@ -23,9 +23,20 @@ elif [[ "${OSTYPE}" == darwin* ]]; then # macOS
|
||||||
|
|
||||||
else # Linux & others
|
else # Linux & others
|
||||||
|
|
||||||
|
if ! which sudo; then
|
||||||
|
function sudo() { "$@"; } # no-op sudo for use in Docker images
|
||||||
|
fi
|
||||||
|
|
||||||
# Distribution packages
|
# Distribution packages
|
||||||
if which apt-get; then
|
if which apt-get; then
|
||||||
apt_packages=(
|
apt_packages=(
|
||||||
|
# Docker image
|
||||||
|
file
|
||||||
|
g++
|
||||||
|
git
|
||||||
|
wget
|
||||||
|
|
||||||
|
# GitHub Actions
|
||||||
libasound2-dev
|
libasound2-dev
|
||||||
libgtk2.0-dev
|
libgtk2.0-dev
|
||||||
gettext
|
gettext
|
||||||
|
@ -43,6 +54,9 @@ else # Linux & others
|
||||||
pip_packages=(
|
pip_packages=(
|
||||||
conan
|
conan
|
||||||
)
|
)
|
||||||
|
|
||||||
|
which cmake || pip_packages+=( cmake ) # get latest CMake when inside Docker image
|
||||||
|
|
||||||
pip3 install wheel setuptools # need these first to install other packages (e.g. conan)
|
pip3 install wheel setuptools # need these first to install other packages (e.g. conan)
|
||||||
pip3 install "${pip_packages[@]}"
|
pip3 install "${pip_packages[@]}"
|
||||||
|
|
||||||
|
|
|
@ -1243,6 +1243,9 @@ else()
|
||||||
#
|
#
|
||||||
# (Don't use generator expressions since it will leave null/empty
|
# (Don't use generator expressions since it will leave null/empty
|
||||||
# entries in the list.)
|
# entries in the list.)
|
||||||
|
set( MIMETYPES
|
||||||
|
application/x-audacity-project
|
||||||
|
)
|
||||||
if( USE_FFMPEG )
|
if( USE_FFMPEG )
|
||||||
list( APPEND MIMETYPES
|
list( APPEND MIMETYPES
|
||||||
audio/aac
|
audio/aac
|
||||||
|
|
|
@ -53,4 +53,4 @@ Categories=AudioVideo;Audio;AudioVideoEditing;
|
||||||
Exec=env UBUNTU_MENUPROXY=0 @AUDACITY_NAME@ %F
|
Exec=env UBUNTU_MENUPROXY=0 @AUDACITY_NAME@ %F
|
||||||
StartupNotify=false
|
StartupNotify=false
|
||||||
Terminal=false
|
Terminal=false
|
||||||
MimeType=application/x-audacity-project;@MIMETYPES@
|
MimeType=@MIMETYPES@;
|
||||||
|
|
Loading…
Reference in New Issue