From 3f2339dac7476e1acea5392ec3e8e6fbfe2b6d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E5=8D=9A=E4=BB=81=28Buo-ren=20Lin=29?= Date: Wed, 27 Mar 2019 18:43:07 +0800 Subject: [PATCH] Implement snap packaging, snaps are universal Linux packages(#704) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Snaps][1] are universal Linux packages that can be installed and run on many GNU+Linux distributions with ease. This patch implements the necessary details to package SimpleScreenRecorder as a snap. [Install Snapcraft][2] and run `snapcraft` under the source tree to build it. [1]: https://snapcraft.io [2]: https://docs.snapcraft.io/snapcraft-overview/8940 Signed-off-by: 林博仁(Buo-ren Lin) --- .gitignore | 9 + .../launchers/simplescreenrecorder-launch | 14 + .../local/patching/patch-desktop-entries.bash | 217 ++++++++++++++++ snap/local/patching/patch-desktop-entries.sed | 28 ++ snap/local/scriptlets/main-adopt-info | 74 ++++++ snap/snapcraft.yaml | 245 ++++++++++++++++++ 6 files changed, 587 insertions(+) create mode 100755 snap/local/launchers/simplescreenrecorder-launch create mode 100755 snap/local/patching/patch-desktop-entries.bash create mode 100644 snap/local/patching/patch-desktop-entries.sed create mode 100755 snap/local/scriptlets/main-adopt-info create mode 100644 snap/snapcraft.yaml diff --git a/.gitignore b/.gitignore index 04c46373..722dab78 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,12 @@ build-* src/simplescreenrecorder private-* + +# Snap packaging specific rules +/snap/.snapcraft/ +/parts/ +/stage/ +/prime/ + +/*.snap +/*_source.tar.bz2 diff --git a/snap/local/launchers/simplescreenrecorder-launch b/snap/local/launchers/simplescreenrecorder-launch new file mode 100755 index 00000000..f017e861 --- /dev/null +++ b/snap/local/launchers/simplescreenrecorder-launch @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# This is the maintainence launcher for the snap, make necessary runtime environment changes to make the snap work here. You may also insert security confinement/deprecation/obsoletion notice of the snap here. + +set \ + -o errexit \ + -o errtrace \ + -o nounset \ + -o pipefail + +# gtk-common-themes support +export QT_QPA_PLATFORMTHEME=gtk3 + +# Finally run the next part of the command chain +exec "${@}" diff --git a/snap/local/patching/patch-desktop-entries.bash b/snap/local/patching/patch-desktop-entries.bash new file mode 100755 index 00000000..a6deaf78 --- /dev/null +++ b/snap/local/patching/patch-desktop-entries.bash @@ -0,0 +1,217 @@ +#!/usr/bin/env bash +# Utility script to patch desktop entries in snap, should only be run in the `override-prime` scriptlet +# 林博仁 © 2018 + +## Makes debuggers' life easier - Unofficial Bash Strict Mode +## BASHDOC: Shell Builtin Commands - Modifying Shell Behavior - The Set Builtin +set \ + -o errexit \ + -o errtrace \ + -o nounset \ + -o pipefail + +## Runtime Dependencies Checking +declare\ + runtime_dependency_checking_result=still-pass\ + required_software + +for required_command in \ + basename \ + dirname \ + realpath; do + if ! command -v "${required_command}" &>/dev/null; then + runtime_dependency_checking_result=fail + + case "${required_command}" in + basename \ + |dirname \ + |realpath) + required_software='GNU Coreutils' + ;; + find \ + |xargs) + required_software='GNU Findutils' + ;; + sed) + required_software='GNU Sed' + ;; + *) + required_software="${required_command}" + ;; + esac + + printf -- \ + 'Error: This program requires "%s" to be installed and its executables in the executable searching paths.\n' \ + "${required_software}" \ + 1>&2 + unset required_software + fi +done; unset required_command required_software + +if [ "${runtime_dependency_checking_result}" = fail ]; then + printf -- \ + 'Error: Runtime dependency checking fail, the progrom cannot continue.\n' \ + 1>&2 + exit 1 +fi; unset runtime_dependency_checking_result + +## Non-overridable Primitive Variables +## BASHDOC: Shell Variables » Bash Variables +## BASHDOC: Basic Shell Features » Shell Parameters » Special Parameters +if [ -v 'BASH_SOURCE[0]' ]; then + RUNTIME_EXECUTABLE_PATH="$(realpath --strip "${BASH_SOURCE[0]}")" + RUNTIME_EXECUTABLE_FILENAME="$(basename "${RUNTIME_EXECUTABLE_PATH}")" + RUNTIME_EXECUTABLE_NAME="${RUNTIME_EXECUTABLE_FILENAME%.*}" + RUNTIME_EXECUTABLE_DIRECTORY="$(dirname "${RUNTIME_EXECUTABLE_PATH}")" + RUNTIME_COMMANDLINE_BASECOMMAND="${0}" + # We intentionally leaves these variables for script developers + # shellcheck disable=SC2034 + declare -r \ + RUNTIME_EXECUTABLE_PATH \ + RUNTIME_EXECUTABLE_FILENAME \ + RUNTIME_EXECUTABLE_NAME \ + RUNTIME_EXECUTABLE_DIRECTORY \ + RUNTIME_COMMANDLINE_BASECOMMAND +fi +declare -ar RUNTIME_COMMANDLINE_ARGUMENTS=("${@}") + +## init function: entrypoint of main program +## This function is called near the end of the file, +## with the script's command-line parameters as arguments +init(){ + if ! process_commandline_arguments; then + printf -- \ + 'Error: Invalid command-line parameters.\n' \ + 1>&2 + + printf '\n' # separate error message and help message + print_help + exit 1 + fi + + if ! test -v SNAPCRAFT_PRIME \ + || test "${PWD}" != "${SNAPCRAFT_PRIME}"; then + printf -- \ + "%s: Error: This script should be run by \`snapcraft\` in the \`override-prime\` scriptlet.\\n" \ + "${RUNTIME_EXECUTABLE_NAME}" + exit 1 + fi + + if test -d share/applications; then + find \ + share/applications \ + -name '*.desktop' \ + -print0 \ + | xargs \ + --no-run-if-empty \ + --null \ + --verbose \ + sed \ + --file "${RUNTIME_EXECUTABLE_DIRECTORY}"/patch-desktop-entries.sed \ + --in-place + fi + + exit 0 +}; declare -fr init + +print_help(){ + # Backticks in help message is Markdown's markup + # shellcheck disable=SC2016 + { + printf '# Help Information for %s #\n' \ + "${RUNTIME_COMMANDLINE_BASECOMMAND}" + printf '## SYNOPSIS ##\n' + printf '* `"%s" _command-line_options_`\n\n' \ + "${RUNTIME_COMMANDLINE_BASECOMMAND}" + + printf '## COMMAND-LINE OPTIONS ##\n' + printf '### `-d` / `--debug` ###\n' + printf 'Enable script debugging\n\n' + + printf '### `-h` / `--help` ###\n' + printf 'Print this message\n\n' + } + return 0 +}; declare -fr print_help; + +process_commandline_arguments() { + if [ "${#RUNTIME_COMMANDLINE_ARGUMENTS[@]}" -eq 0 ]; then + return 0 + fi + + # Modifyable parameters for parsing by consuming + local -a parameters=("${RUNTIME_COMMANDLINE_ARGUMENTS[@]}") + + # Normally we won't want debug traces to appear during parameter parsing, so we add this flag and defer its activation till returning(Y: Do debug) + local enable_debug=N + + while true; do + if [ "${#parameters[@]}" -eq 0 ]; then + break + else + case "${parameters[0]}" in + --debug \ + |-d) + enable_debug=Y + ;; + --help \ + |-h) + print_help; + exit 0 + ;; + *) + printf -- \ + '%s: Error: Unknown command-line argument "%s"\n' \ + "${FUNCNAME[0]}" \ + "${parameters[0]}" \ + >&2 + return 1 + ;; + esac + # shift array by 1 = unset 1st then repack + unset 'parameters[0]' + if [ "${#parameters[@]}" -ne 0 ]; then + parameters=("${parameters[@]}") + fi + fi + done + + if [ "${enable_debug}" = Y ]; then + trap 'trap_return "${FUNCNAME[0]}"' RETURN + set -o xtrace + fi + return 0 +}; declare -fr process_commandline_arguments + +## Traps: Functions that are triggered when certain condition occurred +## Shell Builtin Commands » Bourne Shell Builtins » trap +trap_errexit(){ + printf \ + 'An error occurred and the script is prematurely aborted\n' \ + 1>&2 + return 0 +}; declare -fr trap_errexit; trap trap_errexit ERR + +trap_exit(){ + return 0 +}; declare -fr trap_exit; trap trap_exit EXIT + +trap_return(){ + local returning_function="${1}" + + printf \ + 'DEBUG: %s: returning from %s\n' \ + "${FUNCNAME[0]}" \ + "${returning_function}" \ + 1>&2 +}; declare -fr trap_return + +trap_interrupt(){ + printf '\n' # Separate previous output + printf \ + 'Recieved SIGINT, script is interrupted.' \ + 1>&2 + return 1 +}; declare -fr trap_interrupt; trap trap_interrupt INT + +init "${@}" \ No newline at end of file diff --git a/snap/local/patching/patch-desktop-entries.sed b/snap/local/patching/patch-desktop-entries.sed new file mode 100644 index 00000000..273a86c1 --- /dev/null +++ b/snap/local/patching/patch-desktop-entries.sed @@ -0,0 +1,28 @@ +# This sed script patches the desktop entries of the snapped +# application. +# +# Documentation: +# +# * GNU Sed Manual +# https://www.gnu.org/software/sed/manual +# * `sed` script overview - `sed` scripts +# * `sed` commands summary - `sed` scripts +# * The `s` Command - `sed` scripts +# * Overview of basic regular expression syntax - Regular +# Expressions: selecting text +# * Back-references and Subexpressions - Regular Expressions: +# selecting text + +## Append '(Snap)' to the application name to make it +## distinguishable with the other same application using different +## software distribution technologies +## +## FIXME: The appended string is not localizable, the proper way to +## implement this is to probably use a new X-Snappy-Name keys +## with localestring format to let the translators fill in +## additional localized string and use these values to replace +## the Name keys here. +s/^\(Name\(\[.\+\]\)\?=.*\)$/\1 (Snap)/g + +## Fix-up application icon lookup +s|^Icon=.*|Icon=\${SNAP}/meta/gui/icon.svg| diff --git a/snap/local/scriptlets/main-adopt-info b/snap/local/scriptlets/main-adopt-info new file mode 100755 index 00000000..93390428 --- /dev/null +++ b/snap/local/scriptlets/main-adopt-info @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +# Extract and set the snap's version from the main part +# 林博仁(Buo-ren, Lin) © 2019 + +set \ + -o errexit \ + -o errtrace \ + -o nounset \ + -o pipefail + +init(){ + local \ + flag_dry_run=false \ + upstream_version \ + packaging_revision \ + some_place_under_the_project_repo \ + snap_version_string + + for commandline_argument in "${@}"; do + case "${commandline_argument}" in + # Enable execution tracing + --debug) + set -o xtrace + ;; + # Don't run snapcraftctl for testing purpose + --dry-run) + flag_dry_run=true + ;; + --usage) + print_usage + exit 0 + ;; + *) + printf -- \ + 'main-adopt-info: Error: Invalid command-line argument.\n' \ + >&2 + print_usage + exit 1 + ;; + esac + done + + if ! git describe &>/dev/null; then + upstream_version=unknown + else + upstream_version="$( + git \ + describe \ + --always \ + --dirty=-d \ + --tags \ + | sed s/^v// + )" + fi + + snap_version_string="${upstream_version}" + + printf -- \ + 'main-adopt-info: Setting snap version to "%s".\n' \ + "${snap_version_string}" + if [ "${flag_dry_run}" = false ]; then + snapcraftctl set-version \ + "${snap_version_string}" + fi + + exit 0 +} + +print_usage(){ + printf -- 'Usage: main-adopt-info [options] _snap_name_\n' + printf -- 'options: [--debug|--dry-run|--help]\n' +} + +init "${@}" diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 00000000..278c311b --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,245 @@ +%YAML 1.1 +--- +# Snapcraft Recipe for SimpleScreenRecorder +# ------------------------------ +# This file is in the YAML data serialization format: +# http://yaml.org +# For the spec. of writing this file refer the following documentation: +# * The snapcraft format +# https://docs.snapcraft.io/the-snapcraft-format/8337 +# * Snap Documentation +# https://docs.snapcraft.io +# * Topics under the doc category in the Snapcraft Forum +# https://forum.snapcraft.io/c/doc +# For support refer to the snapcraft section in the Snapcraft Forum: +# https://forum.snapcraft.io/c/snapcraft +name: simplescreenrecorder +title: SimpleScreenRecorder +summary: A feature-rich screen recorder +description: | + SimpleScreenRecorder is a feature-rich screen recorder that supports + X11 and OpenGL. It has a Qt-based graphical user interface. It can + record the entire screen or part of it, or record OpenGL applications + directly(currently not supported in the snap distribution). The recording + can be paused and resumed at any time. Many different file formats and + codecs are supported. + + **Key features** + + * Synchronizes audio and video properly. + * Reduces the video frame rate if your computer is too slow. + * Fully multithreaded: small delays in any of the components will + never block the other components, resulting is smoother video and + better performance on computers with multiple processors. + * Can also do live streaming (experimental). + + **Known issues** + + Currently OpenGL recording is not supported by this build due to the + confinement and library separation nature of snap apps. + +icon: data/icons/scalable/simplescreenrecorder.svg +license: GPL-3.0 +#version: determined-by-adopt-info + +adopt-info: main +base: core18 +confinement: strict +grade: stable + +parts: + # Files to patch the files in the snap + patching: + source: snap/local/patching + plugin: dump + organize: + '*': patching/ + prime: + - -* + + # Launcher programs to fix problems at runtime + launchers: + source: snap/local/launchers + plugin: dump + organize: + '*': bin/ + + # Scriptlet to only build latest tagged release software if it hasn't + # been promoted to the stable channel + # https://forum.snapcraft.io/t/the-selective-pull-scriptlet-stage-snap-workaround/10389 + selective-pull: + plugin: nil + build-packages: + - git + stage-snaps: + - selective-pull + + # Remote part for support of various desktop technologies + # Refer: https://github.com/ubuntu/snapcraft-desktop-helpers/blob/master/snapcraft.yaml + desktop-qt5: + source: https://github.com/ubuntu/snapcraft-desktop-helpers.git + source-depth: 1 + source-subdir: qt + + plugin: make + make-parameters: ["FLAVOR=qt5"] + build-packages: + - build-essential + - qtbase5-dev + - dpkg-dev + stage-packages: + - libxkbcommon0 + - ttf-ubuntu-font-family + - dmz-cursor-theme + - light-themes + - adwaita-icon-theme + - gnome-themes-standard + - shared-mime-info + - libqt5gui5 + - libgdk-pixbuf2.0-0 + - libqt5svg5 # for loading icon themes which are svg + - try: [appmenu-qt5] # not available on core18 + - locales-all + - xdg-user-dirs + - fcitx-frontend-qt5 + + main: + after: + # for patch-desktop-entries.* + - patching + + # for selective-pull scriptlet + - selective-pull + + source: . + + # For building stable releases when needed + #source-tag: 0.3.11 + + override-pull: | + set -o nounset + "${SNAPCRAFT_STAGE}"/scriptlets/selective-pull + + plugin: cmake + configflags: + # Fix output profiles and localization data access + - -DCMAKE_INSTALL_DATAROOTDIR=/snap/$SNAPCRAFT_PROJECT_NAME/current/share + + # Disable OpenGL recording support as it's not possible due to the confined nature of snaps and also for non i386/AMD64 architecture build from source compatibility + - -DWITH_OPENGL_RECORDING=FALSE + - -DWITH_GLINJECT=FALSE + + - -DWITH_QT5=TRUE + build-packages: + - libasound2-dev + - libavcodec-dev + - libavformat-dev + - libavutil-dev + - libjack-dev + - libpulse-dev + - libqt5x11extras5-dev + - libswscale-dev + - libxi-dev + - libxinerama-dev + - pkg-config + - qt5-default + - qt5-qmake + - qtbase5-dev + - qttools5-dev-tools + stage-packages: + # Used in button and menu entries + - breeze-icon-theme + + - libasound2 + #- libavcodec57 + - libavcodec-extra57 + - libavformat57 + - libavutil55 + - libjack0 + - libpulse0 + - libqt5x11extras5 + - libswscale4 + - libxi6 + - libxinerama1 + + # gtk-common-themes support + - qt5-gtk-platformtheme + + organize: + snap/$SNAPCRAFT_PROJECT_NAME/current: / + stage: + # Drop remnants from organizing + - -snap + override-prime: | + set \ + -o nounset + + snapcraftctl prime + + "${SNAPCRAFT_STAGE}"/patching/patch-desktop-entries.bash + + # Avoid using description from appdata until custom override is supported + # Bug #1820797 “Snapcraft should allow prepending/appending additional text from description extracted from adopt-info” : Bugs : Snapcraft + # https://bugs.launchpad.net/snapcraft/+bug/1820797 + parse-info: + - share/appdata/simplescreenrecorder.appdata.xml + +apps: + simplescreenrecorder: + adapter: full + command: bin/simplescreenrecorder + command-chain: + - bin/desktop-launch + - bin/simplescreenrecorder-launch + + common-id: simplescreenrecorder.desktop + desktop: share/applications/simplescreenrecorder.desktop + #environment: + # gtk-common-themes support + # DISABLED: Got overrided by desktop-launch(`appmenu-qt5`), implement in snap launcher instead + #QT_QPA_PLATFORMTHEME: gtk3 + +plugs: + # Audio access + alsa: # Non-A/C + pulseaudio: + + # For snaps with a graphical user interface: + desktop: + desktop-legacy: + x11: + unity7: + wayland: + + # To allow wayland apps access system theme settings + gsettings: + + # gtk-common-themes support + gtk-3-themes: + interface: content + target: $SNAP/data-dir/themes + default-provider: gtk-common-themes:gtk-3-themes + icon-themes: + interface: content + target: $SNAP/data-dir/icons + default-provider: gtk-common-themes:icon-themes + sound-themes: + interface: content + target: $SNAP/data-dir/sounds + default-provider: gtk-common-themes:sounds-themes + + # T.B.D. + opengl: + + # Storage access + home: + removable-media: # Non-A/C + + # Network access (livestreaming support?) + network: + +layout: + /usr/share/alsa: + bind: $SNAP/usr/share/alsa + /usr/share/X11/locale: + bind: $SNAP/usr/share/X11/locale