Handle proto.include_dirs in bp2build for CC
Soong's proto.include_dirs becomes the -I path for aprotoc cpp code
generation. This does not translate well to Bazel because it runs this
action in a sandbox. Even if we construct an -I path, the .proto files
will not be there. This CL attempts to handle this kind of dependency
automatically via bp2build.
For this hypothetical example
```
foo.proto # contains `import bar.proto"
Android.bp # cc_library {srcs:"foo.proto", p.include_dirs:["subdir"]},
subdir/bar.proto
```
Implementation details for CcProtoGen of foo
- Glob the labels of .proto files for each includeDir, and create a
proto_library that encapsulates them.
- Since Bazel poses a contraint that proto_library target needs to be
in the same pacakge as the .proto file, the proto_library might be created
in a subdirectory with an import_prefix
- Add bar's proto_library as transitive deps of foo's cc_proto_library.
This will be added to -I during aprotoc. We cannot add them to `deps`,
otherwise bar's symbols will be statically linked into foo's .a
file.
Implementation details for clang compile of foo
At the end of CcProtoGen, we have converted foo.proto
to .cpp/.h files. To compile them to .a files, we need the .h files
generated from bar.proto. Soong specifies this at the
top-level cc_library soong module, so add those deps as the
implementation deps for clang compile.
(Will add support for java in a follow-up CL)
Test: go test ./bp2build
Test: built some internal modules that were previously blocked by this
Bug: 285140726
Change-Id: I7e1f9f0d1b1ba916a7ba8278f6cfb342b381d695
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 622ec4a..12a8751 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -2394,7 +2394,7 @@
},
include_build_directory: false,
}`,
- ExpectedErr: fmt.Errorf("module \"foo\": Could not find the proto_library target for include dir: external/protobuf/abc"),
+ ExpectedErr: fmt.Errorf("module \"foo\": TODO: Add support for proto.include_dir: external/protobuf/abc. This directory does not contain an Android.bp file"),
})
}
@@ -5054,3 +5054,72 @@
}
runCcLibraryTestCase(t, tc)
}
+
+func TestProtoIncludeDirs(t *testing.T) {
+ tc := Bp2buildTestCase{
+ Description: "cc_library depends on .proto files using proto.include_dirs",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ srcs: [
+ "foo.proto",
+ ],
+ proto: {
+ include_dirs: ["bar"],
+ }
+}
+` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+ Filesystem: map[string]string{
+ "bar/Android.bp": "",
+ "bar/bar.proto": "",
+ "bar/baz/Android.bp": "",
+ "bar/baz/baz.proto": "",
+ },
+ }
+
+ // We will run the test 3 times and check in the root, bar and bar/baz directories
+ // Root dir
+ 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"]`,
+ }),
+ MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+ "deps": `[":foo_proto"]`,
+ "transitive_deps": `[
+ "//bar:bar.include_dir_bp2build_generated_proto",
+ "//bar/baz:bar.include_dir_bp2build_generated_proto",
+ ]`,
+ }),
+ }
+ runCcLibraryTestCase(t, tc)
+
+ // bar dir
+ tc.Dir = "bar"
+ tc.ExpectedBazelTargets = []string{
+ MakeBazelTarget("proto_library", "bar.include_dir_bp2build_generated_proto", AttrNameToString{
+ "srcs": `["bar.proto"]`,
+ "strip_import_prefix": `""`,
+ "tags": `["manual"]`,
+ }),
+ }
+ runCcLibraryTestCase(t, tc)
+
+ // bar/baz dir
+ tc.Dir = "bar/baz"
+ tc.ExpectedBazelTargets = []string{
+ MakeBazelTarget("proto_library", "bar.include_dir_bp2build_generated_proto", AttrNameToString{
+ "srcs": `["//bar/baz:baz.proto"]`,
+ "strip_import_prefix": `""`,
+ "import_prefix": `"baz"`,
+ "tags": `["manual"]`,
+ }),
+ }
+ runCcLibraryTestCase(t, tc)
+}