Skip to content

Add cc_proto_aspect_hint to allow copts on cc_proto_library #19706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

keith
Copy link
Contributor

@keith keith commented Dec 18, 2024

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 bazelbuild/bazel#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.

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 bazelbuild/bazel#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.
cc_proto_aspect_hint = rule(
implementation = _aspect_hint_impl,
attrs = {
"copts": attr.string_list(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can add any other attributes we want here, i imagine linkopts would be the next most sensible one, happy to add other useful ones in this PR, or just as use cases come up

@zhangskz
Copy link
Member

@comius Could you help take a look?

@zhangskz zhangskz added the 🅰️ safe for tests Mark a commit as safe to run presubmits over label Dec 18, 2024
@github-actions github-actions bot removed the 🅰️ safe for tests Mark a commit as safe to run presubmits over label Dec 18, 2024
@zhangskz zhangskz added the bazel label Dec 18, 2024
@comius
Copy link
Contributor

comius commented Feb 6, 2025

What is the motivation to set different flags for C++ on one specific proto_library?

Let me expand on bazelbuild/bazel#4446 (comment) a bit more.

Controlling C++ compilation and linking flags on generated C++ proto code is a pain at Google. We had a bunch of flags, on proto_library that could change C++ behavior, that were introduced before there were aspect_hints. And we're cleaning them up. The last most painful remaining flag is alwayslink on proto_library.

Generated C++ code should always be "compilable/linkable" with the same set of flags. Let's say it's possible to set flags on a specific library. What happens when the generated code changes and because of it that library is broken?

@keith
Copy link
Contributor Author

keith commented Feb 14, 2025

What is the motivation to set different flags for C++ on one specific proto_library?

I might be misunderstanding, but that wasn't my goal, it was just to be able to set custom flags on it at all, while also solving the concern of those flags not propagating to dependent cc_proto_library targets.

Generated C++ code should always be "compilable/linkable" with the same set of flags.

If I'm understanding you correctly I don't disagree, but the problem today is the only "same set of flags" is the default flags, and those aren't customizable. I imagine in many cases users would want all protos to use the same set of flags, just that differ from the defaults. For example in the upstream issue there is a windows specific flag a user wanted to apply to their protos, that couldn't be applied to all compiles

Let's say it's possible to set flags on a specific library. What happens when the generated code changes and because of it that library is broken?

I think the same could be said for the opposite direction? As in my default flags contain -Werror=some-warning and now the generated code violates that warning, the problem is today we don't have the tools to affect these on the proto at all.

@comius
Copy link
Contributor

comius commented Feb 17, 2025

Generated C++ code should always be "compilable/linkable" with the same set of flags.

If I'm understanding you correctly I don't disagree, but the problem today is the only "same set of flags" is the default flags, and those aren't customizable. I imagine in many cases users would want all protos to use the same set of flags, just that differ from the defaults. For example in the upstream issue there is a windows specific flag a user wanted to apply to their protos, that couldn't be applied to all compiles

It's true that flags for compiling protos aren't customizable. Do you have examples of systems where that's needed? I'm asking because protobuf repo is already tested on wide variety of platforms and compilers. I guess there must be something missing.

Setting them somewhere on proto_lang_toolchain and passing them into cc_proto_compile_and_link via user_compile_flags paratmeter should work.

Since protobuf team is the owner, any such design decisions need to be run through them.

Let's say it's possible to set flags on a specific library. What happens when the generated code changes and because of it that library is broken?

I think the same could be said for the opposite direction? As in my default flags contain -Werror=some-warning and now the generated code violates that warning, the problem is today we don't have the tools to affect these on the proto at all.

Yes the argument works in reverse. protobuf should be controlling what copts are set for generated code.

@keith
Copy link
Contributor Author

keith commented Feb 18, 2025

It seems like the first case users normally hit is differing warning flags. I imagine centralizing that in protobuf itself is a tough since those vary depending on project and compiler.

Based on the thread linked above it seems like there's a second category of flags that are actually required, such as:

Large protos may require the -Wa,-mbig-obj copt on Windows, but it is not always possible to use that flag globally (e.g. if also compiling go code).

@vam-google
Copy link

vam-google commented Apr 20, 2025

@comius

It's true that flags for compiling protos aren't customizable. Do you have examples of systems where that's needed?

I would desperately need it for one specific case (which of itself needed to upgrade protobuf depencency for Google's ML stack, including TensorFlow, JAX and XLA): need to support Window's windows dymaic linking (__declspec(dllexport)/__declspec(dllexport) directives in particular). Specifically cc_proto_library() targets which go in a dynamic library need to be compiled with:

local_defines=["PROTOBUF_USE_DLLS", "LIBPROTOBUF_EXPORT"]

to get __declspec(dllexport),

but those whoe depnd on those cc_proto_library targets (and include generated .pb.h headers) need to have:

local_defines=["PROTOBUF_USE_DLLS"]

to get __declspec(dllimport)

Need to have different __declspec directive dependin on which side compiled code is (provider or a consumer of a dynamic library) is at the very core design of windows dynamic linking model, the __declspec(dllimport) is absolutely necessary on consumer side (i.e. .def file would nos suffice) in case of DATA exports (i.e. variables, which unfrotunately protobuf does), as without it consumer code is not able to understand that the actual exported thing is a pointer, not an actual value, and code segfaults very easily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants