Skip to content

fix(uv): add $(EXECROOT) make-var to anchor native sdist env paths across the backend chdir#1233

Open
sallustfire wants to merge 5 commits into
aspect-build:mainfrom
sallustfire:fix/native-sdist-workspace-relative-env-paths
Open

fix(uv): add $(EXECROOT) make-var to anchor native sdist env paths across the backend chdir#1233
sallustfire wants to merge 5 commits into
aspect-build:mainfrom
sallustfire:fix/native-sdist-workspace-relative-env-paths

Conversation

@sallustfire

@sallustfire sallustfire commented Jul 6, 2026

Copy link
Copy Markdown

pep517_native_whl (via uv.override_package(env = {...}, toolchains = [...])) expands $(VAR) make-variables in the build action's env from the toolchains it depends on. Those values are workspace-relative paths: a dependency's include dir expands to something like bazel-out/.../include, which resolves from the execroot but not from the PEP 517 backend's cwd. python -m build runs the backend with its cwd inside the unpacked sdist worktree (build_helper invokes it with cwd=<worktree>), so a workspace-relative -Ibazel-out/.../include dangles and the build fails with fatal error: '<header>' file not found, or the link can't find the dep archive.

Add a $(EXECROOT) make-variable to anchor those paths, e.g. -I$(EXECROOT)/$(DEP_INC). The execroot isn't known at analysis time, so $(EXECROOT) expands to a marker that build_helper replaces with the absolute execroot at build time, before the chdir. It's a plain text substitution rather than flag parsing, so it works for any env var and any flag form (-I, -L, -Wl,-rpath, -framework, CC, ...).

EXECROOT is reserved for this. If a toolchain in toolchains already exports it, $(EXECROOT) would expand to that value instead of the marker and silently skip anchoring, so analysis now fails with a message pointing at the collision rather than producing a confusing compile error later.

I went with an opt-in anchor rather than having build_helper detect and absolutize path-bearing flags itself: it can't reliably tell an execroot-relative path from a symbol/framework name or a worktree-relative path, can't cover every flag syntax, and would risk mangling values it doesn't need to touch.

More generally, what might be missing is some notion of a deps analog to cargo_build_script that can inspect a CcInfo provider and get the CcInfo.linking_context. This is a much bigger design question if were to be offered first-class since setuptools handles the linking, and this would all have to get flattened into LDFLAGS/extra_link_args.

Regression test

Adds uv/private/pep517_whl/tests/native_dep: a cc_library whose include dir and static archive are surfaced as make-vars (standing in for override_package(toolchains=, env=)), consumed by a small PEP 517 backend that compiles a C extension against them.

Split into a red/green pair. The test commit wires the env as plain -I$(DEP_INC) / $(DEP_LIB_A), which fails today because the backend compiles with an execroot-relative -I that dangles after the chdir. The fix commit adds $(EXECROOT) and switches the test to -I$(EXECROOT)/$(DEP_INC).

Changes are visible to end-users: yes

  • Searched for relevant documentation and updated as needed: yes ($(EXECROOT) documented on the override_package(env=) tag and the pep517_native_whl env attr)
  • Breaking change (forces users to change their own code or config): no
  • Suggested release notes appear below: yes

uv.override_package(env = {...}) now supports a $(EXECROOT) make-variable to anchor workspace-relative paths for native sdist builds (e.g. "CPPFLAGS": "-I$(EXECROOT)/$(DEP_INC)"), so they survive the PEP 517 backend's chdir into the sdist worktree.

Testing

  • bazel test //uv/private/pep517_whl/tests/native_dep:native_dep_env_test
  • buildifier --mode=check uv/private/pep517_whl/rule.bzl

…paths

Builds a native sdist whose C extension consumes an in-repo cc_library via
`override_package(env=/toolchains=)`-shaped make-vars: CPPFLAGS = `-I$(DEP_INC)`
and LDFLAGS = `$(DEP_LIB_A)`. Both expand to Bazel workspace-relative paths,
which resolve from the action execroot but not from the PEP 517 backend's cwd
inside the unpacked sdist worktree.

This commit is intentionally RED — it documents the bug. The compile fails with:

    mod.c: fatal error: 'dep.h' file not found
    cc ... -Iuv/private/pep517_whl/tests/native_dep -c mod.c

The fix follows.
…end chdir

`override_package(env = {...})` values expanded from make-vars are Bazel
workspace-relative; they resolve from the action execroot but not from the
PEP 517 backend's cwd, which `python -m build` changes into the unpacked sdist
worktree. `$(EXECROOT)` expands to a marker that build_helper replaces with the
absolute execroot at build time, so `-I$(EXECROOT)/$(DEP_INC)` is anchored
deterministically — no path detection, no per-var-name list, and it applies
uniformly to any env var (e.g. JAVA_HOME).

Fixes the regression from the previous commit.
@xangcastle xangcastle self-requested a review July 6, 2026 17:00
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

py_binary startup benchmark

Version Mean (ms) Median (ms) ± stddev vs BCR vs main Build (s)
BCR 1.11.7 (baseline) 191.975 191.153 ±6.023 34.62
HEAD main 60.974 60.864 ±0.859 -68.2% 9.75
This PR 61.483 61.417 ±0.518 -68.0% +0.8% 8.63

Measured with hyperfine --warmup 5 --runs 50 on Linux
Gate: PR vs HEAD main (threshold: 10%). BCR is shown only as a historical baseline.
Build time: cold bazel build //:bench with isolated output base, no disk cache.

sys.path quality

Version sys.path entries distinct site-packages roots duplicate realpaths
BCR 1.11.7 (baseline) 6 1 0
HEAD main 7 2 0
This PR 7 2 0

sys.path quality measured by bench_syspath inside the assembled venv. Duplicate realpaths indicate symlink redundancy; many distinct site-packages roots suggest an inefficient venv layout.

✅ No regression detected (PR is +0.8% vs HEAD main)

Adds the bzl_library target gazelle generates for defs.bzl, keeping the
BUILD file consistent with the repo's gazelle check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@xangcastle

Copy link
Copy Markdown
Member

Hi, could you resolve the conflicts?

@CLAassistant

CLAassistant commented Jul 7, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@sallustfire sallustfire force-pushed the fix/native-sdist-workspace-relative-env-paths branch from f719140 to 352f05b Compare July 7, 2026 04:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants