Skip to content

Commit fbbdcf9

Browse files
committed
select native compilers from the C++ toolchain for sdist wheel builds
1 parent fc4774a commit fbbdcf9

22 files changed

Lines changed: 1116 additions & 206 deletions

docs/uv.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ configurations, such as going from a Darwin macbook to a Linux container image
2020
using only the normal Bazel `platforms` machinery.
2121

2222
**Correct source builds** - Because uv performs package source builds as a
23-
normal part of your build, it's able to use hermetic or even source built Python
24-
toolchains in addition to Bazel-defined dependencies and C compilers. Future
25-
support for sysroots is planned. Due to its phasing, `pip.parse` is stuck doing
26-
all this non-hermetically.
23+
normal part of your build, it can use hermetic or even source-built Python
24+
toolchains in addition to Bazel-defined dependencies. Native builds select the
25+
C and C++ tools from Bazel's configured compile actions, but do not reuse their
26+
action flags or environment because PEP 517 backends own the compile and link
27+
commands. Tools that require target, sysroot, resource, wrapper, or environment
28+
configuration must provide a backend-compatible command through the package
29+
`env`; generic C++ toolchain projection is not supported. Due to its phasing,
30+
`pip.parse` is stuck doing all this non-hermetically.
2731

2832
**Editable requirements** - Uv provides an `uv.override_requirement()` tag which
2933
allows locked requirements to be replaced with 1stparty Bazel `py_library`
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
# Regression test: python-geohash (sdist-only, C++ extension) must be buildable
2-
# when native_build_toolchain_type is registered via @rules_py_tools//:all.
2+
# with native_build_toolchain_type registered via @rules_py_tools//:all.
33
#
44
# The pep517_native_whl rule requires the native_build_toolchain_type to resolve,
5-
# asserting that the exec and target platforms match. This test verifies that the
6-
# per-platform toolchain entries generated into @rules_py_tools are reachable.
5+
# asserting that the exec and target platforms match. The source patch also
6+
# introduces a C++ standard-library dependency, so linking fails if the helper
7+
# invokes the configured compiler in C rather than C++ driver mode.
78

89
load("@aspect_rules_py//py:defs.bzl", "py_test")
910

11+
exports_files(["require_cxx_driver.patch"])
12+
1013
py_test(
1114
name = "test",
1215
srcs = ["test_geohash.py"],
16+
dep_group = "uv-sdist-native-build",
1317
main = "test_geohash.py",
14-
target_compatible_with = ["@platforms//os:linux"],
1518
deps = ["@pypi_uv_sdist_native_build//python_geohash"],
1619
)
1720

1821
py_test(
1922
name = "venv_test",
2023
srcs = ["test_geohash.py"],
24+
dep_group = "uv-sdist-native-build",
2125
expose_venv = True,
2226
isolated = False,
2327
main = "test_geohash.py",
24-
target_compatible_with = ["@platforms//os:linux"],
2528
deps = ["@pypi_uv_sdist_native_build//python_geohash"],
2629
)

e2e/cases/uv-sdist-native-build/pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ name = "uv-sdist-native-build"
33
version = "0.0.0"
44
requires-python = ">=3.11"
55
dependencies = [
6+
"build==1.4.0",
67
"python-geohash",
8+
"setuptools==75.8.2",
79
]
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
diff --git a/setup.py b/setup.py
2+
--- a/setup.py
3+
+++ b/setup.py
4+
@@ -9,0 +10 @@ c1=Extension('_geohash',
5+
+c1.sources.append('src/native_probe.c')
6+
diff --git a/src/geohash.cpp b/src/geohash.cpp
7+
--- a/src/geohash.cpp
8+
+++ b/src/geohash.cpp
9+
@@ -19,0 +20,4 @@
10+
+#include <string>
11+
+
12+
+extern "C" int native_c_probe(void);
13+
+
14+
@@ -725,0 +731,6 @@
15+
+
16+
+static PyObject *py_native_probe(PyObject *, PyObject *) {
17+
+ std::string suffix = "++";
18+
+ return PyLong_FromLong(native_c_probe() + suffix.size());
19+
+}
20+
+
21+
@@ -732,0 +745 @@
22+
+ {"native_probe", py_native_probe, METH_NOARGS, "exercise C and C++ compilation and linkage"},
23+
diff --git a/src/native_probe.c b/src/native_probe.c
24+
new file mode 100644
25+
--- /dev/null
26+
+++ b/src/native_probe.c
27+
@@ -0,0 +1,3 @@
28+
+int native_c_probe(void) {
29+
+ return 40;
30+
+}

e2e/cases/uv-sdist-native-build/setup.MODULE.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ uv.project(
2222
uv.override_package(
2323
name = "python-geohash",
2424
lock = "//cases/uv-sdist-native-build:uv.lock",
25+
pre_build_patch_strip = 1,
26+
pre_build_patches = ["//cases/uv-sdist-native-build:require_cxx_driver.patch"],
2527
resource_set = "mem_4g",
2628
)
2729

e2e/cases/uv-sdist-native-build/test_geohash.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
"""Verify that python-geohash (built from sdist via pep517_native_whl) is importable."""
22

33
import geohash
4+
import _geohash
45

56

67
def test_encode_decode():
8+
assert _geohash.native_probe() == 42
79
lat, lon = 37.7749, -122.4194
810
encoded = geohash.encode(lat, lon)
911
assert encoded, "geohash.encode should return a non-empty string"

e2e/cases/uv-sdist-native-build/uv.lock

Lines changed: 13 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

e2e/snapshots/sdist_build.uv_sdist_jdk_build.jpype1.BUILD.bazel

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

e2e/snapshots/sdist_build.uv_sdist_native_build.python_geohash.BUILD.bazel

Lines changed: 3 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

uv/private/extension/defs.bzl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,9 @@ def _parse_projects(module_ctx, hub_specs):
407407
pre_build_patches = [str(p) for p in pkg_override.pre_build_patches]
408408
pre_build_patch_strip = pkg_override.pre_build_patch_strip
409409

410-
# `toolchains` / `env` on `uv.override_package` augment
411-
# the defaults baked into sdist_build's BUILD template
412-
# they don't replace them. Empty == no augmentation.
410+
# `toolchains` on `uv.override_package` extends the
411+
# defaults baked into sdist_build's BUILD template. `env`
412+
# is merged over those defaults, replacing named values.
413413
extra_toolchains = []
414414
extra_env = {}
415415
resource_set = "default"
@@ -782,7 +782,7 @@ _override_package_tag = tag_class(
782782
),
783783
"env": attr.string_dict(
784784
default = {},
785-
doc = "Extra environment variables merged into the build action's `env` dict. Values may reference $(VAR) make-variables sourced from the default CC toolchain or any extra `toolchains` listed above.",
785+
doc = "Environment variables merged over the native-build defaults. Values may reference $(VAR) make-variables sourced from the default CC toolchain or any extra `toolchains` listed above.",
786786
),
787787

788788
# Pre-build patches: applied to extracted sdist source before wheel build.

0 commit comments

Comments
 (0)