Created
January 6, 2017 15:47
-
-
Save colebrumley/b4288a4211b06e8da2f2b94cd5368c38 to your computer and use it in GitHub Desktop.
PyPy+Makeself standalone installer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -ex | |
# WHAT THIS IS | |
# This script creates a standalone "installer" for a pip-enabled Python package | |
# using Makeself. What is different about this script versus native Makeself is | |
# that each installer includes a dedicated Python installation (using PyPy) and | |
# wrapper scripts to make invocation transparent. Python is not required on the | |
# host, and changes to the host's Python installation will not affect apps | |
# installed using this script. | |
# REQUIREMENTS | |
# git, openssl, wget, and makeself are expected. | |
# SETTINGS | |
###################### | |
PYPY_VERSION=5.6.0 | |
PYPY_DIRECTORY=pypy | |
PIP_PACKAGE=$1 | |
# Sometimes the binary name is not the same as the package name from pip | |
EXE_NAME=$2 | |
# Where to put this app's Python | |
TARGET_LIB_DIRECTORY="${3:-/usr/lib/pynary}" | |
TARGET_BIN_DIRECTORY="${4:-/usr/bin}" | |
###################### | |
bail(){ >&2 echo "${@}"; exit 1; } | |
cleanup() { rm -Rf "./$PYPY_DIRECTORY" ./*.bz2; } | |
get_pypy() { | |
local pypy_version=$1 | |
local pypy_dirname=$2 | |
local pypy_filename="pypy2-v${pypy_version}-linux64" | |
local pypy_dl_url="https://bitbucket.org/pypy/pypy/downloads/${pypy_filename}.tar.bz2" | |
wget -O- $pypy_dl_url | tar -xjf - | |
mv -n $pypy_filename $pypy_dirname | |
mkdir -p ${pypy_dirname}/{lib,bin} | |
# Lib fix if applicable | |
[[ -f /lib64/libncurses.so.5.9 ]] && \ | |
cp /lib64/libncurses.so.5.9 ${pypy_dirname}/lib/libtinfo.so.5 | |
cat > ${pypy_dirname}/bin/python <<-'EOF' | |
#!/bin/sh | |
LD_LIBRARY_PATH="$(dirname "$0")/../lib" exec "$(dirname "$0")/pypy" -E -s "${@}" | |
EOF | |
chmod +x ${pypy_dirname}/bin/python | |
# Install pip to make things easier later | |
${pypy_dirname}/bin/python -m ensurepip | |
} | |
mkself(){ | |
local pkg=$1 | |
cat > "$PYPY_DIRECTORY/bin/setup.sh" <<-'EOF' | |
#!/bin/bash | |
APP_NAME="$1" | |
EXE_NAME="$2" | |
LIBDIR="${3:-/usr/lib/pynary}/$APP_NAME" | |
BINDIR="${4:-/usr/bin}" | |
[ -d "$LIBDIR" ] || mkdir -p "$LIBDIR" | |
cp -r ./* "${LIBDIR}/" | |
cat > "${BINDIR}/${EXE_NAME}" <<EOD | |
#!/bin/sh | |
exec "$LIBDIR/bin/python" "$LIBDIR/bin/$EXE_NAME" "\$@" | |
EOD | |
chmod +x "${BINDIR}/${EXE_NAME}" | |
EOF | |
chmod +x "$PYPY_DIRECTORY/bin/setup.sh" | |
makeself "$PYPY_DIRECTORY" "$pkg.installer" "PyPy+Makeself installer for $PIP_PACKAGE" \ | |
./bin/setup.sh "$pkg" "$EXE_NAME" "$TARGET_LIB_DIRECTORY" "$TARGET_BIN_DIRECTORY" | |
} | |
# Housekeeping | |
[[ "$PIP_PACKAGE" == "" ]] && bail No pip package defined | |
cd "$(dirname "$0")" | |
trap 'cleanup' EXIT | |
[[ -d "$PYPY_DIRECTORY" ]] || get_pypy "$PYPY_VERSION" "$PYPY_DIRECTORY" | |
LD_LIBRARY_PATH=${PYPY_DIRECTORY}/lib \ | |
${PYPY_DIRECTORY}/bin/python -m pip --no-cache-dir install "$PIP_PACKAGE" | |
mkself $1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment