From 391f0dcde2695c89759dd73773b3fa38144a8409 Mon Sep 17 00:00:00 2001 From: Julien Palard Date: Tue, 7 Dec 2021 11:28:47 +0100 Subject: [PATCH] Initial commit --- README.md | 116 ++++++++++++++++++++++++++++++++++++++++++++++ compile-python.sh | 66 ++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 README.md create mode 100644 compile-python.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..d9ffb14 --- /dev/null +++ b/README.md @@ -0,0 +1,116 @@ +# Compile Python + +This is a small bash script to compile one or multiple Python versions. + +I use it on my laptop, using Debian, but it may work on other distribs. + +On Debian (and Debian-based distribs) it needs the following +dependencies: + +``` +apt install make build-essential libssl-dev zlib1g-dev libbz2-dev \ +ibreadline-dev libsqlite3-dev wget curl llvm libncursesw5-dev \ +xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev +``` + + +## Usage + +Clone the repo anywhere, then in your `~/.bashrc` add: + + source PATH/To/THE/REPO/compile-python.sh + + +TL;DR: + +```bash +$ compile-pythons +$ python3.6 --version +Python 3.6.15 +$ python3.7 --version +Python 3.7.12 +$ python3.8 --version +Python 3.8.12 +$ python3.9 --version +Python 3.9.9 +$ python3.10 --version +Python 3.10.1 +$ python3.11 --version +Python 3.11.0a2 +``` + + +## How it works + +It downloads official Python sources (from +[https://www.python.org/ftp/python/](https://www.python.org/ftp/python/)), +then compiles them using `--with-pydebug` (it's a dev tool, don't use +it in production! Rely on your distrib in production!), and +`--prefix=~/.local`, and finally installs it using `make altinstall`. + +Anyway it's ~67 lines of code, maybe just read it. + + +## Be nice with distrib' provided Python + +`compile-python` only produces binaries on the form `pythonX.Y` (like +`python3.8`), so `python3` and `python` will always point to your +distrib' Python. + +Don't hesitate to `apt install python-is-python3` if you want `python` +to be `python3`. + + +## Functions + +The file declares 3 functions: + +- `compile-pythons`: To compile a set of usefull Python versions. +- `compile-python`: To compile a given Python version (has autocompletion). +- `venv`: Just a wrapper to `python -m venv` that I like to use daily. + +Using a function don't force you to use the others, they are **not** related. + + +### `compile-pythons` + +This is probably the one you're seeking, it compiles a bunch of +usefull Python verisons, typically usefull if you use +[tox](https://tox.wiki/en/latest/) and need multiple Python versions +to test your project. + + +### `compile-python` + +This one is used by `compile-python` but you can use it manually, like: + + compile-python 3.10.1 + + +### `venv` + +A bit unrelated to the two others, here for historical reasons, this +is how I create venvs. I use it like: + +```bash +$ venv +``` + +If the venv does not exists it's created, if it exist it's just activated. + +It takes an optional parameter: the Python version to use, like `venv +3.10` or `venv 3.6`. + +The venv prompt takes the name of the current directory plus the +version, like: + + (compile-python)(py3.10.0) mdk@seaph:~/ $ + +which I find usefull, but feel free to not use it. + + +## Why not using `pyenv`? + +I know `pyenv` exists, I even used it back in the time. I did not +appreciated the `shims` part (I'm not saying it's bad), so I tried +myself as something more simple: just build Python and that's it. diff --git a/compile-python.sh b/compile-python.sh new file mode 100644 index 0000000..290a0f8 --- /dev/null +++ b/compile-python.sh @@ -0,0 +1,66 @@ +venv() +{ + # Usage: + # + # venv: Creates a venv with the current `python` version. + # venv VERSION: Create a venv with given version. + # + # Example: + # + # venv 3.10 + deactivate 2>/dev/null + if ! [[ -d .venv ]] + then + python$1 -m venv --prompt "$(basename "$PWD"))(py$(python$1 --version | cut -d' ' -f2)" .venv + fi + source .venv/bin/activate +} + +compile-python() +{ + # Inspired from the great https://gitlab.com/python-devs/ci-images/ + # Thanks Barry Warsaw. + + # Needs: + # sudo apt-get update; sudo apt-get install make build-essential libssl-dev zlib1g-dev \ + # libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \ + # libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev + + local PY_VERSION="$1" + local BETA="$2" + local FLAGS="" + if dpkg --compare-versions "$PY_VERSION" ge 3.8.0 # Since 3.8.0 debug builds are ABI compatible, let's use them. + then + FLAGS="--with-pydebug" + fi + local URL="https://www.python.org/ftp/python" + ( + cd /tmp + wget -qO- $URL/$PY_VERSION/Python-$PY_VERSION$BETA.tgz | tar -xzf - || ( + echo "Version not found, check on $URL." + ) + [ -d Python-$PY_VERSION$BETA ] && (cd Python-$PY_VERSION$BETA; ./configure $FLAGS --prefix=$HOME/.local/ && make -j $(nproc) && make altinstall) && + rm -r Python-$PY_VERSION$BETA + ) +} + +compile-pythons() +{ + # Compiles a usefull set of Python versions. + compile-python 3.5.10 & + compile-python 3.6.15 & + compile-python 3.7.12 & + compile-python 3.8.12 & + compile-python 3.9.9 & + compile-python 3.10.1 & + compile-python 3.11.0 a2 & + wait +} + +_compile_python() +{ + COMPREPLY=( $( compgen -W '$( command curl -s https://www.python.org/ftp/python/ | grep -o ">[0-9.]\+/<" | sed "s/^>//;s|/<$||" )' -- "${COMP_WORDS[COMP_CWORD]}") ) +} +complete -F _compile_python compile-python + +PATH="$PATH:$HOME/.local/bin"