URI: 
       tbuild.sh - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
       tbuild.sh (10330B)
       ---
            1 #!/bin/bash
            2 
            3 set -e
            4 
            5 PROJECT_ROOT="$(dirname "$(readlink -e "$0")")/../../.."
            6 CONTRIB="$PROJECT_ROOT/contrib"
            7 CONTRIB_APPIMAGE="$CONTRIB/build-linux/appimage"
            8 DISTDIR="$PROJECT_ROOT/dist"
            9 BUILDDIR="$CONTRIB_APPIMAGE/build/appimage"
           10 APPDIR="$BUILDDIR/electrum.AppDir"
           11 CACHEDIR="$CONTRIB_APPIMAGE/.cache/appimage"
           12 PIP_CACHE_DIR="$CACHEDIR/pip_cache"
           13 
           14 export GCC_STRIP_BINARIES="1"
           15 
           16 # pinned versions
           17 # note: compiling python 3.8.x requires at least glibc 2.27,
           18 #       which is first available on ubuntu 18.04
           19 PYTHON_VERSION=3.7.9
           20 PKG2APPIMAGE_COMMIT="eb8f3acdd9f11ab19b78f5cb15daa772367daf15"
           21 SQUASHFSKIT_COMMIT="ae0d656efa2d0df2fcac795b6823b44462f19386"
           22 
           23 
           24 VERSION=`git describe --tags --dirty --always`
           25 APPIMAGE="$DISTDIR/electrum-$VERSION-x86_64.AppImage"
           26 
           27 . "$CONTRIB"/build_tools_util.sh
           28 
           29 rm -rf "$BUILDDIR"
           30 mkdir -p "$APPDIR" "$CACHEDIR" "$PIP_CACHE_DIR" "$DISTDIR"
           31 
           32 # potential leftover from setuptools that might make pip put garbage in binary
           33 rm -rf "$PROJECT_ROOT/build"
           34 
           35 
           36 info "downloading some dependencies."
           37 download_if_not_exist "$CACHEDIR/functions.sh" "https://raw.githubusercontent.com/AppImage/pkg2appimage/$PKG2APPIMAGE_COMMIT/functions.sh"
           38 verify_hash "$CACHEDIR/functions.sh" "78b7ee5a04ffb84ee1c93f0cb2900123773bc6709e5d1e43c37519f590f86918"
           39 
           40 download_if_not_exist "$CACHEDIR/appimagetool" "https://github.com/AppImage/AppImageKit/releases/download/12/appimagetool-x86_64.AppImage"
           41 verify_hash "$CACHEDIR/appimagetool" "d918b4df547b388ef253f3c9e7f6529ca81a885395c31f619d9aaf7030499a13"
           42 
           43 download_if_not_exist "$CACHEDIR/Python-$PYTHON_VERSION.tar.xz" "https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tar.xz"
           44 verify_hash "$CACHEDIR/Python-$PYTHON_VERSION.tar.xz" "91923007b05005b5f9bd46f3b9172248aea5abc1543e8a636d59e629c3331b01"
           45 
           46 
           47 
           48 info "building python."
           49 tar xf "$CACHEDIR/Python-$PYTHON_VERSION.tar.xz" -C "$BUILDDIR"
           50 (
           51     cd "$BUILDDIR/Python-$PYTHON_VERSION"
           52     LC_ALL=C export BUILD_DATE=$(date -u -d "@$SOURCE_DATE_EPOCH" "+%b %d %Y")
           53     LC_ALL=C export BUILD_TIME=$(date -u -d "@$SOURCE_DATE_EPOCH" "+%H:%M:%S")
           54     # Patch taken from Ubuntu http://archive.ubuntu.com/ubuntu/pool/main/p/python3.7/python3.7_3.7.6-1.debian.tar.xz
           55     patch -p1 < "$CONTRIB_APPIMAGE/patches/python-3.7-reproducible-buildinfo.diff"
           56     ./configure \
           57       --cache-file="$CACHEDIR/python.config.cache" \
           58       --prefix="$APPDIR/usr" \
           59       --enable-ipv6 \
           60       --enable-shared \
           61       -q
           62     make -j4 -s || fail "Could not build Python"
           63     make -s install > /dev/null || fail "Could not install Python"
           64     # When building in docker on macOS, python builds with .exe extension because the
           65     # case insensitive file system of macOS leaks into docker. This causes the build
           66     # to result in a different output on macOS compared to Linux. We simply patch
           67     # sysconfigdata to remove the extension.
           68     # Some more info: https://bugs.python.org/issue27631
           69     sed -i -e 's/\.exe//g' "$APPDIR"/usr/lib/python3.7/_sysconfigdata*
           70 )
           71 
           72 
           73 info "Building squashfskit"
           74 git clone "https://github.com/squashfskit/squashfskit.git" "$BUILDDIR/squashfskit"
           75 (
           76     cd "$BUILDDIR/squashfskit"
           77     git checkout "${SQUASHFSKIT_COMMIT}^{commit}"
           78     make -C squashfs-tools mksquashfs || fail "Could not build squashfskit"
           79 )
           80 MKSQUASHFS="$BUILDDIR/squashfskit/squashfs-tools/mksquashfs"
           81 
           82 
           83 "$CONTRIB"/make_libsecp256k1.sh || fail "Could not build libsecp"
           84 cp -f "$PROJECT_ROOT/electrum/libsecp256k1.so.0" "$APPDIR/usr/lib/libsecp256k1.so.0" || fail "Could not copy libsecp to its destination"
           85 
           86 
           87 appdir_python() {
           88   env \
           89     PYTHONNOUSERSITE=1 \
           90     LD_LIBRARY_PATH="$APPDIR/usr/lib:$APPDIR/usr/lib/x86_64-linux-gnu${LD_LIBRARY_PATH+:$LD_LIBRARY_PATH}" \
           91     "$APPDIR/usr/bin/python3.7" "$@"
           92 }
           93 
           94 python='appdir_python'
           95 
           96 
           97 info "installing pip."
           98 "$python" -m ensurepip
           99 
          100 break_legacy_easy_install
          101 
          102 
          103 info "preparing electrum-locale."
          104 (
          105     cd "$PROJECT_ROOT"
          106     git submodule update --init
          107 
          108     pushd "$CONTRIB"/deterministic-build/electrum-locale
          109     if ! which msgfmt > /dev/null 2>&1; then
          110         fail "Please install gettext"
          111     fi
          112     for i in ./locale/*; do
          113         dir="$PROJECT_ROOT/electrum/$i/LC_MESSAGES"
          114         mkdir -p $dir
          115         msgfmt --output-file="$dir/electrum.mo" "$i/electrum.po" || true
          116     done
          117     popd
          118 )
          119 
          120 
          121 info "Installing build dependencies."
          122 "$python" -m pip install --no-dependencies --no-binary :all: --no-warn-script-location \
          123     --cache-dir "$PIP_CACHE_DIR" -r "$CONTRIB/deterministic-build/requirements-build-appimage.txt"
          124 
          125 info "installing electrum and its dependencies."
          126 # note: we prefer compiling C extensions ourselves, instead of using binary wheels,
          127 #       hence "--no-binary :all:" flags. However, we specifically allow
          128 #       - PyQt5, as it's harder to build from source
          129 #       - cryptography, as building it would need openssl 1.1, not available on ubuntu 16.04
          130 "$python" -m pip install --no-dependencies --no-binary :all: --no-warn-script-location \
          131     --cache-dir "$PIP_CACHE_DIR" -r "$CONTRIB/deterministic-build/requirements.txt"
          132 "$python" -m pip install --no-dependencies --no-binary :all: --only-binary pyqt5,cryptography --no-warn-script-location \
          133     --cache-dir "$PIP_CACHE_DIR" -r "$CONTRIB/deterministic-build/requirements-binaries.txt"
          134 "$python" -m pip install --no-dependencies --no-binary :all: --no-warn-script-location \
          135     --cache-dir "$PIP_CACHE_DIR" -r "$CONTRIB/deterministic-build/requirements-hw.txt"
          136 
          137 "$python" -m pip install --no-dependencies --no-warn-script-location \
          138     --cache-dir "$PIP_CACHE_DIR" "$PROJECT_ROOT"
          139 
          140 # was only needed during build time, not runtime
          141 "$python" -m pip uninstall -y Cython
          142 
          143 
          144 info "copying zbar"
          145 cp "/usr/lib/x86_64-linux-gnu/libzbar.so.0" "$APPDIR/usr/lib/libzbar.so.0"
          146 
          147 
          148 info "desktop integration."
          149 cp "$PROJECT_ROOT/electrum.desktop" "$APPDIR/electrum.desktop"
          150 cp "$PROJECT_ROOT/electrum/gui/icons/electrum.png" "$APPDIR/electrum.png"
          151 
          152 
          153 # add launcher
          154 cp "$CONTRIB_APPIMAGE/apprun.sh" "$APPDIR/AppRun"
          155 
          156 info "finalizing AppDir."
          157 (
          158     export PKG2AICOMMIT="$PKG2APPIMAGE_COMMIT"
          159     . "$CACHEDIR/functions.sh"
          160 
          161     cd "$APPDIR"
          162     # copy system dependencies
          163     copy_deps; copy_deps; copy_deps
          164     move_lib
          165 
          166     # apply global appimage blacklist to exclude stuff
          167     # move usr/include out of the way to preserve usr/include/python3.7m.
          168     mv usr/include usr/include.tmp
          169     delete_blacklisted
          170     mv usr/include.tmp usr/include
          171 ) || fail "Could not finalize AppDir"
          172 
          173 info "Copying additional libraries"
          174 (
          175     # On some systems it can cause problems to use the system libusb (on AppImage excludelist)
          176     cp -f /usr/lib/x86_64-linux-gnu/libusb-1.0.so "$APPDIR/usr/lib/libusb-1.0.so" || fail "Could not copy libusb"
          177     # some distros lack libxkbcommon-x11
          178     cp -f /usr/lib/x86_64-linux-gnu/libxkbcommon-x11.so.0 "$APPDIR"/usr/lib/x86_64-linux-gnu || fail "Could not copy libxkbcommon-x11"
          179 )
          180 
          181 info "stripping binaries from debug symbols."
          182 # "-R .note.gnu.build-id" also strips the build id
          183 # "-R .comment" also strips the GCC version information
          184 strip_binaries()
          185 {
          186   chmod u+w -R "$APPDIR"
          187   {
          188     printf '%s\0' "$APPDIR/usr/bin/python3.7"
          189     find "$APPDIR" -type f -regex '.*\.so\(\.[0-9.]+\)?$' -print0
          190   } | xargs -0 --no-run-if-empty --verbose strip -R .note.gnu.build-id -R .comment
          191 }
          192 strip_binaries
          193 
          194 remove_emptydirs()
          195 {
          196   find "$APPDIR" -type d -empty -print0 | xargs -0 --no-run-if-empty rmdir -vp --ignore-fail-on-non-empty
          197 }
          198 remove_emptydirs
          199 
          200 
          201 info "removing some unneeded stuff to decrease binary size."
          202 rm -rf "$APPDIR"/usr/{share,include}
          203 PYDIR="$APPDIR"/usr/lib/python3.7
          204 rm -rf "$PYDIR"/{test,ensurepip,lib2to3,idlelib,turtledemo}
          205 rm -rf "$PYDIR"/{ctypes,sqlite3,tkinter,unittest}/test
          206 rm -rf "$PYDIR"/distutils/{command,tests}
          207 rm -rf "$PYDIR"/config-3.7m-x86_64-linux-gnu
          208 rm -rf "$PYDIR"/site-packages/{opt,pip,setuptools,wheel}
          209 rm -rf "$PYDIR"/site-packages/Cryptodome/SelfTest
          210 rm -rf "$PYDIR"/site-packages/{psutil,qrcode,websocket}/tests
          211 for component in connectivity declarative help location multimedia quickcontrols2 serialport webengine websockets xmlpatterns ; do
          212   rm -rf "$PYDIR"/site-packages/PyQt5/Qt/translations/qt${component}_*
          213   rm -rf "$PYDIR"/site-packages/PyQt5/Qt/resources/qt${component}_*
          214 done
          215 rm -rf "$PYDIR"/site-packages/PyQt5/Qt/{qml,libexec}
          216 rm -rf "$PYDIR"/site-packages/PyQt5/{pyrcc.so,pylupdate.so,uic}
          217 rm -rf "$PYDIR"/site-packages/PyQt5/Qt/plugins/{bearer,gamepads,geometryloaders,geoservices,playlistformats,position,renderplugins,sceneparsers,sensors,sqldrivers,texttospeech,webview}
          218 for component in Bluetooth Concurrent Designer Help Location NetworkAuth Nfc Positioning PositioningQuick Qml Quick Sensors SerialPort Sql Test Web Xml ; do
          219     rm -rf "$PYDIR"/site-packages/PyQt5/Qt/lib/libQt5${component}*
          220     rm -rf "$PYDIR"/site-packages/PyQt5/Qt${component}*
          221 done
          222 rm -rf "$PYDIR"/site-packages/PyQt5/Qt.so
          223 
          224 # these are deleted as they were not deterministic; and are not needed anyway
          225 find "$APPDIR" -path '*/__pycache__*' -delete
          226 # note that *.dist-info is needed by certain packages.
          227 # e.g. see https://gitlab.com/python-devs/importlib_metadata/issues/71
          228 for f in "$PYDIR"/site-packages/importlib_metadata-*.dist-info; do mv "$f" "$(echo "$f" | sed s/\.dist-info/\.dist-info2/)"; done
          229 rm -rf "$PYDIR"/site-packages/*.dist-info/
          230 rm -rf "$PYDIR"/site-packages/*.egg-info/
          231 for f in "$PYDIR"/site-packages/importlib_metadata-*.dist-info2; do mv "$f" "$(echo "$f" | sed s/\.dist-info2/\.dist-info/)"; done
          232 
          233 
          234 find -exec touch -h -d '2000-11-11T11:11:11+00:00' {} +
          235 
          236 
          237 info "creating the AppImage."
          238 (
          239     cd "$BUILDDIR"
          240     cp "$CACHEDIR/appimagetool" "$CACHEDIR/appimagetool_copy"
          241     # zero out "appimage" magic bytes, as on some systems they confuse the linker
          242     sed -i 's|AI\x02|\x00\x00\x00|' "$CACHEDIR/appimagetool_copy"
          243     chmod +x "$CACHEDIR/appimagetool_copy"
          244     "$CACHEDIR/appimagetool_copy" --appimage-extract
          245     # We build a small wrapper for mksquashfs that removes the -mkfs-fixed-time option
          246     # that mksquashfs from squashfskit does not support. It is not needed for squashfskit.
          247     cat > ./squashfs-root/usr/lib/appimagekit/mksquashfs << EOF
          248 #!/bin/sh
          249 args=\$(echo "\$@" | sed -e 's/-mkfs-fixed-time 0//')
          250 "$MKSQUASHFS" \$args
          251 EOF
          252     env VERSION="$VERSION" ARCH=x86_64 SOURCE_DATE_EPOCH=1530212462 ./squashfs-root/AppRun --no-appstream --verbose "$APPDIR" "$APPIMAGE"
          253 )
          254 
          255 
          256 info "done."
          257 ls -la "$DISTDIR"
          258 sha256sum "$DISTDIR"/*