mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Build backend: Add direct builds to the resolver and installer (#9621)
This is like #9556, but at the level of all other builds, including the resolver and installer. Going through PEP 517 to build a package is slow, so when building a package with the uv build backend, we can call into the uv build backend directly instead: No temporary virtual env, no temp venv sync, no python subprocess calls, no uv subprocess calls. This fast path is gated through preview. Since the uv wheel is not available at test time, I've manually confirmed the feature by comparing `uv venv && cargo run pip install . -v --preview --reinstall .` and `uv venv && cargo run pip install . -v --reinstall .`. When hacking the preview so that the python uv build backend works without the setting the direct build also (wheel built with `maturin build --profile profiling`), we can see the perfomance difference: ``` $ hyperfine --prepare "uv venv" --warmup 3 \ "UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview" \ "target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/" Benchmark 1: UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview Time (mean ± σ): 33.1 ms ± 2.5 ms [User: 25.7 ms, System: 13.0 ms] Range (min … max): 29.8 ms … 47.3 ms 73 runs Benchmark 2: target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/ Time (mean ± σ): 115.1 ms ± 4.3 ms [User: 54.0 ms, System: 27.0 ms] Range (min … max): 109.2 ms … 123.8 ms 25 runs Summary UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview ran 3.48 ± 0.29 times faster than target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/ ``` Do we need a global option to disable the fast path? There is one for `uv build` because `--force-pep517` moves `uv build` much closer to a `pip install` from source that a user of a library would experience (See discussion at #9610), but uv overall doesn't really make guarantees around the build env of dependencies, so I consider the direct build a valid option. Best reviewed commit-by-commit, only the last commit is the actual implementation, while the preview mode introduction is just a refactoring touching too many files.
This commit is contained in:
parent
566c178276
commit
6ed6fc108e
29 changed files with 304 additions and 86 deletions
|
@ -18,6 +18,7 @@ workspace = true
|
|||
[dependencies]
|
||||
uv-cache = { workspace = true }
|
||||
uv-configuration = { workspace = true }
|
||||
uv-distribution-filename = { workspace = true }
|
||||
uv-distribution-types = { workspace = true }
|
||||
uv-git = { workspace = true }
|
||||
uv-normalize = { workspace = true }
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::future::Future;
|
||||
use std::path::{Path, PathBuf};
|
||||
use uv_distribution_filename::DistFilename;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
|
@ -115,12 +116,27 @@ pub trait BuildContext {
|
|||
source: &'a Path,
|
||||
subdirectory: Option<&'a Path>,
|
||||
install_path: &'a Path,
|
||||
version_id: Option<String>,
|
||||
version_id: Option<&'a str>,
|
||||
dist: Option<&'a SourceDist>,
|
||||
sources: SourceStrategy,
|
||||
build_kind: BuildKind,
|
||||
build_output: BuildOutput,
|
||||
) -> impl Future<Output = Result<Self::SourceDistBuilder>> + 'a;
|
||||
|
||||
/// Build by calling directly into the uv build backend without PEP 517, if possible.
|
||||
///
|
||||
/// Checks if the source tree uses uv as build backend. If not, it returns `Ok(None)`, otherwise
|
||||
/// it builds and returns the name of the built file.
|
||||
///
|
||||
/// `version_id` is for error reporting only.
|
||||
fn direct_build<'a>(
|
||||
&'a self,
|
||||
source: &'a Path,
|
||||
subdirectory: Option<&'a Path>,
|
||||
output_dir: &'a Path,
|
||||
build_kind: BuildKind,
|
||||
version_id: Option<&'a str>,
|
||||
) -> impl Future<Output = Result<Option<DistFilename>>> + 'a;
|
||||
}
|
||||
|
||||
/// A wrapper for `uv_build::SourceBuild` to avoid cyclical crate dependencies.
|
||||
|
@ -140,7 +156,9 @@ pub trait SourceBuildTrait {
|
|||
///
|
||||
/// For PEP 517 builds, this calls `build_wheel`.
|
||||
///
|
||||
/// Returns the filename of the built wheel inside the given `wheel_dir`.
|
||||
/// Returns the filename of the built wheel inside the given `wheel_dir`. The filename is a
|
||||
/// string and not a `WheelFilename` because the on disk filename might not be normalized in the
|
||||
/// same way as uv would.
|
||||
fn wheel<'a>(&'a self, wheel_dir: &'a Path) -> impl Future<Output = Result<String>> + 'a;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue