From dceea6a78bd7d2c74c1acdc09e32b055ca472c0e Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Tue, 17 Dec 2024 16:28:56 -0800 Subject: [PATCH] Add cc_proto_aspect_hint to allow copts on cc_proto_library This new `cc_proto_aspect_hint` allows users to specify `copts` that are then used when compiling the generated C++ code. This is a potential solution to https://github.com/bazelbuild/bazel/issues/4446 In that discussion the primary concern was that if you have multiple `cc_proto_library` targets that depend on the same `proto_library` targets, if the `copts` was part of `cc_proto_library` you'd have to be sure to duplicate that to all `cc_proto_library` targets in the dependency tree. Using the relatively new `aspect_hints` functionality in bazel we can instead attach that info to the `proto_library` target itself, without adding C++ specific attributes to the `proto_library` rule. --- bazel/cc_proto_library.bzl | 8 +++- bazel/private/bazel_cc_proto_library.bzl | 55 ++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/bazel/cc_proto_library.bzl b/bazel/cc_proto_library.bzl index e1d4ad41444b6..9b27cc71d8511 100644 --- a/bazel/cc_proto_library.bzl +++ b/bazel/cc_proto_library.bzl @@ -1,6 +1,6 @@ """cc_proto_library rule""" -load("//bazel/private:bazel_cc_proto_library.bzl", _cc_proto_library = "cc_proto_library") # buildifier: disable=bzl-visibility +load("//bazel/private:bazel_cc_proto_library.bzl", _cc_proto_aspect_hint = "cc_proto_aspect_hint", _cc_proto_library = "cc_proto_library") # buildifier: disable=bzl-visibility def cc_proto_library(**kwattrs): # Only use Starlark rules when they are removed from Bazel @@ -8,3 +8,9 @@ def cc_proto_library(**kwattrs): _cc_proto_library(**kwattrs) else: native.cc_proto_library(**kwattrs) # buildifier: disable=native-cc-proto + +def cc_proto_aspect_hint(**kwattrs): + if hasattr(native, "cc_proto_library"): + fail("cc_proto_aspect_hint requires bazel 8.x+") + else: + _cc_proto_aspect_hint(**kwattrs) diff --git a/bazel/private/bazel_cc_proto_library.bzl b/bazel/private/bazel_cc_proto_library.bzl index 3dba4880ac791..58df54e8dc2f4 100644 --- a/bazel/private/bazel_cc_proto_library.bzl +++ b/bazel/private/bazel_cc_proto_library.bzl @@ -18,6 +18,12 @@ _CC_PROTO_TOOLCHAIN = Label("//bazel/private:cc_toolchain_type") _ProtoCcFilesInfo = provider(fields = ["files"], doc = "Provide cc proto files.") _ProtoCcHeaderInfo = provider(fields = ["headers"], doc = "Provide cc proto headers.") +_ProtoCcAspectHintInfo = provider( + doc = "Provide extra C++ specific info to proto compile actions", + fields = { + "copts": "Compiler flags to pass to the C++ compile acitons for the generated proto sources", + }, +) def _get_output_files(actions, proto_info, suffixes): result = [] @@ -87,6 +93,11 @@ def _aspect_impl(target, ctx): else: # shouldn't generate code header_provider = _ProtoCcHeaderInfo(headers = depset()) + copts = [] + for hint in getattr(ctx.rule.attr, "aspect_hints", []): + if _ProtoCcAspectHintInfo in hint: + copts.extend(hint[_ProtoCcAspectHintInfo].copts) + proto_common.compile( actions = ctx.actions, proto_info = proto_info, @@ -107,6 +118,7 @@ def _aspect_impl(target, ctx): headers = headers, textual_hdrs = textual_hdrs, strip_include_prefix = _get_strip_include_prefix(ctx, proto_info), + user_compile_flags = copts, ) return [ @@ -196,3 +208,46 @@ rules to generate C++ code for.""", provides = [CcInfo], toolchains = toolchains.use_toolchain(_CC_PROTO_TOOLCHAIN), ) + +def _aspect_hint_impl(ctx): + return _ProtoCcAspectHintInfo(copts = ctx.attr.copts) + +cc_proto_aspect_hint = rule( + implementation = _aspect_hint_impl, + attrs = { + "copts": attr.string_list(), + }, + doc = """ +

+cc_proto_aspect_hint allows you to custom how generated C++ code compiles. +

+ +

+copts custom compiler flags to pass to the C++ compiler. +

+ +

+Example: +

+ +
+
+cc_proto_library(
+    name = "foo_cc_proto",
+    deps = [":foo_proto"],
+)
+
+cc_proto_aspect_hint(
+    name = "custom_cc_flags",
+    copts = ["-Wno-all"],
+)
+
+proto_library(
+    name = "foo_proto",
+    srcs = ["foo.proto"],
+    aspect_hints = [":custom_cc_flags"],
+)
+
+
+""", +)