A plea not to use uv-build

A plea not to use uv-build

After seeing yet another dozen packages lose keywords on Gentoo because of a single key dependency switching to uv-build, I would like to plea on behalf of Gentoo users: please don’t use uv-build as a build backend. Just to be clear, this is not about uv itself or any other Astral tools; these are good tools with a nice and responsive upstream. The uv-build backend is one thing we have to disagree on. I’m not saying it’s bad; I’m saying that its benefits don’t outweigh the drawbacks.

在看到又有十几款软件包因为一个关键依赖项切换到 uv-build 而在 Gentoo 上失去关键字后,我想代表 Gentoo 用户恳求大家:请不要使用 uv-build 作为构建后端。需要明确的是,这并非针对 uv 本身或其他任何 Astral 工具;这些都是优秀的工具,且拥有积极响应的上游。但 uv-build 后端是我们必须持不同意见的一点。我并不是说它不好,我只是说它的收益无法抵消其弊端。

What are the drawbacks? It’s really big and it’s written in Rust. Rust has many advantages, but none of them really matter for a build backend that is used to build pure Python packages. It’s a huge dependency (as of 0.13.0, its wheels are between 1.2 MiB and 1.5 MiB, depending on the platform) and it has no benefit over using a small pure Python backend (say, flit-core whose wheel is 45 KiB). It means that all Gentoo users need to build it from source, and given that it’s released quite frequently (12 releases in the 30 days prior to writing this post), that’s a lot of building. Like, for every 100 ms spent running uv-build to install one release of your package, Gentoo users will spend many hours building new uv-build versions over and over again.

弊端是什么?它非常庞大,而且是用 Rust 编写的。Rust 有许多优点,但对于一个用于构建纯 Python 软件包的构建后端来说,这些优点都无关紧要。它是一个巨大的依赖项(截至 0.13.0 版本,其 wheel 文件大小在 1.2 MiB 到 1.5 MiB 之间,具体取决于平台),相比使用小型纯 Python 后端(例如 wheel 大小仅为 45 KiB 的 flit-core),它没有任何优势。这意味着所有 Gentoo 用户都需要从源码构建它,考虑到它发布非常频繁(在撰写本文前的 30 天内发布了 12 次),这需要大量的构建工作。例如,每花费 100 毫秒运行 uv-build 来安装一个软件包版本,Gentoo 用户就需要花费数小时反复构建新的 uv-build 版本。

However, build times aren’t the biggest problem; portability is. You can run Python pretty much anywhere where you can get a working C compiler. Some minor features may not work, but the core is reasonably portable. The list of platforms supported by Rust is growing slowly, and even if you can get a working Rust compiler on a given platform, uv may not work. The problems can range from bugs in the lot of packages that uv depends on (for example, rustix::fs and its dependencies skipping SPARC, for no apparent reason), to the resulting executable being so big that the toolchain runs out of address space (and unlike system memory, you can’t really add address space to a system; the Gentoo uv ebuild already carries two hacks to make it possible to build uv on 32-bit platforms). And then, if your platform is not supported at all… well, let’s just say that adding and maintaining a new platform is a full-time job that may involve a lot of swearing at the code churn.

然而,构建时间并不是最大的问题,可移植性才是。只要能获得可用的 C 编译器,你几乎可以在任何地方运行 Python。虽然一些次要功能可能无法使用,但核心部分是相当可移植的。Rust 支持的平台列表增长缓慢,即使你在某个平台上能获得可用的 Rust 编译器,uv 也可能无法运行。问题范围很广,从 uv 所依赖的大量软件包中的错误(例如,rustix::fs 及其依赖项无缘无故地跳过了 SPARC 架构),到生成的执行文件过大导致工具链耗尽地址空间(与系统内存不同,你无法真正为系统增加地址空间;Gentoo 的 uv ebuild 已经包含了两个补丁,才使得在 32 位平台上构建 uv 成为可能)。而且,如果你的平台根本不受支持……好吧,只能说添加和维护一个新平台是一项全职工作,其中可能涉及对代码频繁变动的大量抱怨。

What about the advantages? Well, I’m aware of two reasons to use uv-build. One is consistency with using uv for your project, and it doesn’t really matter. It’s a backend and the whole point of PEP 517 is that you can use any backend with any tool. You can use flit-core, you can use hatchling, and either of them will work just fine with uv (or any other frontend). The other reason is performance and that argument makes even less sense. Even if it mattered, we’re realistically talking about a difference in the ballpark of 100 ms, for an action executed rarely; it is equally possible that any gain will be outweighed by the time needed to fetch the 1.5 MiB wheel for uv-build. But it doesn’t matter, because realistically the backend is only used by project developers, contributors, CI/CD workflows, downstream packagers and users of source distributions; all regular users use wheels instead. Of these groups, source distribution user group is the largest and the most impacted, and any performance gain is defeated by the time spent building uv-build.

那么优点呢?我知道使用 uv-build 的两个理由。一个是与你在项目中使用的 uv 保持一致,但这其实并不重要。它只是一个后端,而 PEP 517 的核心意义在于你可以将任何后端与任何工具配合使用。你可以使用 flit-core,也可以使用 hatchling,它们都能与 uv(或任何其他前端)完美协作。另一个理由是性能,但这个论点更站不住脚。即使性能很重要,我们实际上讨论的也只是 100 毫秒左右的差异,而且这种操作执行频率很低;任何性能提升都很可能被下载 1.5 MiB 的 uv-build wheel 文件所需的时间所抵消。但这并不重要,因为实际上该后端仅由项目开发者、贡献者、CI/CD 工作流、下游打包者和源码分发用户使用;所有普通用户都直接使用 wheel。在这些群体中,源码分发用户群体最大且受影响最深,任何性能提升都被构建 uv-build 所花费的时间抵消了。