diff --git a/android/proto.go b/android/proto.go index 0ffb9b62a..6887900c4 100644 --- a/android/proto.go +++ b/android/proto.go @@ -268,6 +268,13 @@ func Bp2buildProtoProperties(ctx Bp2buildMutatorContext, m *ModuleBase, srcs baz protoIncludeDirs = append(protoIncludeDirs, dir) } } + + // proto.local_include_dirs are similar to proto.include_dirs, except that it is relative to the module directory + for _, dir := range props.Proto.Local_include_dirs { + relativeToTop := pathForModuleSrc(ctx, dir).String() + protoIncludeDirs = append(protoIncludeDirs, relativeToTop) + } + } else if props.Proto.Type != info.Type && props.Proto.Type != nil { ctx.ModuleErrorf("Cannot handle arch-variant types for protos at this time.") } @@ -292,9 +299,14 @@ func Bp2buildProtoProperties(ctx Bp2buildMutatorContext, m *ModuleBase, srcs baz // (or a different subpackage), it will not find it. // The CcProtoGen action itself runs fine because we construct the correct ProtoInfo, // but the FileDescriptorSet of each proto_library might not be compile-able - if pkg != ctx.ModuleDir() { + // + // Add manual tag if either + // 1. .proto files are in more than one package + // 2. proto.include_dirs is not empty + if len(SortedStringKeys(pkgToSrcs)) > 1 || len(protoIncludeDirs) > 0 { tags.Append(bazel.MakeStringListAttribute([]string{"manual"})) } + ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{Rule_class: "proto_library"}, CommonAttributes{Name: name, Dir: proptools.StringPtr(pkg), Tags: tags}, diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 28dbf7ead..650121724 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -4965,6 +4965,7 @@ cc_library_static { }), MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{ "srcs": `["foo.proto"]`, + "tags": `["manual"]`, }), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{ "deps": `[ @@ -5033,6 +5034,7 @@ cc_library_static { MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{ "srcs": `["foo.proto"]`, "strip_import_prefix": `""`, + "tags": `["manual"]`, }), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{ "deps": `[ @@ -5103,6 +5105,7 @@ cc_library_static { }), MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{ "srcs": `["foo.proto"]`, + "tags": `["manual"]`, }), MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{ "deps": `[":foo_proto"]`, @@ -5137,3 +5140,58 @@ cc_library_static { } runCcLibraryTestCase(t, tc) } + +func TestProtoLocalIncludeDirs(t *testing.T) { + tc := Bp2buildTestCase{ + Description: "cc_library depends on .proto files using proto.local_include_dirs", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"), + Filesystem: map[string]string{ + "foo/Android.bp": `cc_library_static { + name: "foo", + srcs: [ + "foo.proto", + ], + proto: { + local_include_dirs: ["foo_subdir"], + }, + bazel_module: { bp2build_available: true }, +}`, + "foo/foo.proto": "", + "foo/foo_subdir/Android.bp": "", + "foo/foo_subdir/foo_subdir.proto": "", + }, + } + + // We will run the test 2 times and check in foo and foo/foo_subdir directories + // foo dir + tc.Dir = "foo" + tc.ExpectedBazelTargets = []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "local_includes": `["."]`, + "deps": `["//:libprotobuf-cpp-lite"]`, + "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`, + }), + MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{ + "srcs": `["foo.proto"]`, + "tags": `["manual"]`, + }), + MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{ + "deps": `[":foo_proto"]`, + "transitive_deps": `["//foo/foo_subdir:foo.foo_subdir.include_dir_bp2build_generated_proto"]`, + }), + } + runCcLibraryTestCase(t, tc) + + // foo/foo_subdir + tc.Dir = "foo/foo_subdir" + tc.ExpectedBazelTargets = []string{ + MakeBazelTarget("proto_library", "foo.foo_subdir.include_dir_bp2build_generated_proto", AttrNameToString{ + "srcs": `["foo_subdir.proto"]`, + "strip_import_prefix": `""`, + "tags": `["manual"]`, + }), + } + runCcLibraryTestCase(t, tc) +} diff --git a/python/bp2build.go b/python/bp2build.go index 41e9f4974..8bc3d0a3e 100644 --- a/python/bp2build.go +++ b/python/bp2build.go @@ -33,6 +33,12 @@ type bazelPythonLibraryAttributes struct { type bazelPythonProtoLibraryAttributes struct { Deps bazel.LabelListAttribute + + // A list of proto_library targets that the proto_library in `deps` depends on + // This list is overestimation. + // Overestimation is necessary since Soong includes other protos via proto.include_dirs and not + // a specific .proto file module explicitly. + Transitive_deps bazel.LabelListAttribute } type baseAttributes struct { @@ -81,7 +87,8 @@ func (m *PythonLibraryModule) makeArchVariantBaseAttributes(ctx android.TopDownM }, android.CommonAttributes{ Name: pyProtoLibraryName, }, &bazelPythonProtoLibraryAttributes{ - Deps: bazel.MakeLabelListAttribute(protoInfo.Proto_libs), + Deps: bazel.MakeLabelListAttribute(protoInfo.Proto_libs), + Transitive_deps: bazel.MakeLabelListAttribute(protoInfo.Transitive_proto_libs), }) attrs.Deps.Add(bazel.MakeLabelAttribute(":" + pyProtoLibraryName))