如何确定主机系统使用的libc实现

3
在我们使用预构建二进制文件和绑定生成器的Python设置代码中,我们会检查操作系统和CPU架构,并相应地下载二进制文件。
现在,有许多针对manylinux(glibc)和musllinux(musl)的二进制文件。我们如何找出主机系统使用的libc实现方式呢? 我知道可以使用platform.libc_ver(),但对于musl主机,它目前只返回两个空字符串(请参见CPython issue 87414)。
然而,已经有更精确的代码可用了,因为pip需要选择正确的wheel。

@stark musl系统没有ldd,根据他们的FAQ。相反,ldd功能被构建到他们的动态链接器中。我目前无法访问Alpine Linux平台,所以我不确定这是否可以可靠地区分musl/glibc。无论如何,实现起来都不会很简单。我更倾向于寻找一个Python的单函数调用解决方案。 - mara004
3个回答

3
from packaging.tags import sys_tags
tags = list(sys_tags())
print('musllinux' in tags[0].platform)

1
有趣。我猜我应该仔细看看打包。虽然这不像是最优化的API,但我想阅读打包的_musllinux.py文件。尽管如此,我仍认为一个更优化的解决方案是将打包的musl检测代码移入标准库中。 - mara004
如果你正在构建轮子,可以使用类似于from wheel.vendored.packaging.tags import platform_tags # or sys_tags的东西。包pip也有这些东西,但pip可能不存在。 - sg qy
回到这个问题上,实际上现在有一个开放的 CPython PR https://github.com/python/cpython/pull/103784。 - undefined

0
这是我现在正在使用的解决方案。它受到了@AndrewNelson答案的启发,也使用了platform模块,但它是作为对platform.libc_ver()的覆盖写,并直接调用packaging._musllinux。
import sys
import platform
import packaging._musllinux

def get_libc_info():
    name, ver = platform.libc_ver()
    if not name:
        musl_ver = packaging._musllinux._get_musl_version(sys.executable)
        if musl_ver:
            name, ver = "musl", f"{musl_ver.major}.{musl_ver.minor}"
    return name, ver

print( get_libc_info() )

-1
如果你只是想检查glibc和musl,为什么不直接这样做:
import platform

def is_musl():
    libc, version = platform.libc_ver()
    return libc != "glibc"

这实际上就是我目前正在做的事情,但由于除glibc和musl之外的其他libc实现可能存在于Linux上,因此这种方式有些不安全,虽然不常见。 - mara004

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接