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

使用Bazel构建依赖C库的Rust crate遇CMake报错:原因与解决

Bazel构建依赖C库的Rust Crate时CMake找不到的问题解决

问题描述

尝试用Bazel的rust_rules(尤其是crate_universe规则)构建依赖rdkafka和paho-mqtt的Rust crate,Cargo.toml依赖如下:

[dependencies]
serde = { version = "1.0.163", features = ["derive"] }
chrono = { version = "0.4.26", features = ["serde"] }
uuid = { version = "1.3.3", features = ["v7", "serde"] }
rdkafka = { version = "0.31", features = ["cmake-build"] }
paho-mqtt = { version = "0.11" }

Bazel WORKSPACE配置:

crates_repository(
    name = "crate_index",
    cargo_lockfile = "//my-crate:Cargo.lock",
    lockfile = "//my-crate:Cargo.Bazel.lock",
    manifests = ["//my-crate:Cargo.toml"],
    annotations = {
        "uuid": [crate.annotation(
            rustc_flags = ["--cfg=uuid_unstable"],
        )],
    },
)

load("@crate_index//:defs.bzl", "crate_repositories")

crate_repositories()

BUILD文件配置:

load("@crate_index//:defs.bzl", "all_crate_deps")
load("@rules_rust//rust:defs.bzl", "rust_library")

rust_library(
    name = "my-crate",
    srcs = glob(["src/**/*.rs"]),
    deps = all_crate_deps(
        normal = True,
    ),
)

运行bazel build //my-crate时触发错误:

--stderr:
Building and linking librdkafka statically
CMake Error: Could not find CMAKE_ROOT !!!
CMake has most likely not been installed correctly.
Modules directory not found in

CMake Error: Error executing cmake::LoadCache(). Aborting.

thread 'main' panicked at '
command did not execute successfully, got: exit status: 1

该错误同时出现在rdkafka和paho-mqtt构建过程中,移除rdkafka的cmake-build特性后问题依旧。

已尝试操作

  • cargo build构建成功,排除系统CMake安装问题
  • 尝试export CMAKE_ROOT=/path、Bazel运行参数--action_env=CMAKE_ROOT=/path及use_default_shell_env=True,均未解决

补充信息

  • 操作系统:Arch
  • Bazel版本:6.2.1
  • CMake版本:3.26.4
  • Rust工具链配置:
rust_register_toolchains(
    edition = "2021",
    versions = [
        "1.70.0"
    ],
)

报错原因

Bazel默认启用沙箱构建环境,会隔离大部分系统环境变量和路径。即使系统已安装CMake,rdkafka和paho-mqtt的build.rs在沙箱中无法访问系统的CMake可执行文件及相关环境变量(比如CMAKE_ROOT),导致CMake初始化失败。

另外,crate_universe默认不会自动处理依赖系统C库的Rust crate,需要显式配置让构建过程能找到系统预编译库,或引入Bazel的CMake工具链。

解决方法(避免编译librdkafka)

方案1:改用系统预编译的C库

修改Cargo.toml,让rdkafka和paho-mqtt直接链接系统已安装的库,跳过源码编译:

[dependencies]
# 其他依赖保持不变
rdkafka = { version = "0.31", features = ["system-librdkafka"] } # 替换cmake-build为system-librdkafka
paho-mqtt = { version = "0.11", features = ["system"] } # 启用system特性链接系统库

然后更新Bazel的crates_repository配置,添加注解让build.rs能找到系统库路径:

crates_repository(
    name = "crate_index",
    cargo_lockfile = "//my-crate:Cargo.lock",
    lockfile = "//my-crate:Cargo.Bazel.lock",
    manifests = ["//my-crate:Cargo.toml"],
    annotations = {
        "uuid": [crate.annotation(
            rustc_flags = ["--cfg=uuid_unstable"],
        )],
        # 给rdkafka传递系统库链接参数
        "rdkafka": [crate.annotation(
            build_env = {
                "RDKAFKA_LIB_DIR": "/usr/lib", # 根据Arch系统的librdkafka路径调整
                "RDKAFKA_INCLUDE_DIR": "/usr/include",
            },
        )],
        # 给paho-mqtt传递系统库链接参数
        "paho-mqtt": [crate.annotation(
            build_env = {
                "PAHO_MQTT_C_LIB_DIR": "/usr/lib",
                "PAHO_MQTT_C_INCLUDE_DIR": "/usr/include",
            },
        )],
    },
)

最后重新生成Bazel锁文件:

bazel run @rules_rust//crate_universe:generate_lockfile -- --manifest-path=my-crate/Cargo.toml --output=my-crate/Cargo.Bazel.lock

方案2:让Bazel沙箱访问系统CMake(若需编译源码)

如果必须编译librdkafka源码,需要在Bazel中引入CMake工具链,并允许构建过程访问系统环境:

  1. 在WORKSPACE中加载Bazel的CMake规则:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "rules_foreign_cc",
    sha256 = "d5a2ad2b08c7d38f996907a00540741c368f224a6b51d4f37d15b555059e4405",
    url = "https://github.com/bazelbuild/rules_foreign_cc/releases/download/0.9.0/rules_foreign_cc-0.9.0.tar.gz",
)

load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")

rules_foreign_cc_dependencies()
  1. 在crates_repository中添加注解,给rdkafka和paho-mqtt传递CMake路径:
crates_repository(
    # 其他配置不变
    annotations = {
        # 其他注解不变
        "rdkafka": [crate.annotation(
            build_env = {
                "CMAKE": "/usr/bin/cmake", # 系统CMake路径
            },
        )],
        "paho-mqtt": [crate.annotation(
            build_env = {
                "CMAKE": "/usr/bin/cmake",
            },
        )],
    },
)

同时构建时需要允许Bazel访问系统环境:

bazel build //my-crate --action_env=PATH=/usr/bin:$PATH --use_default_shell_env

此方案会编译librdkafka源码,不符合简化配置需求,优先推荐方案1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:47:03