make_osx (6774B)
1 #!/usr/bin/env bash 2 3 # Parameterize 4 PYTHON_VERSION=3.7.9 5 BUILDDIR=/tmp/electrum-build 6 PACKAGE=Electrum 7 GIT_REPO=https://github.com/spesmilo/electrum 8 9 export GCC_STRIP_BINARIES="1" 10 11 12 . $(dirname "$0")/../build_tools_util.sh 13 14 15 CONTRIB_OSX="$(dirname "$(realpath "$0")")" 16 CONTRIB="$CONTRIB_OSX/.." 17 ROOT_FOLDER="$CONTRIB/.." 18 19 src_dir=$(dirname "$0") 20 cd $src_dir/../.. 21 22 23 which brew > /dev/null 2>&1 || fail "Please install brew from https://brew.sh/ to continue" 24 which xcodebuild > /dev/null 2>&1 || fail "Please install Xcode and xcode command line tools to continue" 25 26 # Code Signing: See https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html 27 if [ -n "$CODESIGN_CERT" ]; then 28 # Test the identity is valid for signing by doing this hack. There is no other way to do this. 29 cp -f /bin/ls ./CODESIGN_TEST 30 codesign -s "$CODESIGN_CERT" --dryrun -f ./CODESIGN_TEST > /dev/null 2>&1 31 res=$? 32 rm -f ./CODESIGN_TEST 33 if ((res)); then 34 fail "Code signing identity \"$CODESIGN_CERT\" appears to be invalid." 35 fi 36 unset res 37 info "Code signing enabled using identity \"$CODESIGN_CERT\"" 38 else 39 warn "Code signing DISABLED. Specify a valid macOS Developer identity installed on the system to enable signing." 40 fi 41 42 43 function DoCodeSignMaybe { # ARGS: infoName fileOrDirName 44 infoName="$1" 45 file="$2" 46 deep="" 47 if [ -z "$CODESIGN_CERT" ]; then 48 # no cert -> we won't codesign 49 return 50 fi 51 if [ -d "$file" ]; then 52 deep="--deep" 53 fi 54 if [ -z "$infoName" ] || [ -z "$file" ] || [ ! -e "$file" ]; then 55 fail "Argument error to internal function DoCodeSignMaybe()" 56 fi 57 hardened_arg="--entitlements=${CONTRIB_OSX}/entitlements.plist -o runtime" 58 59 info "Code signing ${infoName}..." 60 codesign -f -v $deep -s "$CODESIGN_CERT" $hardened_arg "$file" || fail "Could not code sign ${infoName}" 61 } 62 63 64 info "Installing Python $PYTHON_VERSION" 65 export PATH="~/.pyenv/bin:~/.pyenv/shims:~/Library/Python/3.7/bin:$PATH" 66 if [ -d "${HOME}/.pyenv" ]; then 67 pyenv update 68 else 69 curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash > /dev/null 2>&1 70 fi 71 PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install -s $PYTHON_VERSION && \ 72 pyenv global $PYTHON_VERSION || \ 73 fail "Unable to use Python $PYTHON_VERSION" 74 75 break_legacy_easy_install 76 77 # create a fresh virtualenv 78 # This helps to avoid older versions of pip-installed dependencies interfering with the build. 79 VENV_DIR="$CONTRIB_OSX/build-venv" 80 rm -rf "$VENV_DIR" 81 python3 -m venv $VENV_DIR 82 source $VENV_DIR/bin/activate 83 84 info "Installing build dependencies" 85 python3 -m pip install --no-dependencies --no-warn-script-location -Ir ./contrib/deterministic-build/requirements-build-mac.txt \ 86 || fail "Could not install build dependencies" 87 88 info "Using these versions for building $PACKAGE:" 89 sw_vers 90 python3 --version 91 echo -n "Pyinstaller " 92 pyinstaller --version 93 94 rm -rf ./dist 95 96 git submodule update --init 97 98 rm -rf $BUILDDIR > /dev/null 2>&1 99 mkdir $BUILDDIR 100 101 info "generating locale" 102 ( 103 if ! which msgfmt > /dev/null 2>&1; then 104 brew install gettext 105 brew link --force gettext 106 fi 107 cd "$CONTRIB"/deterministic-build/electrum-locale 108 for i in ./locale/*; do 109 dir="$ROOT_FOLDER"/electrum/$i/LC_MESSAGES 110 mkdir -p $dir 111 msgfmt --output-file=$dir/electrum.mo $i/electrum.po || true 112 done 113 ) || fail "failed generating locale" 114 115 116 info "Downloading libusb..." 117 curl https://homebrew.bintray.com/bottles/libusb-1.0.23.high_sierra.bottle.tar.gz | \ 118 tar xz --directory $BUILDDIR 119 cp $BUILDDIR/libusb/1.0.23/lib/libusb-1.0.dylib contrib/osx 120 echo "caea266f3fc3982adc55d6cb8d9bad10f6e61f0c24ce5901aa1804618e08e14d contrib/osx/libusb-1.0.dylib" | \ 121 shasum -a 256 -c || fail "libusb checksum mismatched" 122 123 info "Preparing for building libsecp256k1" 124 brew install autoconf automake libtool 125 "$CONTRIB"/make_libsecp256k1.sh || fail "Could not build libsecp" 126 cp "$ROOT_FOLDER"/electrum/libsecp256k1.0.dylib contrib/osx 127 128 info "Building CalinsQRReader..." 129 d=contrib/osx/CalinsQRReader 130 pushd $d 131 rm -fr build 132 # prefer building using xcode ourselves. otherwise fallback to prebuilt binary 133 xcodebuild || cp -r prebuilt_qr build || fail "Could not build CalinsQRReader" 134 popd 135 DoCodeSignMaybe "CalinsQRReader.app" "${d}/build/Release/CalinsQRReader.app" 136 137 138 info "Installing requirements..." 139 python3 -m pip install --no-dependencies --no-warn-script-location -Ir ./contrib/deterministic-build/requirements.txt \ 140 || fail "Could not install requirements" 141 142 info "Installing hardware wallet requirements..." 143 python3 -m pip install --no-dependencies --no-warn-script-location -Ir ./contrib/deterministic-build/requirements-hw.txt \ 144 || fail "Could not install hardware wallet requirements" 145 146 info "Installing dependencies specific to binaries..." 147 python3 -m pip install --no-dependencies --no-warn-script-location -Ir ./contrib/deterministic-build/requirements-binaries-mac.txt \ 148 || fail "Could not install dependencies specific to binaries" 149 150 info "Building $PACKAGE..." 151 python3 -m pip install --no-dependencies --no-warn-script-location . > /dev/null || fail "Could not build $PACKAGE" 152 153 info "Faking timestamps..." 154 for d in ~/Library/Python/ ~/.pyenv .; do 155 pushd $d 156 find . -exec touch -t '200101220000' {} + 157 popd 158 done 159 160 VERSION=`git describe --tags --dirty --always` 161 162 info "Building binary" 163 APP_SIGN="$CODESIGN_CERT" pyinstaller --noconfirm --ascii --clean --name $VERSION contrib/osx/osx.spec || fail "Could not build binary" 164 165 info "Adding bitcoin URI types to Info.plist" 166 plutil -insert 'CFBundleURLTypes' \ 167 -xml '<array><dict> <key>CFBundleURLName</key> <string>bitcoin</string> <key>CFBundleURLSchemes</key> <array><string>bitcoin</string></array> </dict></array>' \ 168 -- dist/$PACKAGE.app/Contents/Info.plist \ 169 || fail "Could not add keys to Info.plist. Make sure the program 'plutil' exists and is installed." 170 171 DoCodeSignMaybe "app bundle" "dist/${PACKAGE}.app" 172 173 if [ ! -z "$CODESIGN_CERT" ]; then 174 if [ ! -z "$APPLE_ID_USER" ]; then 175 info "Notarizing .app with Apple's central server..." 176 "${CONTRIB_OSX}/notarize_app.sh" "dist/${PACKAGE}.app" || fail "Could not notarize binary." 177 else 178 warn "AppleID details not set! Skipping Apple notarization." 179 fi 180 fi 181 182 info "Creating .DMG" 183 hdiutil create -fs HFS+ -volname $PACKAGE -srcfolder dist/$PACKAGE.app dist/electrum-$VERSION.dmg || fail "Could not create .DMG" 184 185 DoCodeSignMaybe ".DMG" "dist/electrum-${VERSION}.dmg" 186 187 if [ -z "$CODESIGN_CERT" ]; then 188 warn "App was built successfully but was not code signed. Users may get security warnings from macOS." 189 warn "Specify a valid code signing identity to enable code signing." 190 fi