3.5 KiB
pyenv-binary (experimental)
Package an installed Python version into a relocatable archive that can be installed on another machine.
This is experimental and intentionally decoupled: it does not change
pyenv install or any other command. You drive it explicitly through
pyenv binary. Run pyenv binary <command> --help for details on a command.
Portability
An archive is portable across machines that share its build platform (OS, architecture and a compatible libc) and have the recorded system libraries. It is not portable across, say, glibc and musl, or to an older glibc; the platform and dependency metadata exist to catch that.
Commands
pyenv binary package <version>[:<entry>] --archive-base-url <url>
Installs <version> from source under a separate name, packages that install
with save, then emits a python-build definition for it with
generate-installer. With no explicit entry, the name is generated from the
current platform, platform version and architecture. An explicit entry keeps
the existing custom-build workflow.
pyenv binary package 3.12.7 \
--archive-base-url https://example.com/binaries
# On Debian 12 x86_64, writes 3.12.7-debian-12-x86_64.tar.gz,
# its .meta file and a `3.12.7-debian-12-x86_64' definition.
pyenv binary package 3.12.7:company-python \
--archive-base-url https://example.com/binaries
The archive, metadata and definition land in the current directory, named after
the entry. Host the archive under <url> and drop the definition into
python-build's definition directory.
pyenv binary package-name <version>
Prints the automatically generated entry name without building anything. Linux
uses the distribution name and version, macOS uses the macOS version, and other
systems use the name and release reported by uname. All names include the
architecture.
pyenv binary package-name 3.12.7
# 3.12.7-debian-12-x86_64
pyenv binary save <version> [<output-dir>] [--name <name>]
Packs an installed version into <version>-<platform>.tar.gz (relative paths)
and writes <version>-<platform>.meta describing the build platform (OS, arch,
distro and libc version) and the system libraries the build links against. Use
--name to set a different base name for both files.
pyenv binary save 3.12.7 ./dist
pyenv binary generate-installer <metadata-file> --archive-url <url> [-o <output>]
Reads a .meta file and emits a python-build definition. Drop it into
python-build's definition directory and pyenv install <name> installs the
archive like any other version. The archive location is a parameter, so you can
host it anywhere (it does not have to be a pyenv location); the archive itself
must sit next to the .meta file so its checksum can be baked into the
definition.
The definition refuses to install on a different OS/architecture, or an older glibc, than the archive was built for, and checks that the system libraries it needs are present.
pyenv binary generate-installer ./dist/3.12.7-linux-x86_64.meta \
--archive-url https://example.com/3.12.7-linux-x86_64.tar.gz \
-o "$(pyenv root)/plugins/python-build/share/python-build/3.12.7-linux-x86_64"
pyenv install 3.12.7-linux-x86_64
pyenv binary relocate <prefix>
Rewrites the rpaths of a Python tree unpacked into <prefix> so the interpreter
and its extension modules load the bundled libraries from there rather than from
the path the archive was built at. Uses patchelf. The generated definition
calls this; you rarely run it by hand.
Relocation is implemented for Linux; macOS is not wired up yet.