diff --git a/bazel/upb_proto_library.bzl b/bazel/upb_proto_library.bzl index bb14cf0918..b307740c31 100644 --- a/bazel/upb_proto_library.bzl +++ b/bazel/upb_proto_library.bzl @@ -190,7 +190,32 @@ GeneratedSrcsInfo = provider( }, ) +def _concat_lists(lists): + ret = [] + for lst in lists: + ret = ret + lst + return ret + +def _merge_generated_srcs(srcs): + return GeneratedSrcsInfo( + srcs = _concat_lists([s.srcs for s in srcs]), + hdrs = _concat_lists([s.hdrs for s in srcs]), + thunks = _concat_lists([s.thunks for s in srcs]), + includes = _concat_lists([s.includes for s in srcs]), + ) + UpbWrappedCcInfo = provider("Provider for cc_info for protos", fields = ["cc_info", "cc_info_with_thunks"]) + +def _merge_wrapped_cc_infos(infos, cc_infos): + return UpbWrappedCcInfo( + cc_info = cc_common.merge_cc_infos( + direct_cc_infos = cc_infos + [info.cc_info for info in infos], + ), + cc_info_with_thunks = cc_common.merge_cc_infos( + direct_cc_infos = [info.cc_info_with_thunks for info in infos], + ), + ) + _UpbDefsWrappedCcInfo = provider("Provider for cc_info for protos", fields = ["cc_info"]) _UpbWrappedGeneratedSrcsInfo = provider("Provider for generated sources", fields = ["srcs"]) _WrappedDefsGeneratedSrcsInfo = provider( @@ -198,7 +223,7 @@ _WrappedDefsGeneratedSrcsInfo = provider( fields = ["srcs"], ) -def _compile_upb_protos(ctx, generator, proto_info, proto_sources): +def _generate_upb_protos(ctx, generator, proto_info, proto_sources): if len(proto_sources) == 0: return GeneratedSrcsInfo(srcs = [], hdrs = [], thunks = [], includes = []) @@ -288,91 +313,50 @@ def _generate_name(ctx, generator, thunks = False): return ctx.rule.attr.name + "." + generator + ".thunks" return ctx.rule.attr.name + "." + generator -def _upb_proto_aspect_impl(target, ctx, generator, cc_provider, file_provider, provide_cc_shared_library_hints = True): - providers = [] - if not getattr(ctx.rule.attr, "srcs", []): - # This target doesn't declare any sources, reexport all its deps instead. - srcs = [] - hdrs = [] - thunks = [] - includes = [] - cc_infos = [] - cc_infos_with_thunks = [] - for dep in ctx.rule.attr.deps: - if CcInfo in dep: - cc_infos.append(dep[CcInfo]) - if UpbWrappedCcInfo in dep: - cc_infos.append(dep[UpbWrappedCcInfo].cc_info) - cc_infos_with_thunks.append(dep[UpbWrappedCcInfo].cc_info_with_thunks) - if _UpbDefsWrappedCcInfo in dep: - cc_infos.append(dep[_UpbDefsWrappedCcInfo].cc_info) - - if _UpbWrappedGeneratedSrcsInfo in dep: - unwrapped_sources = dep[_UpbWrappedGeneratedSrcsInfo].srcs - srcs += unwrapped_sources.srcs - hdrs += unwrapped_sources.hdrs - thunks += unwrapped_sources.thunks - includes += unwrapped_sources.includes - if _WrappedDefsGeneratedSrcsInfo in dep: - unwrapped_sources = dep[_WrappedDefsGeneratedSrcsInfo].srcs - srcs += unwrapped_sources.srcs - hdrs += unwrapped_sources.hdrs - thunks += unwrapped_sources.thunks - includes += unwrapped_sources.includes - - if len(cc_infos_with_thunks) > 0: - providers.append(cc_provider( - cc_info = cc_common.merge_cc_infos(direct_cc_infos = cc_infos), - cc_info_with_thunks = cc_common.merge_cc_infos(direct_cc_infos = cc_infos_with_thunks), - )) - else: - providers.append(cc_provider(cc_info = cc_common.merge_cc_infos(direct_cc_infos = cc_infos))) - providers.append(file_provider(srcs = GeneratedSrcsInfo(srcs = srcs, hdrs = hdrs, thunks = thunks, includes = includes))) - else: - proto_info = target[ProtoInfo] - files = _compile_upb_protos(ctx, generator, proto_info, proto_info.direct_sources) - deps = ctx.rule.attr.deps + getattr(ctx.attr, "_" + generator) - dep_ccinfos = [dep[CcInfo] for dep in deps if CcInfo in dep] - dep_ccinfos += [dep[UpbWrappedCcInfo].cc_info for dep in deps if UpbWrappedCcInfo in dep] - dep_ccinfos += [dep[_UpbDefsWrappedCcInfo].cc_info for dep in deps if _UpbDefsWrappedCcInfo in dep] - if generator == "upbdefs": - if UpbWrappedCcInfo not in target: - fail("Target should have UpbWrappedCcInfo provider") - dep_ccinfos.append(target[UpbWrappedCcInfo].cc_info) - - cc_info = _cc_library_func( +def _get_dep_cc_info(target, ctx, generator): + deps = ctx.rule.attr.deps + getattr(ctx.attr, "_" + generator) + dep_ccinfos = [dep[CcInfo] for dep in deps if CcInfo in dep] + dep_ccinfos += [dep[_UpbDefsWrappedCcInfo].cc_info for dep in deps if _UpbDefsWrappedCcInfo in dep] + + dep_wrapped_infos = [dep[UpbWrappedCcInfo] for dep in deps if UpbWrappedCcInfo in dep] + if generator == "upbdefs": + if UpbWrappedCcInfo not in target: + fail("Target should have UpbWrappedCcInfo provider") + dep_wrapped_infos.append(target[UpbWrappedCcInfo]) + + return _merge_wrapped_cc_infos(dep_wrapped_infos, dep_ccinfos) + +def _compile_upb_protos(ctx, files, generator, dep_wrapped_ccinfo, cc_provider): + cc_info = _cc_library_func( + ctx = ctx, + name = _generate_name(ctx, generator), + hdrs = files.hdrs, + srcs = files.srcs, + includes = files.includes, + copts = ctx.attr._copts[UpbProtoLibraryCoptsInfo].copts, + dep_ccinfos = [dep_wrapped_ccinfo.cc_info], + ) + + if files.thunks: + cc_info_with_thunks = _cc_library_func( ctx = ctx, - name = _generate_name(ctx, generator), - hdrs = files.hdrs, - srcs = files.srcs, + name = _generate_name(ctx, generator, files.thunks), + hdrs = [], + srcs = files.thunks, includes = files.includes, copts = ctx.attr._copts[UpbProtoLibraryCoptsInfo].copts, - dep_ccinfos = dep_ccinfos, + dep_ccinfos = [dep_wrapped_ccinfo.cc_info, cc_info], + ) + return cc_provider( + cc_info = cc_info, + cc_info_with_thunks = cc_info_with_thunks, + ) + else: + return cc_provider( + cc_info = cc_info, ) - if files.thunks: - cc_info_with_thunks = _cc_library_func( - ctx = ctx, - name = _generate_name(ctx, generator, files.thunks), - hdrs = [], - srcs = files.thunks, - includes = files.includes, - copts = ctx.attr._copts[UpbProtoLibraryCoptsInfo].copts, - dep_ccinfos = dep_ccinfos + [cc_info], - ) - wrapped_cc_info = cc_provider( - cc_info = cc_info, - cc_info_with_thunks = cc_info_with_thunks, - ) - else: - wrapped_cc_info = cc_provider( - cc_info = cc_info, - ) - providers += [ - wrapped_cc_info, - file_provider(srcs = files), - ] - +def _get_hint_providers(ctx, generator): if generator not in _GENERATORS: fail("Please add new generator '{}' to _GENERATORS list".format(generator)) @@ -381,13 +365,44 @@ def _upb_proto_aspect_impl(target, ctx, generator, cc_provider, file_provider, p possible_owners.append(ctx.label.relative(_generate_name(ctx, generator))) possible_owners.append(ctx.label.relative(_generate_name(ctx, generator, thunks = True))) - if provide_cc_shared_library_hints: - if hasattr(cc_common, "CcSharedLibraryHintInfo"): - providers.append(cc_common.CcSharedLibraryHintInfo(owners = possible_owners)) - elif hasattr(cc_common, "CcSharedLibraryHintInfo_6_X_constructor_do_not_use"): - # This branch can be deleted once 6.X is not supported by upb rules - providers.append(cc_common.CcSharedLibraryHintInfo_6_X_constructor_do_not_use(owners = possible_owners)) - return providers + if hasattr(cc_common, "CcSharedLibraryHintInfo"): + return [cc_common.CcSharedLibraryHintInfo(owners = possible_owners)] + elif hasattr(cc_common, "CcSharedLibraryHintInfo_6_X_constructor_do_not_use"): + # This branch can be deleted once 6.X is not supported by upb rules + return [cc_common.CcSharedLibraryHintInfo_6_X_constructor_do_not_use(owners = possible_owners)] + + return [] + +def _upb_proto_aspect_impl(target, ctx, generator, cc_provider, file_provider, provide_cc_shared_library_hints = True): + dep_wrapped_ccinfo = _get_dep_cc_info(target, ctx, generator) + if not getattr(ctx.rule.attr, "srcs", []): + # This target doesn't declare any sources, reexport all its deps instead. + # This is known as an "alias library": + # https://bazel.build/reference/be/protocol-buffer#proto_library.srcs + files = _merge_generated_srcs([dep[file_provider].srcs for dep in ctx.rule.attr.deps]) + wrapped_cc_info = dep_wrapped_ccinfo + else: + proto_info = target[ProtoInfo] + files = _generate_upb_protos( + ctx, + generator, + proto_info, + proto_info.direct_sources, + ) + wrapped_cc_info = _compile_upb_protos( + ctx, + files, + generator, + dep_wrapped_ccinfo, + cc_provider, + ) + + hints = _get_hint_providers(ctx, generator) if provide_cc_shared_library_hints else [] + + return hints + [ + file_provider(srcs = files), + wrapped_cc_info, + ] _GENERATORS = ["upb", "upbdefs"]