Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 656 – Musl을 사용하는 Linux 배포판을 위한 플랫폼 태그

Author:
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
Type:
Standards Track
Topic:
Packaging
Created:
17-Mar-2021
Post-History:
17-Mar-2021, 18-Apr-2021
Resolution:
Discourse message

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

이 PEP는 Linux 배포판에서 musl에 의존하는 Python 설치를 위한 바이너리 Python 패키지 배포에 사용되는 새로운 플랫폼 태그 시리즈 musllinux를 제안합니다. 이 태그는 PEP 600에서 지정한 “perennial manylinux” 플랫폼 태그와 유사하게 작동하지만, 대신 musl 기반 플랫폼을 대상으로 합니다.

동기

컨테이너가 널리 사용되면서 Alpine Linux [alpine]와 같은 배포판이 그 어느 때보다 큰 인기를 얻고 있습니다. 이들 중 다수는 glibc와는 다른 libc 구현인 musl [musl]을 기반으로 하므로 기존 manylinux 플랫폼 태그를 사용할 수 없습니다. 이는 Python 패키지 프로젝트가 이러한 배포판을 위해 PyPI에 바이너리 배포를 제공할 수 없다는 의미입니다. 이러한 프로젝트의 사용자는 해당 프로젝트에 빌드 제약 조건을 요구하므로, 프로젝트 유지 관리자에게 불필요한 부담이 발생합니다.

근거

문서에 따르면 musl은 안정적인 ABI를 제공하고 하위 호환성을 유지하므로 [musl-compatibility] [compare-libcs], 이전 버전의 musl에 맞춰 컴파일된 바이너리는 최신 musl 런타임에서 실행된다고 보장됩니다 [musl-compat-ml]. 따라서 glibc 버전에 기반한 manylinux 태그와 유사한 체계를 사용하되, glibc 대신 musl 버전을 기준으로 합니다.

새로운 플랫폼 태그의 기본 논리는 PEP 600(“perennial manylinux”)를 대체로 따르며, 이 태그를 사용하는 휠이 유사한 보장을 제공하도록 요구합니다. 설계의 근거와 논리에 대한 자세한 내용은 PEP 600을 참조하십시오.

musllinux 플랫폼 태그는 Linux 운영 체제에서 musl libc에 동적으로 연결되고 런타임 공유 라이브러리에서 실행되는 Python 인터프리터에만 적용됩니다. 정적으로 연결된 인터프리터 또는 glibc와 같은 다른 libc 구현과 혼합된 빌드는 범위에 포함되지 않으며, 이 문서에서 정의하는 플랫폼 태그의 지원 대상이 아닙니다. 이러한 인터프리터는 musllinux 플랫폼 태그와의 호환성을 주장해서는 안 됩니다.

사양

새로운 체계를 사용하는 태그는 다음 형식을 취합니다.:

musllinux_${MUSLMAJOR}_${MUSLMINOR}_${ARCH}

이 태그는 perennial 설계에 따라, musl 버전 ${MUSLMAJOR}.${MUSLMINOR}을 사용하는 모든 주류 Linux 배포판에서 휠이 작동한다고 보장합니다. 그 밖의 모든 시스템 수준 의존성 요구 사항은 PEP 600에서 도입된 의도적으로 모호한 “주류”라는 설명에 대한 커뮤니티의 정의에 의존합니다. 지정된 musl 버전을 사용하는 모든 주류 배포판이 해당 의존성을 기본으로 제공하는 경우 휠은 더 최신의 시스템 의존성을 사용할 수 있습니다. musl 버전의 모든 주류 배포판이 특정 의존성 버전을 기본으로 제공하게 되면, 이전 버전에 의존하는 사용자는 해당 musllinux 태그의 적용 범위에서 자동으로 제외됩니다.

musl 버전 읽기

Python 인터프리터가 현재 실행 중인 musl libc 공유 라이브러리를 실행하고 출력을 분석하여 musl 버전 값을 얻을 수 있습니다.:

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

현재 Python 인터프리터가 실행 중인 musl 라이브러리의 위치를 찾는 방법은 두 가지입니다. 시스템 ldd 명령 [ldd]을 사용하거나 실행 파일의 ELF 헤더에서 PT_INTERP 섹션의 값을 분석하는 방법 [elf]입니다.

태그 형식 지정

이 태그를 사용하는 배포판은 PEP 600에 설명된 다음과 같은 유사한 보장을 제공합니다.

  1. 배포판은 musl 버전 ${MUSLMAJOR}.${MUSLMINOR} 이상을 사용하는 모든 주류 Linux 배포판에서 작동합니다.
  2. 배포판의 ${ARCH}는 호스트 시스템에서 sysconfig.get_platform()이 반환하는 값과 일치하며, PEP 425PEP 427에 설명된 대로 마침표(.)와 하이픈(-) 문자를 밑줄(_)로 바꿉니다.

예시 값:

musllinux_1_1_x86_64   # musl 1.1 running on x86-64.
musllinux_1_2_aarch64  # musl 1.2 running on ARM 64-bit.

값은 다음 Python 코드로 형식을 지정할 수 있습니다.:

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}"

패키지 색인에 대한 권장 사항

PyPI를 포함한 Python 패키지 저장소는 다음 정규 표현식과 일치하는 플랫폼 태그를 허용하는 것이 좋습니다.:

musllinux_([0-9]+)_([0-9]+)_([^.-]+)

Python 패키지 저장소는 알려진 문제가 있는 휠을 거부하기 위해 추가 요구 사항을 부과할 수 있으며, 여기에는 다음 항목이 포함되지만 이에 국한되지는 않습니다:

  • musl 1.2 이상에서만 사용할 수 있는 기호를 포함하는 musllinux_1_1 휠입니다.
  • 패키지 색인의 대상 사용자가 일반적으로 사용할 수 있다고 간주되지 않는 외부 라이브러리에 의존하는 휠입니다.
  • 존재하지 않는 musl 버전과의 호환성을 주장하는 플랫폼 태그입니다(예: musllinux_9000_0).

이러한 정책은 궁극적으로 개별 패키지 저장소에 달려 있습니다. 저자가 유지 관리자에게 제한을 부과하려는 의도는 아닙니다.

하위 호환성

이 PEP에는 하위 호환성 문제가 없습니다.

거부된 아이디어

Alpine Linux 전용 플랫폼 태그 만들기

과거 manylinux 태그 시리즈의 경험에 따르면 이 접근 방식은 시간 측면에서 비용이 너무 큽니다. 저자는 “다른 것들과 잘 작동한다”는 규칙이 더 포괄적이며 실제로도 충분히 잘 작동한다고 생각합니다.

참고 자료