You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bazel的py_library中依赖tiny-cuda-nn的CMake构建目标?

问题描述

我尝试用Bazel封装tiny-cuda-nn作为其他项目的依赖,该项目是CMake项目但提供Python绑定,常规安装方式为执行以下pip命令:

pip install git+https://github.com/NVlabs/tiny-cuda-nn/#subdirectory=bindings/torch

我已在WORKSPACE文件中通过new_git_repository拉取了tiny-cuda-nn仓库,配置如下:

load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")

_ALL_CONTENT = """\
filegroup(
    name = "all_srcs",
    srcs = glob(["**"]),
    visibility = ["//visibility:public"],
)
"""

new_git_repository(
    name = "tinycudann_repo",
    branch = "master",
    build_file_content = _ALL_CONTENT,
    recursive_init_submodules = True,
    remote = "git@github.com:NVlabs/tiny-cuda-nn.git",
)

在./third_party/tinycudann目录下的BUILD.bazel文件中,我定义了cmake目标built_and_installed_tinycudann和py_library目标tinycudann_py_lib,并将cmake目标作为py_library的依赖,配置如下:

load("@rules_python//python:pip.bzl", "compile_pip_requirements")

# Update requirements based on requirements_lock.in
compile_pip_requirements(
    name = "requirements_lock",
    src = "requirements_lock.in",
    requirements_txt = "requirements_lock.txt",
)

load("@rules_python//python:defs.bzl", "py_library")
load("@pip_deps_nerfstudio//:requirements.bzl", "requirement")

# First, build tinycudann.
load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")

cmake(
    name = "built_and_installed_tinycudann",
    install = True,
    lib_source = "@tinycudann_repo//:all_srcs",
    out_binaries = [
        "mlp_learning_an_image",
        "bench_image_ours",
    ],
    out_static_libs = [
        "libtiny-cuda-nn.a",
    ],
)

py_library(
    name = "tinycudann_py_lib",
    srcs = ["@tinycudann_repo//:all_srcs"],
    visibility = ["//visibility:public"],
    deps = [
        ":built_and_installed_tinycudann",
        requirement("torch"),
    ],
)

requirements_lock.in文件仅包含torch==2.4.0,requirements_lock.txt通过bazel run命令生成。预期其他Python脚本可通过依赖//third_party/tinycudann:tinycudann_py_lib来使用该库。

单独构建cmake目标时会正常编译(耗时约15分钟),但构建py_library仅需1秒,未触发CMake编译;下游引用该库的脚本报错:AttributeError: module 'tinycudann' has no attribute 'Encoding'。

我的核心疑问有两点:

  1. 为何py_library未触发其依赖的cmake目标构建?
  2. 即便能触发构建,py_library是否是使用该CMake构建项目的正确方式?

解决方案

1. py_library未触发cmake构建的原因

Bazel的依赖触发逻辑是仅当目标实际依赖对方的输出文件时,才会触发依赖构建。你的py_library仅将built_and_installed_tinycudann列为deps,但srcs直接引用了原始仓库的未编译文件,没有关联cmake生成的任何产物(比如编译后的Python绑定模块)。Bazel分析后判定py_library不需要cmake目标的输出,因此跳过了构建流程。

简单来说:deps只是声明了逻辑依赖,但没有实际的文件依赖关系,Bazel的增量构建机制会忽略这种无输出关联的依赖。

2. 正确的构建方式:关联cmake生成的Python绑定

tiny-cuda-nn的Python绑定是编译生成的二进制扩展模块(如.so/.pyd文件),并非纯Python源码,因此不能直接用py_library引用原始仓库文件。需要调整构建流程,让Bazel识别并使用cmake生成的绑定产物:

步骤1:修改cmake目标,确保生成并安装Python绑定

tiny-cuda-nn的Python绑定在bindings/torch目录下生成,需在cmake配置中开启绑定构建,并指定安装路径:

cmake(
    name = "built_and_installed_tinycudann",
    install = True,
    lib_source = "@tinycudann_repo//:all_srcs",
    # 指定构建参数,开启Python绑定并关闭不必要的示例编译
    cmake_options = [
        "-DCMAKE_INSTALL_PREFIX=$(BINDIR)/install",
        "-DTINY_CUDA_NN_BUILD_PYTHON_BINDINGS=ON",
        "-DTINY_CUDA_NN_BUILD_EXAMPLES=OFF",
    ],
    # 声明输出的Python二进制模块(根据系统调整后缀,如Windows下为.pyd)
    out_shared_libs = [
        "tinycudann/tinycudann.so",
    ],
)

步骤2:用py_library引用cmake生成的绑定模块

不能直接使用原始仓库源码,需引用cmake安装后的Python模块目录,并将二进制文件加入data确保运行时可访问:

py_library(
    name = "tinycudann_py_lib",
    # 引用cmake生成的Python模块目录
    srcs = [":built_and_installed_tinycudann"],
    # 将二进制扩展模块加入data,确保Bazel运行时将其放入Python的sys.path
    data = [":built_and_installed_tinycudann"],
    visibility = ["//visibility:public"],
    deps = [
        requirement("torch"),
    ],
)

关键说明

  • tiny-cuda-nn的Python绑定是编译产物,原始仓库中没有可直接导入的纯Python模块,必须通过cmake构建后才能使用。
  • py_library的data属性必须包含二进制扩展模块,否则运行时Python无法找到该模块。

内容的提问来源于stack exchange,提问作者Chuck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:39:59