Skip to content

Commit 11c7312

Browse files
thesayyncopybara-github
authored andcommitted
fix: cc_toolchain should prefer protoc when prebuilt flag is flipped. (#25168)
cc_toolchain now respects the prefer_prebuilt_protoc flag. When the flag is set to true, the toolchain uses the full protoc binary instead of protoc_minimal, enabling prebuilt protoc support. Follow up to this is to have minimal protoc released as an artifact and use that. Closes #25168 COPYBARA_INTEGRATE_REVIEW=#25168 from thesayyn:cc_toolchain_prebuilt 30451be FUTURE_COPYBARA_INTEGRATE_REVIEW=#25168 from thesayyn:cc_toolchain_prebuilt 30451be PiperOrigin-RevId: 853356620
1 parent c404f03 commit 11c7312

File tree

6 files changed

+111
-5
lines changed

6 files changed

+111
-5
lines changed

BUILD.bazel

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,13 @@ proto_lang_toolchain(
566566
command_line = "--cpp_out=$(OUT)",
567567
plugin = "//src/google/protobuf/compiler/cpp:protoc-gen-cpp",
568568
plugin_format_flag = "--plugin=protoc-gen-cpp=%s",
569-
protoc_minimal_do_not_use = "//src/google/protobuf/compiler:protoc_minimal",
569+
protoc_minimal_do_not_use = select({
570+
# Set minimal protoc if prefer_prebuilt_protoc.flag_set is true since a prebuilt for protoc_minimal is not available
571+
# TODO: Add a flag to switch between minimal and full protoc with proto_lang_toolchain once we have a minimal protoc binary.
572+
# Setting this attribute to None will make the toolchain to pick the full protoc binary.
573+
"//bazel/toolchains:prefer_prebuilt_protoc.flag_set": None,
574+
"//conditions:default": "//src/google/protobuf/compiler:protoc_minimal",
575+
}),
570576
runtime = "//src/google/protobuf",
571577
visibility = ["//visibility:public"],
572578
)

bazel/tests/BUILD

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
12
load("//bazel:proto_descriptor_set.bzl", "proto_descriptor_set")
23
load("//bazel:proto_library.bzl", "proto_library")
34
load(":bazel_proto_library_tests.bzl", "bazel_proto_library_test_suite")
5+
load(":cc_toolchain_tests.bzl", "cc_toolchain_test_suite")
46
load(":java_proto_library_tests.bzl", "java_proto_library_test_suite")
57
load(":proto_common_check_collocated_tests.bzl", "proto_common_check_collocated_test_suite")
68
load(":proto_common_compile_tests.bzl", "proto_common_compile_test_suite")
@@ -19,6 +21,8 @@ proto_common_check_collocated_test_suite(name = "proto_common_check_collocated_t
1921

2022
bazel_proto_library_test_suite(name = "bazel_proto_library_test_suite")
2123

24+
cc_toolchain_test_suite(name = "cc_toolchain_test_suite")
25+
2226
java_proto_library_test_suite(name = "java_proto_library_test_suite")
2327

2428
proto_library(

bazel/tests/cc_toolchain_tests.bzl

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Protocol Buffers - Google's data interchange format
2+
# Copyright 2025 Google Inc. All rights reserved.
3+
#
4+
# Use of this source code is governed by a BSD-style
5+
# license that can be found in the LICENSE file or at
6+
# https://developers.google.com/open-source/licenses/bsd
7+
"""Tests for cc_toolchain prebuilt protoc configuration."""
8+
9+
load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite")
10+
load("@rules_testing//lib:truth.bzl", "matching")
11+
load("@rules_testing//lib:util.bzl", "util")
12+
load("//bazel:proto_library.bzl", "proto_library")
13+
load("//bazel/tests/testdata:compile_rule.bzl", "compile_rule")
14+
15+
_PREFER_PREBUILT_PROTOC = str(Label("//bazel/toolchains:prefer_prebuilt_protoc"))
16+
17+
def cc_toolchain_test_suite(name):
18+
test_suite(
19+
name = name,
20+
tests = [
21+
_test_cc_toolchain_uses_full_protoc_when_prefer_prebuilt_flag_set,
22+
_test_cc_toolchain_uses_protoc_minimal_by_default,
23+
],
24+
)
25+
26+
def _test_cc_toolchain_uses_full_protoc_when_prefer_prebuilt_flag_set(name):
27+
util.helper_target(
28+
proto_library,
29+
name = name + "_proto",
30+
srcs = ["A.proto"],
31+
)
32+
util.helper_target(
33+
compile_rule,
34+
name = name + "_compile",
35+
proto_dep = ":" + name + "_proto",
36+
toolchain = "//:cc_toolchain",
37+
)
38+
39+
analysis_test(
40+
name = name,
41+
target = name + "_compile",
42+
impl = _test_cc_toolchain_uses_full_protoc_when_prefer_prebuilt_flag_set_impl,
43+
config_settings = {_PREFER_PREBUILT_PROTOC: True},
44+
)
45+
46+
def _test_cc_toolchain_uses_full_protoc_when_prefer_prebuilt_flag_set_impl(env, target):
47+
# Find the compile action
48+
action = env.expect.that_target(target).action_named("GenProto")
49+
50+
# When prefer_prebuilt_protoc is True, protoc_minimal_do_not_use is None,
51+
# so the cc_toolchain should use the full protoc (not protoc_minimal).
52+
# The protoc path should end with "/protoc" not contain "protoc_minimal"
53+
action.argv().contains_predicate(matching.str_matches("*/protoc"))
54+
action.argv().not_contains_predicate(matching.str_matches("*protoc_minimal*"))
55+
56+
def _test_cc_toolchain_uses_protoc_minimal_by_default(name):
57+
util.helper_target(
58+
proto_library,
59+
name = name + "_proto",
60+
srcs = ["A.proto"],
61+
)
62+
util.helper_target(
63+
compile_rule,
64+
name = name + "_compile",
65+
proto_dep = ":" + name + "_proto",
66+
toolchain = "//:cc_toolchain",
67+
)
68+
69+
analysis_test(
70+
name = name,
71+
target = name + "_compile",
72+
impl = _test_cc_toolchain_uses_protoc_minimal_by_default_impl,
73+
)
74+
75+
def _test_cc_toolchain_uses_protoc_minimal_by_default_impl(env, target):
76+
# Find the compile action
77+
action = env.expect.that_target(target).action_named("GenProto")
78+
79+
# By default (prefer_prebuilt_protoc is False), protoc_minimal_do_not_use is set,
80+
# so the cc_toolchain should use protoc_minimal.
81+
action.argv().contains_predicate(matching.str_matches("*protoc_minimal*"))

bazel/toolchains/BUILD

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ bool_flag(
5353
config_setting(
5454
name = "prefer_prebuilt_protoc.flag_set",
5555
flag_values = {":prefer_prebuilt_protoc": "true"},
56-
visibility = ["//bazel/private/toolchains/prebuilt:__pkg__"],
56+
visibility = [
57+
"//bazel/private/toolchains/prebuilt:__pkg__",
58+
# Needed by cc_toolchain to switch between minimal and full protoc
59+
"//:__pkg__",
60+
],
5761
)
5862

5963
# The public API users set to disable the validation action failing.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Simulate a non-functional CC toolchain
2-
common --per_file_copt=external/.*protobuf.*@--THIS_CC_TOOLCHAIN_IS_BROKEN
3-
common --host_per_file_copt=external/.*protobuf.*@--THIS_CC_TOOLCHAIN_IS_BROKEN
2+
common --per_file_copt=external/.*protobuf.*/src/google/protobuf/compiler/main.cc@--THIS_CC_TOOLCHAIN_IS_BROKEN
3+
common --host_per_file_copt=external/.*protobuf.*/src/google/protobuf/compiler/main.cc@--THIS_CC_TOOLCHAIN_IS_BROKEN
44
# But, users should be able to use pre-built protoc toolchains instead.
55
common --incompatible_enable_proto_toolchain_resolution
6-
common --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc
6+
common --@com_google_protobuf//bazel/toolchains:prefer_prebuilt_protoc
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1+
load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library")
12
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
23

34
proto_library(
45
name = "empty_proto",
56
srcs = ["empty.proto"],
67
)
8+
9+
cc_proto_library(
10+
name = "cc_empty_proto",
11+
# We already have a anaylsis test that asserts that the cc_proto_library
12+
# uses the correct prebuilt toolchain, this cc_proto_library will never
13+
# compile since the prebuilt toolchain is always behind the HEAD therefore
14+
# will end up in version skew compilation errors.
15+
tags = ["manual"],
16+
deps = [":empty_proto"],
17+
)

0 commit comments

Comments
 (0)