prepare-wine.sh (5608B)
1 #!/bin/bash 2 3 # Please update these carefully, some versions won't work under Wine 4 NSIS_FILENAME=nsis-3.05-setup.exe 5 NSIS_URL=https://downloads.sourceforge.net/project/nsis/NSIS%203/3.05/$NSIS_FILENAME 6 NSIS_SHA256=1a3cc9401667547b9b9327a177b13485f7c59c2303d4b6183e7bc9e6c8d6bfdb 7 8 LIBUSB_REPO="https://github.com/libusb/libusb.git" 9 LIBUSB_COMMIT="c6a35c56016ea2ab2f19115d2ea1e85e0edae155" 10 # ^ tag v1.0.24 11 12 PYINSTALLER_REPO="https://github.com/SomberNight/pyinstaller.git" 13 PYINSTALLER_COMMIT="80ee4d613ecf75a1226b960a560ee01459e65ddb" 14 # ^ tag 4.2, plus a custom commit that fixes cross-compilation with MinGW 15 16 PYTHON_VERSION=3.8.7 17 18 19 # Let's begin! 20 set -e 21 22 here="$(dirname "$(readlink -e "$0")")" 23 24 . "$CONTRIB"/build_tools_util.sh 25 26 info "Booting wine." 27 wine 'wineboot' 28 29 30 cd "$CACHEDIR" 31 mkdir -p $WINEPREFIX/drive_c/tmp 32 33 info "Installing Python." 34 # note: you might need "sudo apt-get install dirmngr" for the following 35 # keys from https://www.python.org/downloads/#pubkeys 36 KEYRING_PYTHON_DEV="keyring-electrum-build-python-dev.gpg" 37 gpg --no-default-keyring --keyring $KEYRING_PYTHON_DEV --import "$here"/gpg_keys/7ED10B6531D7C8E1BC296021FC624643487034E5.asc 38 if [ "$WIN_ARCH" = "win32" ] ; then 39 PYARCH="win32" 40 elif [ "$WIN_ARCH" = "win64" ] ; then 41 PYARCH="amd64" 42 else 43 fail "unexpected WIN_ARCH: $WIN_ARCH" 44 fi 45 PYTHON_DOWNLOADS="$CACHEDIR/python$PYTHON_VERSION" 46 mkdir -p "$PYTHON_DOWNLOADS" 47 for msifile in core dev exe lib pip tools; do 48 echo "Installing $msifile..." 49 download_if_not_exist "$PYTHON_DOWNLOADS/${msifile}.msi" "https://www.python.org/ftp/python/$PYTHON_VERSION/$PYARCH/${msifile}.msi" 50 download_if_not_exist "$PYTHON_DOWNLOADS/${msifile}.msi.asc" "https://www.python.org/ftp/python/$PYTHON_VERSION/$PYARCH/${msifile}.msi.asc" 51 verify_signature "$PYTHON_DOWNLOADS/${msifile}.msi.asc" $KEYRING_PYTHON_DEV 52 wine msiexec /i "$PYTHON_DOWNLOADS/${msifile}.msi" /qb TARGETDIR=$WINE_PYHOME 53 done 54 55 break_legacy_easy_install 56 57 info "Installing build dependencies." 58 $WINE_PYTHON -m pip install --no-dependencies --no-warn-script-location \ 59 --cache-dir "$WINE_PIP_CACHE_DIR" -r "$CONTRIB"/deterministic-build/requirements-build-wine.txt 60 61 info "Installing NSIS." 62 download_if_not_exist "$CACHEDIR/$NSIS_FILENAME" "$NSIS_URL" 63 verify_hash "$CACHEDIR/$NSIS_FILENAME" "$NSIS_SHA256" 64 wine "$CACHEDIR/$NSIS_FILENAME" /S 65 66 67 info "Compiling libusb..." 68 ( 69 cd "$CACHEDIR" 70 if [ -f "libusb/libusb/.libs/libusb-1.0.dll" ]; then 71 info "libusb-1.0.dll already built, skipping" 72 exit 0 73 fi 74 rm -rf libusb 75 mkdir libusb 76 cd libusb 77 # Shallow clone 78 git init 79 git remote add origin $LIBUSB_REPO 80 git fetch --depth 1 origin $LIBUSB_COMMIT 81 git checkout -b pinned "${LIBUSB_COMMIT}^{commit}" 82 echo "libusb_1_0_la_LDFLAGS += -Wc,-static" >> libusb/Makefile.am 83 ./bootstrap.sh || fail "Could not bootstrap libusb" 84 host="$GCC_TRIPLET_HOST" 85 LDFLAGS="-Wl,--no-insert-timestamp" ./configure \ 86 --host=$host \ 87 --build=$GCC_TRIPLET_BUILD || fail "Could not run ./configure for libusb" 88 make -j4 || fail "Could not build libusb" 89 ${host}-strip libusb/.libs/libusb-1.0.dll 90 ) || fail "libusb build failed" 91 cp "$CACHEDIR/libusb/libusb/.libs/libusb-1.0.dll" $WINEPREFIX/drive_c/tmp/ || fail "Could not copy libusb to its destination" 92 93 94 # copy already built DLLs 95 cp "$DLL_TARGET_DIR/libsecp256k1-0.dll" $WINEPREFIX/drive_c/tmp/ || fail "Could not copy libsecp to its destination" 96 cp "$DLL_TARGET_DIR/libzbar-0.dll" $WINEPREFIX/drive_c/tmp/ || fail "Could not copy libzbar to its destination" 97 98 99 info "Building PyInstaller." 100 # we build our own PyInstaller boot loader as the default one has high 101 # anti-virus false positives 102 ( 103 if [ "$WIN_ARCH" = "win32" ] ; then 104 PYINST_ARCH="32bit" 105 elif [ "$WIN_ARCH" = "win64" ] ; then 106 PYINST_ARCH="64bit" 107 else 108 fail "unexpected WIN_ARCH: $WIN_ARCH" 109 fi 110 if [ -f "$CACHEDIR/pyinstaller/PyInstaller/bootloader/Windows-$PYINST_ARCH/runw.exe" ]; then 111 info "pyinstaller already built, skipping" 112 exit 0 113 fi 114 cd "$WINEPREFIX/drive_c/electrum" 115 ELECTRUM_COMMIT_HASH=$(git rev-parse HEAD) 116 cd "$CACHEDIR" 117 rm -rf pyinstaller 118 mkdir pyinstaller 119 cd pyinstaller 120 # Shallow clone 121 git init 122 git remote add origin $PYINSTALLER_REPO 123 git fetch --depth 1 origin $PYINSTALLER_COMMIT 124 git checkout -b pinned "${PYINSTALLER_COMMIT}^{commit}" 125 rm -fv PyInstaller/bootloader/Windows-*/run*.exe || true 126 # add reproducible randomness. this ensures we build a different bootloader for each commit. 127 # if we built the same one for all releases, that might also get anti-virus false positives 128 echo "const char *electrum_tag = \"tagged by Electrum@$ELECTRUM_COMMIT_HASH\";" >> ./bootloader/src/pyi_main.c 129 pushd bootloader 130 # cross-compile to Windows using host python 131 python3 ./waf all CC="${GCC_TRIPLET_HOST}-gcc" \ 132 CFLAGS="-static \ 133 -Wno-dangling-else \ 134 -Wno-error=unused-value \ 135 -Wno-error=implicit-function-declaration \ 136 -Wno-error=int-to-pointer-cast \ 137 -Wno-error=stringop-truncation" 138 popd 139 # sanity check bootloader is there: 140 [[ -e "PyInstaller/bootloader/Windows-$PYINST_ARCH/runw.exe" ]] || fail "Could not find runw.exe in target dir!" 141 ) || fail "PyInstaller build failed" 142 info "Installing PyInstaller." 143 $WINE_PYTHON -m pip install --no-dependencies --no-warn-script-location ./pyinstaller 144 145 info "Wine is configured."