|
| 1 | +#!/bin/bash |
| 2 | +set -e |
| 3 | + |
| 4 | +NAME="PythonSkeleton" |
| 5 | +IDENTIFIER="com.example.PythonSkeleton" |
| 6 | +OSXVERSION=10.9 |
| 7 | +APPLICATION=application |
| 8 | + |
| 9 | +BASE=`pwd` |
| 10 | +PREFIX="$BASE/dist" |
| 11 | +BREW=/usr/local |
| 12 | + |
| 13 | +brew update |
| 14 | + |
| 15 | +function brew_install { |
| 16 | + pkg=$1 |
| 17 | + brew list | grep -q $pkg || brew install $pkg |
| 18 | + brew outdated $pkg || brew upgrade $pkg |
| 19 | +} |
| 20 | + |
| 21 | +brew_install openssl |
| 22 | +brew_install sqlite |
| 23 | +brew_install xz |
| 24 | +brew_install readline |
| 25 | + |
| 26 | +# add lxml dependencies |
| 27 | +brew_install libxml2 |
| 28 | +brew_install libxslt |
| 29 | + |
| 30 | +# Python |
| 31 | +CPPFLAGS="-I$BREW/opt/openssl/include/openssl" |
| 32 | +LDFLAGS="" |
| 33 | +for pkg in openssl sqlite readline xz; do |
| 34 | + CPPFLAGS="$CPPFLAGS -I$BREW/opt/$pkg/include" |
| 35 | + LDFLAGS="$LDFLAGS -L$BREW/opt/$pkg/lib" |
| 36 | +done |
| 37 | +export CPPFLAGS |
| 38 | +export LDFLAGS |
| 39 | + |
| 40 | +version=3.5.2 |
| 41 | +url="https://www.python.org/ftp/python/${version}/Python-${version}.tar.xz" |
| 42 | +name=`basename $url .tar.xz` |
| 43 | +tar=`basename $url` |
| 44 | + |
| 45 | +test -e $tar || curl -O $url |
| 46 | +test -e $name || tar xf $tar |
| 47 | +cd $name |
| 48 | +./configure MACOSX_DEPLOYMENT_TARGET=$OSXVERSION --prefix="$PREFIX" |
| 49 | +make -j8 |
| 50 | +make altinstall |
| 51 | + |
| 52 | +unset CPPFLAGS |
| 53 | +unset LDFLAGS |
| 54 | + |
| 55 | +ln -sf pip3.5 "$PREFIX/bin/pip" |
| 56 | +ln -sf pip3.5 "$PREFIX/bin/pip3" |
| 57 | +ln -sf python3.5 "$PREFIX/bin/python3" |
| 58 | + |
| 59 | + |
| 60 | +PATH="$PREFIX/bin:$PATH" |
| 61 | +cd "$BASE" |
| 62 | +test -e requirements.txt && pip3.5 install -r requirements.txt |
| 63 | + |
| 64 | +chmod -R +rw "$PREFIX/lib" |
| 65 | +# make self contained |
| 66 | +for lib in \ |
| 67 | + opt/libxml2/lib/libxml2.2.dylib \ |
| 68 | + opt/libxslt/lib/libexslt.0.dylib \ |
| 69 | + opt/libxslt/lib/libxslt.1.dylib \ |
| 70 | + opt/openssl/lib/libcrypto.1.0.0.dylib \ |
| 71 | + opt/openssl/lib/libssl.1.0.0.dylib \ |
| 72 | + opt/readline/lib/libreadline.6.dylib \ |
| 73 | + opt/sqlite/lib/libsqlite3.0.dylib \ |
| 74 | + opt/xz/lib/liblzma.5.dylib \ |
| 75 | +; do |
| 76 | + target="$PREFIX/lib/`basename "$lib"`" |
| 77 | + rm -f "$target" |
| 78 | + cp -a "$BREW/$lib" "$target" |
| 79 | +done |
| 80 | +chmod -R +rw "$PREFIX/lib" |
| 81 | +mkdir -p "$PREFIX/etc/openssl/certs" |
| 82 | +cp /usr/local/etc/openssl/cert.pem "$PREFIX/etc/openssl" |
| 83 | + |
| 84 | +# cleanup |
| 85 | +rm -rf \ |
| 86 | + "$PREFIX/lib/python3.5/test" \ |
| 87 | + "$PREFIX/bin/openssl" \ |
| 88 | + "$PREFIX/etc/openssl/man" \ |
| 89 | + "$PREFIX/bin/c_rehash" \ |
| 90 | + "$PREFIX/bin/2to3-3.5" \ |
| 91 | + "$PREFIX/bin/easy_install-3.5" \ |
| 92 | + "$PREFIX/bin/idle3.5" \ |
| 93 | + "$PREFIX/bin/pyvenv-3.5" \ |
| 94 | + "$PREFIX/bin/c_rehash" \ |
| 95 | + "$PREFIX/bin/pydoc3.5" |
| 96 | + |
| 97 | +for bin in $PREFIX/bin/pip3.5 $PREFIX/bin/python3.5m-config; do |
| 98 | + sed "s#$PREFIX/bin/python3.5#/usr/bin/env python3.5#g" "$bin" > "$bin.t" |
| 99 | + mv "$bin.t" "$bin" |
| 100 | + chmod +x "$bin" |
| 101 | +done |
| 102 | + |
| 103 | +find "$PREFIX" -d -name "__pycache__" -type d -exec rm -r "{}" \; |
| 104 | +find "$PREFIX" -name "*.pyc" -exec rm "{}" \; |
| 105 | +find "$PREFIX" -name "*.a" -exec rm -f "{}" \; |
| 106 | + |
| 107 | +for plib in \ |
| 108 | + $PREFIX/lib/python3.5/site-packages/lxml/etree.cpython-35m-darwin.so \ |
| 109 | + $PREFIX/lib/python3.5/site-packages/lxml/objectify.cpython-35m-darwin.so \ |
| 110 | + $PREFIX/lib/python3.5/lib-dynload/_hashlib.cpython-35m-darwin.so \ |
| 111 | + $PREFIX/lib/python3.5/lib-dynload/_lzma.cpython-35m-darwin.so \ |
| 112 | + $PREFIX/lib/python3.5/lib-dynload/_sqlite3.cpython-35m-darwin.so \ |
| 113 | + $PREFIX/lib/python3.5/lib-dynload/_ssl.cpython-35m-darwin.so \ |
| 114 | + $PREFIX/lib/python3.5/lib-dynload/readline.cpython-35m-darwin.so \ |
| 115 | +; do |
| 116 | + if [ -e "$plib" ]; then |
| 117 | + for lib in \ |
| 118 | + $BREW/Cellar/libxslt/1.1.28_1/lib/libxslt.1.dylib \ |
| 119 | + $BREW/Cellar/openssl/1.0.2d_1/lib/libcrypto.1.0.0.dylib \ |
| 120 | + $BREW/opt/libxml2/lib/libxml2.2.dylib \ |
| 121 | + $BREW/opt/libxslt/lib/libexslt.0.dylib \ |
| 122 | + $BREW/opt/libxslt/lib/libxslt.1.dylib \ |
| 123 | + $BREW/opt/openssl/lib/libcrypto.1.0.0.dylib \ |
| 124 | + $BREW/opt/openssl/lib/libssl.1.0.0.dylib \ |
| 125 | + $BREW/opt/readline/lib/libreadline.6.dylib \ |
| 126 | + $BREW/opt/sqlite/lib/libsqlite3.0.dylib \ |
| 127 | + $BREW/opt/xz/lib/liblzma.5.dylib \ |
| 128 | + $PREFIX/lib/libcrypto.1.0.0.dylib \ |
| 129 | + $PREFIX/lib/libexslt.0.dylib \ |
| 130 | + $PREFIX/lib/liblzma.5.dylib \ |
| 131 | + $PREFIX/lib/libreadline.6.dylib \ |
| 132 | + $PREFIX/lib/libsqlite3.0.dylib \ |
| 133 | + $PREFIX/lib/libssl.1.0.0.dylib \ |
| 134 | + $PREFIX/lib/libxml2.2.dylib \ |
| 135 | + $PREFIX/lib/libxslt.1.dylib \ |
| 136 | + /usr/lib/libexslt.0.dylib \ |
| 137 | + /usr/lib/libreadline.6.dylib \ |
| 138 | + /usr/lib/libxml2.2.dylib \ |
| 139 | + /usr/lib/libxslt.1.dylib \ |
| 140 | + ; do |
| 141 | + name=`basename $lib` |
| 142 | + otool -L "$plib" | grep -q "$lib" && install_name_tool -change "$lib" "@executable_path/../lib/$name" "$plib" |
| 143 | + done |
| 144 | + otool -L "$plib" |
| 145 | + fi |
| 146 | +done |
| 147 | + |
| 148 | +mkdir -p "${NAME}.app/Contents/MacOS" |
| 149 | +mv $PREFIX "${NAME}.app/Contents/Python" |
| 150 | +cat > "$NAME.app/Contents/MacOS/$NAME" << EOF |
| 151 | +#!/bin/bash |
| 152 | +cd "\$(dirname "\$0")" |
| 153 | +PREFIX="\$(dirname "\$(pwd)")/Python" |
| 154 | +export SSL_CERT_FILE="\$PREFIX/etc/openssl/cert.pem" |
| 155 | +export SSL_CERT_DIR="\$PREFIX/etc/openssl/certs" |
| 156 | +"\$PREFIX/bin/python3.5" -m $APPLICATION |
| 157 | +EOF |
| 158 | +chmod +x "$NAME.app/Contents/MacOS/$NAME" |
| 159 | + |
| 160 | +cat > "$NAME.app/Contents/Info.plist" << EOF |
| 161 | +<?xml version="1.0" encoding="UTF-8"?> |
| 162 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| 163 | +<plist version="1.0"> |
| 164 | +<dict> |
| 165 | + <key>BuildMachineOSBuild</key> |
| 166 | + <string>15C50</string> |
| 167 | + <key>CFBundleDevelopmentRegion</key> |
| 168 | + <string>en</string> |
| 169 | + <key>CFBundleExecutable</key> |
| 170 | + <string>${NAME}</string> |
| 171 | + <key>CFBundleIconFile</key> |
| 172 | + <string>AppIcon</string> |
| 173 | + <key>CFBundleIdentifier</key> |
| 174 | + <string>${IDENTIFIER}</string> |
| 175 | + <key>CFBundleInfoDictionaryVersion</key> |
| 176 | + <string>6.0</string> |
| 177 | + <key>CFBundleName</key> |
| 178 | + <string>${NAME}</string> |
| 179 | + <key>CFBundlePackageType</key> |
| 180 | + <string>APPL</string> |
| 181 | + <key>CFBundleShortVersionString</key> |
| 182 | + <string>0.8</string> |
| 183 | + <key>CFBundleSignature</key> |
| 184 | + <string>????</string> |
| 185 | + <key>CFBundleSupportedPlatforms</key> |
| 186 | + <array> |
| 187 | + <string>MacOSX</string> |
| 188 | + </array> |
| 189 | + <key>CFBundleVersion</key> |
| 190 | + <string>1</string> |
| 191 | + <key>DTPlatformBuild</key> |
| 192 | + <string>7C68</string> |
| 193 | + <key>DTPlatformVersion</key> |
| 194 | + <string>GM</string> |
| 195 | + <key>DTSDKBuild</key> |
| 196 | + <string>15C43</string> |
| 197 | + <key>DTSDKName</key> |
| 198 | + <string>macosx10.10</string> |
| 199 | + <key>DTXcode</key> |
| 200 | + <string>0720</string> |
| 201 | + <key>DTXcodeBuild</key> |
| 202 | + <string>7C68</string> |
| 203 | + <key>LSMinimumSystemVersion</key> |
| 204 | + <string>${OSXVERSION}</string> |
| 205 | + <key>LSUIElement</key> |
| 206 | + <true/> |
| 207 | + <key>NSHumanReadableCopyright</key> |
| 208 | + <string>No Copyright</string> |
| 209 | + <key>NSMainNibFile</key> |
| 210 | + <string>MainMenu</string> |
| 211 | + <key>NSPrincipalClass</key> |
| 212 | + <string>NSApplication</string> |
| 213 | +</dict> |
| 214 | +</plist> |
| 215 | +EOF |
| 216 | + |
| 217 | +test -e test.py && "${NAME}.app/Contents/Python/bin/python3.5" test.py |
| 218 | + |
| 219 | +find "${NAME}.app" -d -name "__pycache__" -type d -exec rm -r "{}" \; |
| 220 | +find "${NAME}.app" -name "*.pyc" -exec rm "{}" \; |
0 commit comments