-
Notifications
You must be signed in to change notification settings - Fork 16.1k
Description
Summary
When using --incompatible_enable_proto_toolchain_resolution with a cc_binary that uses
dynamic_deps, the protobuf runtime library is not linked - even if the proto is in the
static deps and the shared library is completely unrelated to protobuf.
Minimal Reproduction
Prerequisites
- Bazel 8.x
Steps
bazel build //:main_dynamicExpected Result
Build succeeds.
Actual Result
Linker fails with undefined references to protobuf and abseil symbols:
undefined reference to 'google::protobuf::Message::kDescriptorMethods'
undefined reference to 'google::protobuf::internal::TcParser::GenericFallback(...)'
undefined reference to 'absl::lts_20250127::log_internal::MakeCheckOpString<...>(...)'
Key Findings
The issue requires both conditions:
--incompatible_enable_proto_toolchain_resolutionenableddynamic_depsattribute used (even with an unrelated shared library)
The shared library does NOT need to depend on protobuf. Simply having any dynamic_deps
with the toolchain resolution flag causes the protobuf runtime to be excluded from linking.
| Target | dynamic_deps | Result |
|---|---|---|
//:main |
No | ✓ Works |
//:main_dynamic |
Yes (unrelated) | ✗ Fails |
Analysis
When --incompatible_enable_proto_toolchain_resolution is enabled, cc_proto_library
obtains the protobuf runtime via toolchain resolution (proto_lang_toolchain.runtime)
rather than as a direct attribute dependency.
This toolchain-provided runtime is not properly propagated to the linker when the
binary uses dynamic_deps - even when the shared library has no relationship to protobuf.
Workaround
Disable the flag:
bazel build //target --noincompatible_enable_proto_toolchain_resolution
Or explicitly include @protobuf as a dependency.
Environment
- Bazel: 8.5
- Protobuf: 33.4
- rules_cc: 0.2.11
- OS: Linux
Files
| File | Description |
|---|---|
MODULE.bazel |
Bazel module dependencies |
.bazelrc |
Enables --incompatible_enable_proto_toolchain_resolution |
BUILD.bazel |
Two targets: main (works) and main_dynamic (fails) |
example.proto |
Simple proto with a Person message |
main.cc |
C++ binary that uses the proto |
unrelated_lib.cc |
Unrelated library used by the shared library |