diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000000..cda801d9a879 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,93 @@ +name: "Build" + +on: + pull_request: + types: + - opened + - synchronize + +env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.OSX_BUILD_CERTIFICATE_BASE64 }} + P12_PASSWORD: ${{ secrets.OSX_P12_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.OSX_KEYCHAIN_PASSWORD }} + CODESIGN_CERT: ${{ secrets.OSX_CODESIGN_CERT }} + APPLE_ID_USER: ${{ secrets.OSX_APPLE_ID_USER }} + APPLE_ID_PASSWORD: ${{ secrets.OSX_APPLE_ID_PASSWORD }} + APPLE_ID_PROVIDER_SHORT_NAME: ${{ secrets.OSX_APPLE_ID_PROVIDER_SHORT_NAME }} + +jobs: + macos: + runs-on: macos-10.15 + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install the Apple certificate + run: | + set -e + # create variables + CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + + # import certificate and provisioning profile from secrets + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH + + # create temporary keychain + security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + security set-keychain-settings -lut 21600 $KEYCHAIN_PATH + security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + + # import certificate to keychain + security import $CERTIFICATE_PATH -P $P12_PASSWORD -A -t cert -f pkcs12 -k $KEYCHAIN_PATH + security list-keychain -d user -s $KEYCHAIN_PATH + - name: Build app + run: ./contrib/osx/make_osx $CODESIGN_CERT + - name: 'Upload Artifact' + uses: actions/upload-artifact@v2 + with: + name: artifact-macos + path: dist/*.dmg + + windows: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Builder image + env: + TARGET_OS: Windows + run: docker build --no-cache -t electrum-wine-builder-img ./contrib/build-wine/ + - name: Compile Windows binary + env: + TARGET_OS: Windows + run: docker run --name electrum-wine-builder-cont -v $PWD:/opt/wine64/drive_c/electrum --rm --workdir /opt/wine64/drive_c/electrum/contrib/build-wine electrum-wine-builder-img ./build.sh + - name: 'Upload Artifact' + uses: actions/upload-artifact@v2 + with: + name: artifact-windows + path: contrib/build-wine/dist/*.exe + if-no-files-found: error + retention-days: 7 + + appimage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + - name: Builder image + run: docker build --no-cache -t electrum-appimage-builder-img ./contrib/build-linux/appimage/ + - name: Compile Linux AppImage + run: 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 + - name: 'Upload Artifact' + uses: actions/upload-artifact@v2 + with: + name: artifact-appimage + path: dist/*.AppImage + if-no-files-found: error + retention-days: 7 diff --git a/.gitignore b/.gitignore index 8f0c77ef1dca..a9d62b38f7ad 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,20 @@ venv .DS_Store # Temporary bulds files +contrib/secp256k1 contrib/osx/libsecp256k1.0.dylib contrib/osx/libusb-1.0.dylib +electrum/libsecp256k1-0.dll +electrum/libsecp256k1.so.0 prebuilt_qr/ + +# generated locale's +contrib/deterministic-build/electrum-locale +electrum/es_ES +electrum/id_ID +electrum/ja_JP +electrum/ko_KR +electrum/pt_PT +electrum/tr_TR +electrum/vi_VN +electrum/zh_CN diff --git a/contrib/build-linux/appimage/Dockerfile b/contrib/build-linux/appimage/Dockerfile index 7003235a2694..f4afb1e9fd97 100644 --- a/contrib/build-linux/appimage/Dockerfile +++ b/contrib/build-linux/appimage/Dockerfile @@ -21,7 +21,7 @@ RUN apt-get update -q && \ libusb-1.0-0-dev=2:1.0.20-1 \ libudev-dev=229-4ubuntu21.31 \ gettext=0.19.7-2ubuntu3.1 \ - libzbar0=0.10+doc-10ubuntu1 \ + libzbar0=0.10+doc-10ubuntu1 \ libdbus-1-3=1.10.6-1ubuntu3.6 \ libxkbcommon-x11-0=0.5.0-1ubuntu2.1 \ libxcb-util1=0.4.0-0ubuntu3 \ diff --git a/contrib/build-wine/Dockerfile b/contrib/build-wine/Dockerfile index 60464e2cde4e..27e742c32da7 100644 --- a/contrib/build-wine/Dockerfile +++ b/contrib/build-wine/Dockerfile @@ -1,4 +1,3 @@ - FROM ubuntu:18.04@sha256:b58746c8a89938b8c9f5b77de3b8cf1fe78210c696ab03a1442e235eea65d84f ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 @@ -7,14 +6,14 @@ RUN dpkg --add-architecture i386 && \ apt-get update -q && \ apt-get install -qy \ wget=1.19.4-1ubuntu2.2 \ - gnupg2=2.2.4-1ubuntu1.4 \ - dirmngr=2.2.4-1ubuntu1.4 \ - python3-software-properties=0.96.24.32.1 \ - software-properties-common=0.96.24.32.1 + gnupg2=2.2.4-1ubuntu1.5 \ + dirmngr=2.2.4-1ubuntu1.5 \ + python3-software-properties=0.96.24.32.14 \ + software-properties-common=0.96.24.32.14 RUN apt-get update -q && \ apt-get install -qy \ - git=1:2.17.1-1ubuntu0.9 \ + git=1:2.17.1-1ubuntu0.11 \ p7zip-full=16.02+dfsg-6 \ make=4.1-9.1ubuntu1 \ mingw-w64=5.0.3-1 \ @@ -24,7 +23,7 @@ RUN apt-get update -q && \ autopoint=0.19.8.1-6ubuntu0.3 \ autoconf=2.69-11 \ libtool=2.4.6-2 \ - gettext=0.19.8.1-6 + gettext=0.19.8.1-6ubuntu0.3 RUN wget -nc https://dl.winehq.org/wine-builds/Release.key && \ echo "c51bcb8cc4a12abfbd7c7660eaf90f49674d15e222c262f27e6c96429111b822 Release.key" | sha256sum -c - && \ diff --git a/contrib/build-wine/build-electrum-git.sh b/contrib/build-wine/build-electrum-git.sh index e7ec10155752..fff7f9677149 100755 --- a/contrib/build-wine/build-electrum-git.sh +++ b/contrib/build-wine/build-electrum-git.sh @@ -11,6 +11,7 @@ export PYTHONHASHSEED=22 PYHOME=c:/python3 PYTHON="wine $PYHOME/python.exe -OO -B" +git config --global --add safe.directory $WINEPREFIX/drive_c/electrum # Let's begin! set -e @@ -60,7 +61,7 @@ rm -rf dist/ # build standalone and portable versions info "Running pyinstaller..." -wine "$PYHOME/scripts/pyinstaller.exe" --noconfirm --ascii --clean --name $NAME_ROOT-$VERSION -w deterministic.spec +wine "$PYHOME/scripts/pyinstaller.exe" --noconfirm --ascii --clean deterministic.spec # set timestamps in dist, in order to make the installer reproducible pushd dist diff --git a/contrib/build-wine/deterministic.spec b/contrib/build-wine/deterministic.spec index c4db5367fb30..176f772f7560 100644 --- a/contrib/build-wine/deterministic.spec +++ b/contrib/build-wine/deterministic.spec @@ -3,12 +3,9 @@ from PyInstaller.utils.hooks import collect_data_files, collect_submodules, collect_dynamic_libs import sys -for i, x in enumerate(sys.argv): - if x == '--name': - cmdline_name = sys.argv[i+1] - break -else: - raise Exception('no name') +for i, x in enumerate(sys.argv):import os + +cmdline_name = str(os.environ['NAME_ROOT']+"-"+os.environ['VERSION']) PYHOME = 'c:/python3' diff --git a/contrib/build-wine/prepare-wine.sh b/contrib/build-wine/prepare-wine.sh index ef8ea1fab540..1b1ce8e53600 100755 --- a/contrib/build-wine/prepare-wine.sh +++ b/contrib/build-wine/prepare-wine.sh @@ -123,6 +123,6 @@ info "Building PyInstaller." fi ) || fail "PyInstaller build failed" info "Installing PyInstaller." -$PYTHON -m pip install --no-dependencies --no-warn-script-location ./pyinstaller +$PYTHON -m pip install pyinstaller #--no-dependencies --no-warn-script-location ./pyinstaller info "Wine is configured." diff --git a/contrib/make_libusb.sh b/contrib/make_libusb.sh new file mode 100755 index 000000000000..20e3f27c375e --- /dev/null +++ b/contrib/make_libusb.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +LIBUSB_VERSION="c6a35c56016ea2ab2f19115d2ea1e85e0edae155" +# ^ tag v1.0.24 + +set -e + +. $(dirname "$0")/build_tools_util.sh || (echo "Could not source build_tools_util.sh" && exit 1) + +here=$(dirname $(realpath "$0" 2> /dev/null || grealpath "$0")) +CONTRIB="$here" +PROJECT_ROOT="$CONTRIB/.." + +pkgname="libusb" +info "Building $pkgname..." + +( + cd $CONTRIB + if [ ! -d libusb ]; then + git clone https://github.com/libusb/libusb.git + fi + cd libusb + if ! $(git cat-file -e ${LIBUSB_VERSION}) ; then + info "Could not find requested version $LIBUSB_VERSION in local clone; fetching..." + git fetch --all + fi + git reset --hard + git clean -dfxq + git checkout "${LIBUSB_VERSION}^{commit}" + + if [ "$BUILD_TYPE" = "wine" ] ; then + echo "libusb_1_0_la_LDFLAGS += -Wc,-static" >> libusb/Makefile.am + fi + ./bootstrap.sh || fail "Could not bootstrap libusb" + if ! [ -r config.status ] ; then + if [ "$BUILD_TYPE" = "wine" ] ; then + # windows target + LDFLAGS="-Wl,--no-insert-timestamp" + elif [ $(uname) == "Darwin" ]; then + # macos target + LDFLAGS="-Wl -lm" + else + # linux target + LDFLAGS="" + fi + LDFLAGS="$LDFLAGS" ./configure \ + $AUTOCONF_FLAGS \ + || fail "Could not configure $pkgname. Please make sure you have a C compiler installed and try again." + fi + make -j4 || fail "Could not build $pkgname" + make install || fail "Could not install $pkgname" + . "$here/$pkgname/libusb/.libs/libusb-1.0.la" + host_strip "$here/$pkgname/libusb/.libs/$dlname" + TARGET_NAME="$dlname" + if [ $(uname) == "Darwin" ]; then # on mac, dlname is "libusb-1.0.0.dylib" + TARGET_NAME="libusb-1.0.dylib" + fi + cp -fpv "$here/$pkgname/libusb/.libs/$dlname" "$PROJECT_ROOT/electrum/$TARGET_NAME" || fail "Could not copy the $pkgname binary to its destination" + info "$TARGET_NAME has been placed in the inner 'electrum' folder." + if [ -n "$DLL_TARGET_DIR" ] ; then + cp -fpv "$here/$pkgname/libusb/.libs/$dlname" "$DLL_TARGET_DIR/$TARGET_NAME" || fail "Could not copy the $pkgname binary to DLL_TARGET_DIR" + fi +) diff --git a/contrib/make_zbar.sh b/contrib/make_zbar.sh new file mode 100755 index 000000000000..de60c68abd6e --- /dev/null +++ b/contrib/make_zbar.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +# This script can be used on Linux hosts to build native libzbar binaries. +# sudo apt-get install pkg-config libx11-dev libx11-6 libv4l-dev libxv-dev libxext-dev libjpeg-dev +# +# It can also be used to cross-compile to Windows: +# $ sudo apt-get install mingw-w64 mingw-w64-tools win-iconv-mingw-w64-dev +# For a Windows x86 (32-bit) target, run: +# $ GCC_TRIPLET_HOST="i686-w64-mingw32" BUILD_TYPE="wine" ./contrib/make_zbar.sh +# Or for a Windows x86_64 (64-bit) target, run: +# $ GCC_TRIPLET_HOST="x86_64-w64-mingw32" BUILD_TYPE="wine" ./contrib/make_zbar.sh + +ZBAR_VERSION="aac86d5f08d64ab4c3da78188eb622fa3cb07182" + +set -e + +. $(dirname "$0")/build_tools_util.sh || (echo "Could not source build_tools_util.sh" && exit 1) + +here=$(dirname $(realpath "$0" 2> /dev/null || grealpath "$0")) +CONTRIB="$here" +PROJECT_ROOT="$CONTRIB/.." + +pkgname="zbar" +info "Building $pkgname..." + +( + cd $CONTRIB + if [ ! -d zbar ]; then + git clone https://github.com/mchehab/zbar.git + fi + cd zbar + if ! $(git cat-file -e ${ZBAR_VERSION}) ; then + info "Could not find requested version $ZBAR_VERSION in local clone; fetching..." + git fetch --all + fi + git reset --hard + git clean -dfxq + git checkout "${ZBAR_VERSION}^{commit}" + + if [ "$BUILD_TYPE" = "wine" ] ; then + echo "libzbar_la_LDFLAGS += -Wc,-static" >> zbar/Makefile.am + echo "LDFLAGS += -Wc,-static" >> Makefile.am + fi + if ! [ -x configure ] ; then + autoreconf -vfi || fail "Could not run autoreconf for $pkgname. Please make sure you have automake and libtool installed, and try again." + fi + if ! [ -r config.status ] ; then + if [ "$BUILD_TYPE" = "wine" ] ; then + # windows target + AUTOCONF_FLAGS="$AUTOCONF_FLAGS \ + --with-x=no \ + --enable-video=yes \ + --with-jpeg=no \ + --with-directshow=yes \ + --disable-dependency-tracking" + elif [ $(uname) == "Darwin" ]; then + # macos target + AUTOCONF_FLAGS="$AUTOCONF_FLAGS \ + --with-x=no \ + --enable-video=no \ + --with-jpeg=no" + else + # linux target + AUTOCONF_FLAGS="$AUTOCONF_FLAGS \ + --with-x=yes \ + --enable-video=yes \ + --with-jpeg=yes" + fi + ./configure \ + $AUTOCONF_FLAGS \ + --prefix="$here/$pkgname/dist" \ + --enable-pthread=no \ + --enable-doc=no \ + --with-python=no \ + --with-gtk=no \ + --with-qt=no \ + --with-java=no \ + --with-imagemagick=no \ + --with-dbus=no \ + --enable-codes=qrcode \ + --disable-static \ + --enable-shared || fail "Could not configure $pkgname. Please make sure you have a C compiler installed and try again." + fi + make -j4 || fail "Could not build $pkgname" + make install || fail "Could not install $pkgname" + . "$here/$pkgname/dist/lib/libzbar.la" + host_strip "$here/$pkgname/dist/lib/$dlname" + cp -fpv "$here/$pkgname/dist/lib/$dlname" "$PROJECT_ROOT/electrum" || fail "Could not copy the $pkgname binary to its destination" + info "$dlname has been placed in the inner 'electrum' folder." + if [ -n "$DLL_TARGET_DIR" ] ; then + cp -fpv "$here/$pkgname/dist/lib/$dlname" "$DLL_TARGET_DIR" || fail "Could not copy the $pkgname binary to DLL_TARGET_DIR" + fi +) diff --git a/contrib/osx/make_osx b/contrib/osx/make_osx index c193be963bb5..43f6e00d812a 100755 --- a/contrib/osx/make_osx +++ b/contrib/osx/make_osx @@ -14,6 +14,7 @@ export GCC_STRIP_BINARIES="1" CONTRIB_OSX="$(dirname "$(realpath "$0")")" CONTRIB="$CONTRIB_OSX/.." +PROJECT_ROOT="$CONTRIB/.." ROOT_FOLDER="$CONTRIB/.." src_dir=$(dirname "$0") @@ -114,18 +115,32 @@ info "generating locale" done ) || fail "failed generating locale" +info "Installing some build-time deps for compilation..." +brew install autoconf automake libtool gettext coreutils pkgconfig openssl -info "Downloading libusb..." -curl https://homebrew.bintray.com/bottles/libusb-1.0.23.high_sierra.bottle.tar.gz | \ -tar xz --directory "$BUILDDIR" -cp "$BUILDDIR/libusb/1.0.23/lib/libusb-1.0.dylib" contrib/osx -echo "caea266f3fc3982adc55d6cb8d9bad10f6e61f0c24ce5901aa1804618e08e14d contrib/osx/libusb-1.0.dylib" | \ - shasum -a 256 -c || fail "libusb checksum mismatched" +if [ ! -f "$PROJECT_ROOT"/electrum/libsecp256k1.0.dylib ]; then + info "Building libsecp256k1 dylib..." + "$CONTRIB"/make_libsecp256k1.sh || fail "Could not build libsecp" +else + info "Skipping libsecp256k1 build: reusing already built dylib." +fi +cp "$PROJECT_ROOT"/electrum/libsecp256k1.0.dylib "$CONTRIB"/osx -info "Preparing for building libsecp256k1" -brew install autoconf automake libtool -"$CONTRIB"/make_libsecp256k1.sh || fail "Could not build libsecp" -cp "$ROOT_FOLDER"/electrum/libsecp256k1.0.dylib contrib/osx +if [ ! -f "$PROJECT_ROOT"/electrum/libzbar.0.dylib ]; then + info "Building ZBar dylib..." + "$CONTRIB"/make_zbar.sh || fail "Could not build ZBar dylib" +else + info "Skipping ZBar build: reusing already built dylib." +fi +cp "$PROJECT_ROOT"/electrum/libzbar.0.dylib "$CONTRIB"/osx + +if [ ! -f "$PROJECT_ROOT"/electrum/libusb-1.0.dylib ]; then + info "Building libusb dylib..." + "$CONTRIB"/make_libusb.sh || fail "Could not build libusb dylib" +else + info "Skipping libusb build: reusing already built dylib." +fi +cp "$PROJECT_ROOT"/electrum/libusb-1.0.dylib "$CONTRIB"/osx info "Building CalinsQRReader..." d=contrib/osx/CalinsQRReader