Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
6.5 KiB
141 lines
6.5 KiB
# Protocol Buffers - Google's data interchange format |
|
# Copyright 2024 Google Inc. All rights reserved. |
|
# |
|
# Use of this source code is governed by a BSD-style |
|
# license that can be found in the LICENSE file or at |
|
# https://developers.google.com/open-source/licenses/bsd |
|
# |
|
"""Supporting C++ compilation of generated code""" |
|
|
|
load("@proto_bazel_features//:features.bzl", "bazel_features") |
|
load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain") |
|
|
|
def get_feature_configuration(ctx, has_sources, extra_requested_features = []): |
|
"""Returns C++ feature configuration for compiling and linking generated C++ files. |
|
|
|
Args: |
|
ctx: (RuleCtx) rule context. |
|
has_sources: (bool) Has the proto_library sources. |
|
extra_requested_features: (list[str]) Additionally requested features. |
|
Returns: |
|
(FeatureConfiguration) C++ feature configuration |
|
""" |
|
cc_toolchain = find_cc_toolchain(ctx) |
|
requested_features = ctx.features + extra_requested_features |
|
|
|
# TODO: Remove LAYERING_CHECK once we have verified that there are direct |
|
# dependencies for all generated #includes. |
|
unsupported_features = ctx.disabled_features + ["parse_headers", "layering_check"] |
|
if has_sources: |
|
requested_features.append("header_modules") |
|
else: |
|
unsupported_features.append("header_modules") |
|
return cc_common.configure_features( |
|
ctx = ctx, |
|
cc_toolchain = cc_toolchain, |
|
requested_features = requested_features, |
|
unsupported_features = unsupported_features, |
|
) |
|
|
|
def _get_libraries_from_linking_outputs(linking_outputs, feature_configuration): |
|
library_to_link = linking_outputs.library_to_link |
|
if not library_to_link: |
|
return [] |
|
outputs = [] |
|
if library_to_link.static_library: |
|
outputs.append(library_to_link.static_library) |
|
if library_to_link.pic_static_library: |
|
outputs.append(library_to_link.pic_static_library) |
|
|
|
# On Windows, dynamic library is not built by default, so don't add them to files_to_build. |
|
if not cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows"): |
|
if library_to_link.resolved_symlink_dynamic_library: |
|
outputs.append(library_to_link.resolved_symlink_dynamic_library) |
|
elif library_to_link.dynamic_library: |
|
outputs.append(library_to_link.dynamic_library) |
|
if library_to_link.resolved_symlink_interface_library: |
|
outputs.append(library_to_link.resolved_symlink_interface_library) |
|
elif library_to_link.interface_library: |
|
outputs.append(library_to_link.interface_library) |
|
return outputs |
|
|
|
def cc_proto_compile_and_link(ctx, deps, sources, headers, disallow_dynamic_library = None, feature_configuration = None, alwayslink = False, **kwargs): |
|
"""Creates C++ compilation and linking actions for C++ proto sources. |
|
|
|
Args: |
|
ctx: rule context |
|
deps: (list[CcInfo]) List of libraries to be added as dependencies to compilation and linking |
|
actions. |
|
sources:(list[File]) List of C++ sources files. |
|
headers: list(File] List of C++ headers files. |
|
disallow_dynamic_library: (bool) Are dynamic libraries disallowed. |
|
feature_configuration: (FeatureConfiguration) feature configuration to use. |
|
alwayslink: (bool) Should the library be always linked. |
|
**kwargs: Additional arguments passed to the compilation. See cc_common.compile. |
|
|
|
Returns: |
|
(CcInfo, list[File], list[File]) |
|
- CcInfo provider with compilation context and linking context |
|
- A list of linked libraries related to this proto |
|
- A list of temporary files generated durind compilation |
|
""" |
|
cc_toolchain = find_cc_toolchain(ctx) |
|
feature_configuration = feature_configuration or get_feature_configuration(ctx, bool(sources)) |
|
if disallow_dynamic_library == None: |
|
# TODO: Configure output artifact with action_config |
|
# once proto compile action is configurable from the crosstool. |
|
disallow_dynamic_library = not cc_common.is_enabled( |
|
feature_name = "supports_dynamic_linker", |
|
feature_configuration = feature_configuration, |
|
) |
|
|
|
(compilation_context, compilation_outputs) = cc_common.compile( |
|
actions = ctx.actions, |
|
feature_configuration = feature_configuration, |
|
cc_toolchain = cc_toolchain, |
|
srcs = sources, |
|
public_hdrs = headers, |
|
compilation_contexts = [dep[CcInfo].compilation_context for dep in deps if CcInfo in dep], |
|
name = ctx.label.name, |
|
# Don't instrument the generated C++ files even when --collect_code_coverage is set. |
|
# If we actually start generating coverage instrumentation for .proto files based on coverage |
|
# data from the generated C++ files, this will have to be removed. Currently, the work done |
|
# to instrument those files and execute the instrumentation is all for nothing, and it can |
|
# be quite a bit of extra computation even when that's not made worse by performance bugs, |
|
# as in b/64963386. |
|
# code_coverage_enabled = False (cc_common.compile disables code_coverage by default) |
|
**kwargs |
|
) |
|
|
|
if sources: |
|
linking_context, linking_outputs = cc_common.create_linking_context_from_compilation_outputs( |
|
actions = ctx.actions, |
|
feature_configuration = feature_configuration, |
|
cc_toolchain = cc_toolchain, |
|
compilation_outputs = compilation_outputs, |
|
linking_contexts = [dep[CcInfo].linking_context for dep in deps if CcInfo in dep], |
|
name = ctx.label.name, |
|
disallow_dynamic_library = disallow_dynamic_library, |
|
alwayslink = alwayslink, |
|
) |
|
libraries = _get_libraries_from_linking_outputs(linking_outputs, feature_configuration) |
|
else: |
|
linking_context = cc_common.merge_linking_contexts( |
|
linking_contexts = [dep[CcInfo].linking_context for dep in deps if CcInfo in dep], |
|
) |
|
libraries = [] |
|
|
|
debug_context = None |
|
temps = [] |
|
if bazel_features.cc.protobuf_on_allowlist: |
|
debug_context = cc_common.merge_debug_context( |
|
[cc_common.create_debug_context(compilation_outputs)] + |
|
[dep[CcInfo].debug_context() for dep in deps if CcInfo in dep], |
|
) |
|
temps = compilation_outputs.temps() |
|
|
|
return CcInfo( |
|
compilation_context = compilation_context, |
|
linking_context = linking_context, |
|
debug_context = debug_context, |
|
), libraries, temps
|
|
|