PEP 656 – Plattform-Tag für Linux-Distributionen, die Musl verwenden
- Autor:
- Tzu-ping Chung <uranusjr at gmail.com>
- Sponsor:
- Brett Cannon <brett at python.org>
- PEP-Delegate:
- Paul Moore <p.f.moore at gmail.com>
- Discussions-To:
- Discourse thread
- Status:
- Final
- Typ:
- Standards Track
- Thema:
- Packaging
- Erstellt:
- 17-März-2021
- Post-History:
- 17-März-2021, 18-Apr-2021
- Resolution:
- Discourse-Nachricht
Zusammenfassung
Dieses PEP schlägt eine neue Plattform-Tag-Serie musllinux für binäre Python-Paketdistributionen für eine Python-Installation vor, die auf musl auf einer Linux-Distribution basiert. Der Tag funktioniert ähnlich wie die in PEP 600 spezifizierten "perennial manylinux"-Plattform-Tags, zielt aber stattdessen auf musl-basierte Plattformen ab.
Motivation
Angesichts der weit verbreiteten Nutzung von Containern gewinnen Distributionen wie Alpine Linux [alpine] mehr an Popularität als je zuvor. Viele von ihnen basieren auf musl [musl], einer anderen libc-Implementierung als glibc, und können daher die bestehenden manylinux-Plattform-Tags nicht verwenden. Dies bedeutet, dass Python-Paketprojekte keine binären Distributionen auf PyPI für sie bereitstellen können. Benutzer solcher Projekte fordern Build-Einschränkungen von diesen Projekten, was eine unnötige Belastung für die Projektbetreuer darstellt.
Begründung
Laut Dokumentation hat musl eine stabile ABI und erhält die Abwärtskompatibilität aufrecht [musl-compatibility] [compare-libcs]. Daher ist garantiert, dass ein gegen eine frühere Version von musl kompiliertes Binärpaket gegen eine neuere musl-Laufzeitumgebung läuft [musl-compat-ml]. Daher verwenden wir ein Schema, das dem auf glibc-Versionen basierenden manylinux-Tag-Schema ähnelt, jedoch gegen musl-Versionen anstelle von glibc.
Die Logik hinter dem neuen Plattform-Tag folgt weitgehend PEP 600 ("perennial manylinux") und erfordert, dass Wheels mit diesem Tag ähnliche Zusagen machen. Weitere Details zur Begründung und zum Design finden Sie in PEP 600.
Die musllinux-Plattform-Tags gelten nur für Python-Interpreter, die dynamisch gegen die musl libc gelinkt und in der Laufzeit-Shared-Library auf einem Linux-Betriebssystem ausgeführt werden. Statisch gelinkte Interpreter oder gemischte Builds mit anderen libc-Implementierungen (wie glibc) sind nicht betroffen und werden durch die in diesem Dokument definierten Plattform-Tags nicht unterstützt. Solche Interpreter sollten keine Kompatibilität mit musllinux-Plattform-Tags beanspruchen.
Spezifikation
Tags mit dem neuen Schema haben die Form
musllinux_${MUSLMAJOR}_${MUSLMINOR}_${ARCH}
Dieser Tag verspricht, dass das Wheel auf jeder Mainstream-Linux-Distribution läuft, die musl-Version ${MUSLMAJOR}.${MUSLMINOR} verwendet, gemäß dem perennialen Design. Alle anderen systembezogenen Abhängigkeitsanforderungen beruhen auf der Definition der Community für die bewusst vage Beschreibung "Mainstream", die in PEP 600 eingeführt wurde. Ein Wheel kann neuere Systemabhängigkeiten verwenden, wenn alle Mainstream-Distributionen, die die angegebene musl-Version verwenden, die Abhängigkeit standardmäßig bereitstellen. Sobald alle Mainstream-Distributionen auf der musl-Version eine bestimmte Abhängigkeitsversion standardmäßig ausliefern, werden Benutzer, die sich auf ältere Versionen verlassen, automatisch aus der Abdeckung dieses musllinux-Tags entfernt.
Auslesen der Musl-Version
Die musl-Versionswerte können durch Ausführung der musl libc Shared-Library, auf der der Python-Interpreter gerade läuft, und Parsen der Ausgabe erhalten werden
import re
import subprocess
def get_musl_major_minor(so: str) -> tuple[int, int] | None:
"""Detect musl runtime version.
Returns a two-tuple ``(major, minor)`` that indicates musl
library's version, or ``None`` if the given libc .so does not
output expected information.
The libc library should output something like this to stderr::
musl libc (x86_64)
Version 1.2.2
Dynamic Program Loader
"""
proc = subprocess.run([so], stderr=subprocess.PIPE, text=True)
lines = (line.strip() for line in proc.stderr.splitlines())
lines = [line for line in lines if line]
if len(lines) < 2 or lines[0][:4] != "musl":
return None
match = re.match(r"Version (\d+)\.(\d+)", lines[1])
if match:
return (int(match.group(1)), int(match.group(2)))
return None
Es gibt derzeit zwei mögliche Wege, den Speicherort der musl-Bibliothek zu finden, auf die ein Python-Interpreter läuft: entweder mit dem systemeigenen ldd-Befehl [ldd] oder durch Parsen des PT_INTERP-Abschnitts aus dem ELF-Header der ausführbaren Datei [elf].
Formatieren des Tags
Distributionen, die den Tag verwenden, machen ähnliche Zusagen wie in PEP 600 beschrieben, einschließlich
- Das Binärpaket funktioniert auf jeder Mainstream-Linux-Distribution mit musl-Version
${MUSLMAJOR}.${MUSLMINOR}oder neuer. - Die
${ARCH}des Binärpakets stimmt mit dem Rückgabewert vonsysconfig.get_platform()auf dem Host-System überein, wobei Punkte (.) und Bindestriche (-) durch Unterstriche (_) ersetzt werden, wie in PEP 425 und PEP 427 beschrieben.
Beispielwerte
musllinux_1_1_x86_64 # musl 1.1 running on x86-64.
musllinux_1_2_aarch64 # musl 1.2 running on ARM 64-bit.
Der Wert kann mit dem folgenden Python-Code formatiert werden
import sysconfig
def format_musllinux(musl_version: tuple[int, int]) -> str:
os_name, sep, arch = sysconfig.get_platform().partition("-")
assert os_name == "linux" and sep, "Not a Linux"
arch = arch.replace(".", "_").replace("-", "_")
return f"musllinux_{musl_version[0]}_{musl_version[1]}_{arch}"
Empfehlungen für Paketindizes
Es wird empfohlen, dass Python-Paket-Repositories, einschließlich PyPI, Plattform-Tags akzeptieren, die dem folgenden regulären Ausdruck entsprechen
musllinux_([0-9]+)_([0-9]+)_([^.-]+)
Python-Paket-Repositories können zusätzliche Anforderungen auferlegen, um Wheels mit bekannten Problemen abzulehnen, einschließlich, aber nicht beschränkt auf
- Ein
musllinux_1_1-Wheel, das Symbole enthält, die nur in musl 1.2 oder neuer verfügbar sind. - Ein Wheel, das von externen Bibliotheken abhängt, die nicht als allgemein verfügbar für die Zielgruppe des Paketindex gelten.
- Ein Plattform-Tag, der Kompatibilität mit einer nicht existierenden musl-Version beansprucht (z. B.
musllinux_9000_0).
Solche Richtlinien liegen letztendlich bei den einzelnen Paket-Repositories. Es ist nicht die Absicht des Autors, den Betreuern Einschränkungen aufzuerlegen.
Abwärtskompatibilität
Es gibt keine Abwärtskompatibilitätsprobleme in diesem PEP.
Abgelehnte Ideen
Erstellung eines Plattform-Tags speziell für Alpine Linux
Erfahrungen aus der Vergangenheit mit der manylinux-Tag-Serie zeigen, dass dieser Ansatz zu zeitaufwändig wäre. Der Autor ist der Meinung, dass die Regel "funktioniert gut mit anderen" inklusiver ist und in der Praxis gut funktioniert.
Referenzen
Urheberrecht
Dieses Dokument wird in die Public Domain oder unter die CC0-1.0-Universal-Lizenz gestellt, je nachdem, welche Lizenz permissiver ist.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0656.rst
Zuletzt geändert: 2025-02-01 08:55:40 GMT