URI: 
       tMerge pull request #5042 from SomberNight/appimage - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 76ff2f53c504b8dc9e7a5fce3e25634267e1ec02
   DIR parent ca931f476fc20e0c2003d4eb4fcafceb85e3972e
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Mon,  4 Feb 2019 19:16:15 +0100
       
       Merge pull request #5042 from SomberNight/appimage
       
       binaries for Linux: AppImage
       Diffstat:
         M .travis.yml                         |      11 +++++++++++
         A contrib/build-linux/appimage/Docke… |      25 +++++++++++++++++++++++++
         A contrib/build-linux/appimage/READM… |      41 +++++++++++++++++++++++++++++++
         A contrib/build-linux/appimage/appru… |      11 +++++++++++
         A contrib/build-linux/appimage/build… |     197 +++++++++++++++++++++++++++++++
         M contrib/build-wine/prepare-wine.sh  |      56 ++-----------------------------
         A contrib/build_tools_util.sh         |      69 ++++++++++++++++++++++++++++++
         M contrib/osx/base.sh                 |      16 ++--------------
       
       8 files changed, 359 insertions(+), 67 deletions(-)
       ---
   DIR diff --git a/.travis.yml b/.travis.yml
       t@@ -70,6 +70,17 @@ jobs:
              script: ./contrib/osx/make_osx
              after_script: ls -lah dist && md5 dist/*
              after_success: true
       +    - name: "AppImage build"
       +      sudo: true
       +      language: c
       +      python: false
       +      services:
       +        - docker
       +      install:
       +        - sudo docker build --no-cache -t electrum-appimage-builder-img ./contrib/build-linux/appimage/
       +      script:
       +        - sudo docker run --name electrum-appimage-builder-cont -v $PWD:/opt/electrum --rm --workdir /opt/electrum/contrib/build-linux/appimage electrum-appimage-builder-img ./build.sh
       +      after_success: true
            - stage: release check
              install:
                  - git fetch --all --tags
   DIR diff --git a/contrib/build-linux/appimage/Dockerfile b/contrib/build-linux/appimage/Dockerfile
       t@@ -0,0 +1,25 @@
       +FROM ubuntu:14.04@sha256:cac55e5d97fad634d954d00a5c2a56d80576a08dcc01036011f26b88263f1578
       +
       +ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
       +
       +RUN apt-get update -q && \
       +    apt-get install -qy \
       +        git \
       +        wget \
       +        make \
       +        autotools-dev \
       +        autoconf \
       +        libtool \
       +        xz-utils \
       +        libssl-dev \
       +        zlib1g-dev \
       +        libffi6 \
       +        libffi-dev \
       +        libusb-1.0-0-dev \
       +        libudev-dev \
       +        gettext \
       +        libzbar0  \
       +        && \
       +    rm -rf /var/lib/apt/lists/* && \
       +    apt-get autoremove -y && \
       +    apt-get clean
   DIR diff --git a/contrib/build-linux/appimage/README.md b/contrib/build-linux/appimage/README.md
       t@@ -0,0 +1,41 @@
       +AppImage binary for Electrum
       +============================
       +
       +This assumes an Ubuntu host, but it should not be too hard to adapt to another
       +similar system. The docker commands should be executed in the project's root
       +folder.
       +
       +1. Install Docker
       +
       +    ```
       +    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
       +    $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
       +    $ sudo apt-get update
       +    $ sudo apt-get install -y docker-ce
       +    ```
       +
       +2. Build image
       +
       +    ```
       +    $ sudo docker build --no-cache -t electrum-appimage-builder-img contrib/build-linux/appimage
       +    ```
       +
       +3. Build binary
       +
       +    ```
       +    $ sudo docker run -it \
       +        --name electrum-appimage-builder-cont \
       +        -v $PWD:/opt/electrum \
       +        --rm \
       +        --workdir /opt/electrum/contrib/build-linux/appimage \
       +        electrum-appimage-builder-img \
       +        ./build.sh
       +    ```
       +
       +4. The generated binary is in `./dist`.
       +
       +
       +## FAQ
       +
       +### How can I see what is included in the AppImage?
       +Execute the binary as follows: `./electrum*.AppImage --appimage-extract`
   DIR diff --git a/contrib/build-linux/appimage/apprun.sh b/contrib/build-linux/appimage/apprun.sh
       t@@ -0,0 +1,11 @@
       +#!/bin/bash
       +
       +set -e
       +
       +APPDIR="$(dirname "$(readlink -e "$0")")"
       +
       +export LD_LIBRARY_PATH="${APPDIR}/usr/lib/:${APPDIR}/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH+:$LD_LIBRARY_PATH}"
       +export PATH="${APPDIR}/usr/bin:${PATH}"
       +export LDFLAGS="-L${APPDIR}/usr/lib/x86_64-linux-gnu -L${APPDIR}/usr/lib"
       +
       +exec "${APPDIR}/usr/bin/python3.6" -s "${APPDIR}/usr/bin/electrum" "$@"
   DIR diff --git a/contrib/build-linux/appimage/build.sh b/contrib/build-linux/appimage/build.sh
       t@@ -0,0 +1,197 @@
       +#!/bin/bash
       +
       +set -e
       +
       +PROJECT_ROOT="$(dirname "$(readlink -e "$0")")/../../.."
       +CONTRIB="$PROJECT_ROOT/contrib"
       +DISTDIR="$PROJECT_ROOT/dist"
       +BUILDDIR="$CONTRIB/build-linux/appimage/build/appimage"
       +APPDIR="$BUILDDIR/electrum.AppDir"
       +CACHEDIR="$CONTRIB/build-linux/appimage/.cache/appimage"
       +
       +# pinned versions
       +PYTHON_VERSION=3.6.8
       +PKG2APPIMAGE_COMMIT="83483c2971fcaa1cb0c1253acd6c731ef8404381"
       +LIBSECP_VERSION="452d8e4d2a2f9f1b5be6b02e18f1ba102e5ca0b4"
       +
       +
       +VERSION=`git describe --tags --dirty --always`
       +APPIMAGE="$DISTDIR/electrum-$VERSION-x86_64.AppImage"
       +
       +rm -rf "$BUILDDIR"
       +mkdir -p "$APPDIR" "$CACHEDIR" "$DISTDIR"
       +
       +
       +. "$CONTRIB"/build_tools_util.sh
       +
       +
       +info "downloading some dependencies."
       +download_if_not_exist "$CACHEDIR/functions.sh" "https://raw.githubusercontent.com/AppImage/pkg2appimage/$PKG2APPIMAGE_COMMIT/functions.sh"
       +verify_hash "$CACHEDIR/functions.sh" "a73a21a6c1d1e15c0a9f47f017ae833873d1dc6aa74a4c840c0b901bf1dcf09c"
       +
       +download_if_not_exist "$CACHEDIR/appimagetool" "https://github.com/probonopd/AppImageKit/releases/download/11/appimagetool-x86_64.AppImage"
       +verify_hash "$CACHEDIR/appimagetool" "c13026b9ebaa20a17e7e0a4c818a901f0faba759801d8ceab3bb6007dde00372"
       +
       +download_if_not_exist "$CACHEDIR/Python-$PYTHON_VERSION.tar.xz" "https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tar.xz"
       +verify_hash "$CACHEDIR/Python-$PYTHON_VERSION.tar.xz" "35446241e995773b1bed7d196f4b624dadcadc8429f26282e756b2fb8a351193"
       +
       +
       +
       +info "building python."
       +tar xf "$CACHEDIR/Python-$PYTHON_VERSION.tar.xz" -C "$BUILDDIR"
       +(
       +    cd "$BUILDDIR/Python-$PYTHON_VERSION"
       +    export SOURCE_DATE_EPOCH=1530212462
       +    ./configure \
       +      --cache-file="$CACHEDIR/python.config.cache" \
       +      --prefix="$APPDIR/usr" \
       +      --enable-ipv6 \
       +      --enable-shared \
       +      --with-threads \
       +      -q
       +    make -s
       +    make -s install > /dev/null
       +)
       +
       +
       +info "building libsecp256k1."
       +(
       +    git clone https://github.com/bitcoin-core/secp256k1 "$CACHEDIR"/secp256k1 || (cd "$CACHEDIR"/secp256k1 && git pull)
       +    cd "$CACHEDIR"/secp256k1
       +    git reset --hard "$LIBSECP_VERSION"
       +    git clean -f -x -q
       +    export SOURCE_DATE_EPOCH=1530212462
       +    ./autogen.sh
       +    echo "LDFLAGS = -no-undefined" >> Makefile.am
       +    ./configure \
       +      --prefix="$APPDIR/usr" \
       +      --enable-module-recovery \
       +      --enable-experimental \
       +      --enable-module-ecdh \
       +      --disable-jni \
       +      -q
       +    make -s
       +    make -s install > /dev/null
       +)
       +
       +
       +appdir_python() {
       +  env \
       +    PYTHONNOUSERSITE=1 \
       +    LD_LIBRARY_PATH="$APPDIR/usr/lib:$APPDIR/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH+:$LD_LIBRARY_PATH}" \
       +    "$APPDIR/usr/bin/python3.6" "$@"
       +}
       +
       +python='appdir_python'
       +
       +
       +info "installing pip."
       +"$python" -m ensurepip
       +
       +
       +info "preparing electrum-locale."
       +(
       +    cd "$PROJECT_ROOT"
       +    git submodule update --init
       +
       +    pushd "$CONTRIB"/deterministic-build/electrum-locale
       +    if ! which msgfmt > /dev/null 2>&1; then
       +        echo "Please install gettext"
       +        exit 1
       +    fi
       +    for i in ./locale/*; do
       +        dir="$PROJECT_ROOT/electrum/$i/LC_MESSAGES"
       +        mkdir -p $dir
       +        msgfmt --output-file="$dir/electrum.mo" "$i/electrum.po" || true
       +    done
       +    popd
       +)
       +
       +
       +info "installing electrum and its dependencies."
       +mkdir -p "$CACHEDIR/pip_cache"
       +"$python" -m pip install --cache-dir "$CACHEDIR/pip_cache" -r "$CONTRIB/deterministic-build/requirements.txt"
       +"$python" -m pip install --cache-dir "$CACHEDIR/pip_cache" -r "$CONTRIB/deterministic-build/requirements-binaries.txt"
       +"$python" -m pip install --cache-dir "$CACHEDIR/pip_cache" -r "$CONTRIB/deterministic-build/requirements-hw.txt"
       +"$python" -m pip install --cache-dir "$CACHEDIR/pip_cache" "$PROJECT_ROOT"
       +
       +
       +info "copying zbar"
       +cp "/usr/lib/libzbar.so.0" "$APPDIR/usr/lib/libzbar.so.0"
       +
       +
       +info "desktop integration."
       +cp "$PROJECT_ROOT/electrum.desktop" "$APPDIR/electrum.desktop"
       +cp "$PROJECT_ROOT/icons/electrum.png" "$APPDIR/electrum.png"
       +
       +
       +# add launcher
       +cp "$CONTRIB/build-linux/appimage/apprun.sh" "$APPDIR/AppRun"
       +
       +info "finalizing AppDir."
       +(
       +    export PKG2AICOMMIT="$PKG2APPIMAGE_COMMIT"
       +    . "$CACHEDIR/functions.sh"
       +
       +    cd "$APPDIR"
       +    # copy system dependencies
       +    # note: temporarily move PyQt5 out of the way so
       +    # we don't try to bundle its system dependencies.
       +    mv "$APPDIR/usr/lib/python3.6/site-packages/PyQt5" "$BUILDDIR"
       +    copy_deps; copy_deps; copy_deps
       +    move_lib
       +    mv "$BUILDDIR/PyQt5" "$APPDIR/usr/lib/python3.6/site-packages"
       +
       +    # apply global appimage blacklist to exclude stuff
       +    # move usr/include out of the way to preserve usr/include/python3.6m.
       +    mv usr/include usr/include.tmp
       +    delete_blacklisted
       +    mv usr/include.tmp usr/include
       +)
       +
       +
       +info "stripping binaries from debug symbols."
       +strip_binaries()
       +{
       +  chmod u+w -R "$APPDIR"
       +  {
       +    printf '%s\0' "$APPDIR/usr/bin/python3.6"
       +    find "$APPDIR" -type f -regex '.*\.so\(\.[0-9.]+\)?$' -print0
       +  } | xargs -0 --no-run-if-empty --verbose -n1 strip
       +}
       +strip_binaries
       +
       +remove_emptydirs()
       +{
       +  find "$APPDIR" -type d -empty -print0 | xargs -0 --no-run-if-empty rmdir -vp --ignore-fail-on-non-empty
       +}
       +remove_emptydirs
       +
       +
       +info "removing some unneeded stuff to decrease binary size."
       +rm -rf "$APPDIR"/usr/lib/python3.6/test
       +rm -rf "$APPDIR"/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/translations/qtwebengine_locales
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/resources/qtwebengine_*
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/qml
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/lib/libQt5Web*
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/lib/libQt5Designer*
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/lib/libQt5Qml*
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/lib/libQt5Quick*
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/lib/libQt5Location*
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/lib/libQt5Test*
       +rm -rf "$APPDIR"/usr/lib/python3.6/site-packages/PyQt5/Qt/lib/libQt5Xml*
       +
       +
       +info "creating the AppImage."
       +(
       +    cd "$BUILDDIR"
       +    chmod +x "$CACHEDIR/appimagetool"
       +    "$CACHEDIR/appimagetool" --appimage-extract
       +    env VERSION="$VERSION" ./squashfs-root/AppRun --no-appstream --verbose "$APPDIR" "$APPIMAGE"
       +)
       +
       +
       +info "done."
       +ls -la "$DISTDIR"
       +sha256sum "$DISTDIR"/*
   DIR diff --git a/contrib/build-wine/prepare-wine.sh b/contrib/build-wine/prepare-wine.sh
       t@@ -24,62 +24,12 @@ PYHOME="c:/$PYTHON_FOLDER"
        PYTHON="wine $PYHOME/python.exe -OO -B"
        
        
       -# based on https://superuser.com/questions/497940/script-to-verify-a-signature-with-gpg
       -verify_signature() {
       -    local file=$1 keyring=$2 out=
       -    if out=$(gpg --no-default-keyring --keyring "$keyring" --status-fd 1 --verify "$file" 2>/dev/null) &&
       -       echo "$out" | grep -qs "^\[GNUPG:\] VALIDSIG "; then
       -        return 0
       -    else
       -        echo "$out" >&2
       -        exit 1
       -    fi
       -}
       -
       -verify_hash() {
       -    local file=$1 expected_hash=$2
       -    actual_hash=$(sha256sum $file | awk '{print $1}')
       -    if [ "$actual_hash" == "$expected_hash" ]; then
       -        return 0
       -    else
       -        echo "$file $actual_hash (unexpected hash)" >&2
       -        rm "$file"
       -        exit 1
       -    fi
       -}
       -
       -download_if_not_exist() {
       -    local file_name=$1 url=$2
       -    if [ ! -e $file_name ] ; then
       -        wget -O $PWD/$file_name "$url"
       -    fi
       -}
       -
       -# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
       -retry() {
       -  local result=0
       -  local count=1
       -  while [ $count -le 3 ]; do
       -    [ $result -ne 0 ] && {
       -      echo -e "\nThe command \"$@\" failed. Retrying, $count of 3.\n" >&2
       -    }
       -    ! { "$@"; result=$?; }
       -    [ $result -eq 0 ] && break
       -    count=$(($count + 1))
       -    sleep 1
       -  done
       -
       -  [ $count -gt 3 ] && {
       -    echo -e "\nThe command \"$@\" failed 3 times.\n" >&2
       -  }
       -
       -  return $result
       -}
       -
        # Let's begin!
       -here=$(dirname $(readlink -e $0))
       +here="$(dirname "$(readlink -e "$0")")"
        set -e
        
       +. $here/../build_tools_util.sh
       +
        wine 'wineboot'
        
        # HACK to work around https://bugs.winehq.org/show_bug.cgi?id=42474#c22
   DIR diff --git a/contrib/build_tools_util.sh b/contrib/build_tools_util.sh
       t@@ -0,0 +1,69 @@
       +#!/usr/bin/env bash
       +
       +RED='\033[0;31m'
       +BLUE='\033[0;34m'
       +YELLOW='\033[0;33m'
       +NC='\033[0m' # No Color
       +function info {
       +    printf "\r💬 ${BLUE}INFO:${NC}  ${1}\n"
       +}
       +function fail {
       +    printf "\r🗯 ${RED}ERROR:${NC} ${1}\n"
       +    exit 1
       +}
       +function warn {
       +    printf "\r⚠️  ${YELLOW}WARNING:${NC}  ${1}\n"
       +}
       +
       +
       +# based on https://superuser.com/questions/497940/script-to-verify-a-signature-with-gpg
       +function verify_signature() {
       +    local file=$1 keyring=$2 out=
       +    if out=$(gpg --no-default-keyring --keyring "$keyring" --status-fd 1 --verify "$file" 2>/dev/null) &&
       +       echo "$out" | grep -qs "^\[GNUPG:\] VALIDSIG "; then
       +        return 0
       +    else
       +        echo "$out" >&2
       +        exit 1
       +    fi
       +}
       +
       +function verify_hash() {
       +    local file=$1 expected_hash=$2
       +    actual_hash=$(sha256sum $file | awk '{print $1}')
       +    if [ "$actual_hash" == "$expected_hash" ]; then
       +        return 0
       +    else
       +        echo "$file $actual_hash (unexpected hash)" >&2
       +        rm "$file"
       +        exit 1
       +    fi
       +}
       +
       +function download_if_not_exist() {
       +    local file_name=$1 url=$2
       +    if [ ! -e $file_name ] ; then
       +        wget -O $file_name "$url"
       +    fi
       +}
       +
       +# https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/templates/header.sh
       +function retry() {
       +  local result=0
       +  local count=1
       +  while [ $count -le 3 ]; do
       +    [ $result -ne 0 ] && {
       +      echo -e "\nThe command \"$@\" failed. Retrying, $count of 3.\n" >&2
       +    }
       +    ! { "$@"; result=$?; }
       +    [ $result -eq 0 ] && break
       +    count=$(($count + 1))
       +    sleep 1
       +  done
       +
       +  [ $count -gt 3 ] && {
       +    echo -e "\nThe command \"$@\" failed 3 times.\n" >&2
       +  }
       +
       +  return $result
       +}
   DIR diff --git a/contrib/osx/base.sh b/contrib/osx/base.sh
       t@@ -1,19 +1,7 @@
        #!/usr/bin/env bash
        
       -RED='\033[0;31m'
       -BLUE='\033[0,34m'
       -YELLOW='\033[0;33m'
       -NC='\033[0m' # No Color
       -function info {
       -        printf "\r💬 ${BLUE}INFO:${NC}  ${1}\n"
       -}
       -function fail {
       -    printf "\r🗯 ${RED}ERROR:${NC} ${1}\n"
       -    exit 1
       -}
       -function warn {
       -        printf "\r⚠️  ${YELLOW}WARNING:${NC}  ${1}\n"
       -}
       +. $(dirname "$0")/../build_tools_util.sh
       +
        
        function DoCodeSignMaybe { # ARGS: infoName fileOrDirName codesignIdentity
            infoName="$1"