What happened?
Summary
pep517_native_whl (in uv/private/pep517_whl/rule.bzl) resolves
the C compiler via cc_toolchain.compiler_executable and
passes it as env["CC"]. This works with legacy
cc_toolchain_config toolchains that define tool_paths, but
fails with toolchains built using the modern
@rules_cc//cc/toolchains API (cc_tool / cc_args /
cc_tool_map), which do not populate tool_paths.
Root cause
# uv/private/pep517_whl/rule.bzl (v1.11.7)
cc_toolchain = find_cc_toolchain(ctx, mandatory = False)
if cc_toolchain:
env["CC"] = cc_toolchain.compiler_executable # legacy
field
extra_inputs.append(cc_toolchain.all_files)
With a modern rules_cc toolchain (no tool_paths),
compiler_executable falls back to a composed path of
/ (e.g.
external//toolchains/gcc/gcc). That directory holds only
the toolchain definitions, not the compiler binary — the
actual binary lives in a separately-fetched repo referenced by
cc_tool.src. Build fails with:
error: command '.../toolchains/gcc/gcc' failed: No such file
or directory
Two problems, in fact:
- compiler_executable points to the definition package, not
the real binary.
- Even with the correct path, only CC is passed — none of the
toolchain's compile flags (-B, -isystem, -idirafter,
--sysroot, etc.), which the modern API expresses as cc_args,
are forwarded. A bare compiler invocation therefore can't
locate the assembler/headers/libs.
Reproduction
Use a hermetic GCC toolchain defined with the modern
@rules_cc//cc/toolchains API (cc_tool + cc_tool_map + cc_args,
no tool_paths), then build any sdist-only package with a C
extension (e.g. smbus==1.1.post2) through the uv extension.
cc_library/cc_shared_library using the same toolchain compile
fine, confirming the toolchain itself is correctly registered
and resolvable.
Suggested fix
Resolve the compiler and flags through the modern
action-config API instead of the legacy field, e.g.
cc_common.get_tool_for_action(ACTION_NAMES.c_compile, ...) for
the compiler path and cc_common.create_compile_variables +
get_memory_inefficient_command_line to expand the toolchain's
flags into the build environment. This keeps compatibility
with both legacy and modern toolchains.
Environment
- aspect_rules_py: 1.11.7
- rules_cc: 0.2.16 (modern cc/toolchains API)
- Bazel: bzlmod
Version
Development (host) and target OS/architectures:
Output of bazel --version:
Version of the Aspect rules, or other relevant rules from your
WORKSPACE or MODULE.bazel file:
Language(s) and/or frameworks involved:
How to reproduce
Any other information?
No response
What happened?
Summary
pep517_native_whl (in uv/private/pep517_whl/rule.bzl) resolves
the C compiler via cc_toolchain.compiler_executable and
passes it as env["CC"]. This works with legacy
cc_toolchain_config toolchains that define tool_paths, but
fails with toolchains built using the modern
@rules_cc//cc/toolchains API (cc_tool / cc_args /
cc_tool_map), which do not populate tool_paths.
Root cause
# uv/private/pep517_whl/rule.bzl (v1.11.7)
cc_toolchain = find_cc_toolchain(ctx, mandatory = False)
if cc_toolchain:
env["CC"] = cc_toolchain.compiler_executable # legacy
field
extra_inputs.append(cc_toolchain.all_files)
With a modern rules_cc toolchain (no tool_paths),
compiler_executable falls back to a composed path of
/ (e.g.
external//toolchains/gcc/gcc). That directory holds only
the toolchain definitions, not the compiler binary — the
actual binary lives in a separately-fetched repo referenced by
cc_tool.src. Build fails with:
error: command '.../toolchains/gcc/gcc' failed: No such file
or directory
Two problems, in fact:
the real binary.
toolchain's compile flags (-B, -isystem, -idirafter,
--sysroot, etc.), which the modern API expresses as cc_args,
are forwarded. A bare compiler invocation therefore can't
locate the assembler/headers/libs.
Reproduction
Use a hermetic GCC toolchain defined with the modern
@rules_cc//cc/toolchains API (cc_tool + cc_tool_map + cc_args,
no tool_paths), then build any sdist-only package with a C
extension (e.g. smbus==1.1.post2) through the uv extension.
cc_library/cc_shared_library using the same toolchain compile
fine, confirming the toolchain itself is correctly registered
and resolvable.
Suggested fix
Resolve the compiler and flags through the modern
action-config API instead of the legacy field, e.g.
cc_common.get_tool_for_action(ACTION_NAMES.c_compile, ...) for
the compiler path and cc_common.create_compile_variables +
get_memory_inefficient_command_line to expand the toolchain's
flags into the build environment. This keeps compatibility
with both legacy and modern toolchains.
Environment
Version
Development (host) and target OS/architectures:
Output of
bazel --version:Version of the Aspect rules, or other relevant rules from your
WORKSPACEorMODULE.bazelfile:Language(s) and/or frameworks involved:
How to reproduce
Any other information?
No response