使用Bazel构建时,不兼容平台上的目标为何未被跳过?
问题:指定不兼容平台构建时Bazel未跳过Rust目标反而报错
根据Bazel官方文档,当目标与指定平台不兼容时应被跳过。但执行bazel build --platforms=//:qnx-x86_64 //...时,标记为仅兼容Linux的Rust目标未被跳过,反而出现工具链匹配错误:
ERROR: ./hello_world_rust/BUILD:3:12: While resolving toolchains for target //hello_world_rust:hello_world_rust: No matching toolchains found for types @bazel_tools//tools/cpp:toolchain_type, @rules_rust//rust:toolchain_type.
环境:bazelisk + Bazel 6.1.0,主机系统为Ubuntu。
相关文件内容
./BUILD
platform( name = "qnx-x86_64", constraint_values = [ "@platforms//os:qnx", "@platforms//cpu:x86_64", ], visibility = ["//visibility:public"], )
./WORKSPACE
load("//:repositories.bzl", "load_bazel_skylib_repositories", "load_rules_rust_repositories") load_bazel_skylib_repositories() load_rules_rust_repositories() load("//:setup.bzl", "setup_rules_rust_repositories") setup_rules_rust_repositories()
./hello_world_rust/BUILD
load("@rules_rust//rust:defs.bzl", "rust_binary") rust_binary( name = "hello_world_rust", srcs = ["src/main.rs"], edition = "2021", target_compatible_with = [ "@platforms//os:linux", "@platforms//cpu:x86_64", ], )
./hello_world_rust/Cargo.toml
[package] name = "hello_world_rust" version = "0.1.0" edition = "2021"
./hello_world_rust/src/main.rs
fn main() { println!("Hello, World!"); }
./repositories.bzl
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") VERSION = "1.3.0" def load_bazel_skylib_repositories(): maybe( name = "bazel_skylib", repo_rule = http_archive, urls = [ "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/{version}/bazel-skylib-{version}.tar.gz".format(version = VERSION), "https://github.com/bazelbuild/bazel-skylib/releases/download/{version}/bazel-skylib-{version}.tar.gz".format(version = VERSION), ], sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506", ) RULES_RUST_VERSION = "0.18.0" def load_rules_rust_repositories(): maybe( name = "rules_rust", repo_rule = http_archive, sha256 = "2466e5b2514772e84f9009010797b9cd4b51c1e6445bbd5b5e24848d90e6fb2e", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/rules_rust/releases/download/{version}/rules_rust-v{version}.tar.gz".format(version = RULES_RUST_VERSION), "https://github.com/bazelbuild/rules_rust/releases/download/{version}/rules_rust-v{version}.tar.gz".format(version = RULES_RUST_VERSION), ], )
./setup.bzl
load( "@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains", "rust_repositories", ) def setup_rules_rust_repositories(): rules_rust_dependencies() rust_repositories() rust_register_toolchains(versions = ["1.61.0"], edition = "2021")
原因分析
Bazel的工具链解析逻辑优先级高于目标兼容性检查:先检查是否存在适配指定平台的工具链,再判断目标是否与平台兼容。这里指定QNX平台后,Bazel找不到对应的Rust和C++工具链,直接在工具链解析阶段报错,根本没走到跳过不兼容目标的步骤。
解决方案
方案1:注册QNX适配工具链(需实际构建QNX目标)
如果需要为QNX平台构建目标,需补充适配的工具链。对于rules_rust,可通过rust_register_toolchains的target_triples参数指定QNX的目标三元组(如x86_64-unknown-nto-qnx710),同时确保本地有对应版本的Rust工具链。
方案2:启用提前兼容性检查(仅跳过不兼容目标)
添加--incompatible_enable_skip_target_compatibility_check构建标志,让Bazel先判断目标是否兼容平台,再解析工具链。不兼容的目标会直接被跳过,不会触发工具链错误。可以在命令中直接使用:
bazel build --platforms=//:qnx-x86_64 --incompatible_enable_skip_target_compatibility_check //...
也可以在项目根目录的.bazelrc中全局配置:
build --incompatible_enable_skip_target_compatibility_check
方案3:直接排除不兼容目标
在构建命令中用--exclude_patterns跳过特定目标:
bazel build --platforms=//:qnx-x86_64 //... --exclude_patterns=//hello_world_rust:*
内容的提问来源于stack exchange,提问作者nnnmmm
相关产品推荐
相关产品推荐

