diff options
-rw-r--r-- | android/module.go | 4 | ||||
-rw-r--r-- | android/proto.go | 52 | ||||
-rw-r--r-- | cc/builder.go | 1 | ||||
-rw-r--r-- | cc/cc.go | 5 | ||||
-rw-r--r-- | cc/cc_test.go | 1 | ||||
-rw-r--r-- | cc/compiler.go | 1 | ||||
-rw-r--r-- | cc/proto.go | 140 | ||||
-rw-r--r-- | cc/proto_test.go | 35 | ||||
-rw-r--r-- | cc/util.go | 1 | ||||
-rw-r--r-- | genrule/genrule.go | 6 | ||||
-rw-r--r-- | genrule/genrule_test.go | 2 | ||||
-rw-r--r-- | java/gen.go | 2 | ||||
-rw-r--r-- | java/java.go | 7 | ||||
-rw-r--r-- | java/proto.go | 64 | ||||
-rw-r--r-- | python/proto.go | 2 | ||||
-rw-r--r-- | python/python.go | 2 |
16 files changed, 209 insertions, 116 deletions
diff --git a/android/module.go b/android/module.go index abf2cae4..201c27a8 100644 --- a/android/module.go +++ b/android/module.go @@ -1425,6 +1425,10 @@ type SourceFileProducer interface { Srcs() Paths } +type HostToolProvider interface { + HostToolPath() OptionalPath +} + // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must // be tagged with `android:"path" to support automatic source module dependency resolution. // diff --git a/android/proto.go b/android/proto.go index 83dc32a9..5247c68d 100644 --- a/android/proto.go +++ b/android/proto.go @@ -17,6 +17,7 @@ package android import ( "strings" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -35,21 +36,61 @@ type ProtoFlags struct { SubDir ModuleGenPath OutTypeFlag string OutParams []string + Deps Paths +} + +type protoDependencyTag struct { + blueprint.BaseDependencyTag + name string +} + +var ProtoPluginDepTag = protoDependencyTag{name: "plugin"} + +func ProtoDeps(ctx BottomUpMutatorContext, p *ProtoProperties) { + if String(p.Proto.Plugin) != "" && String(p.Proto.Type) != "" { + ctx.ModuleErrorf("only one of proto.type and proto.plugin can be specified.") + } + + if plugin := String(p.Proto.Plugin); plugin != "" { + ctx.AddFarVariationDependencies([]blueprint.Variation{ + {Mutator: "arch", Variation: ctx.Config().BuildOsVariant}, + }, ProtoPluginDepTag, "protoc-gen-"+plugin) + } } func GetProtoFlags(ctx ModuleContext, p *ProtoProperties) ProtoFlags { - var protoFlags []string + var flags []string + var deps Paths + if len(p.Proto.Local_include_dirs) > 0 { localProtoIncludeDirs := PathsForModuleSrc(ctx, p.Proto.Local_include_dirs) - protoFlags = append(protoFlags, JoinWithPrefix(localProtoIncludeDirs.Strings(), "-I")) + flags = append(flags, JoinWithPrefix(localProtoIncludeDirs.Strings(), "-I")) } if len(p.Proto.Include_dirs) > 0 { rootProtoIncludeDirs := PathsForSource(ctx, p.Proto.Include_dirs) - protoFlags = append(protoFlags, JoinWithPrefix(rootProtoIncludeDirs.Strings(), "-I")) + flags = append(flags, JoinWithPrefix(rootProtoIncludeDirs.Strings(), "-I")) + } + + ctx.VisitDirectDepsWithTag(ProtoPluginDepTag, func(dep Module) { + if hostTool, ok := dep.(HostToolProvider); !ok || !hostTool.HostToolPath().Valid() { + ctx.PropertyErrorf("proto.plugin", "module %q is not a host tool provider", + ctx.OtherModuleName(dep)) + } else { + plugin := String(p.Proto.Plugin) + deps = append(deps, hostTool.HostToolPath().Path()) + flags = append(flags, "--plugin=protoc-gen-"+plugin+"="+hostTool.HostToolPath().String()) + } + }) + + var protoOutFlag string + if plugin := String(p.Proto.Plugin); plugin != "" { + protoOutFlag = "--" + plugin + "_out" } return ProtoFlags{ - Flags: protoFlags, + Flags: flags, + Deps: deps, + OutTypeFlag: protoOutFlag, CanonicalPathFromRoot: proptools.BoolDefault(p.Proto.Canonical_path_from_root, true), Dir: PathForModuleGen(ctx, "proto"), SubDir: PathForModuleGen(ctx, "proto", ctx.ModuleDir()), @@ -61,6 +102,9 @@ type ProtoProperties struct { // Proto generator type. C++: full or lite. Java: micro, nano, stream, or lite. Type *string `android:"arch_variant"` + // Proto plugin to use as the generator. Must be a cc_binary_host module. + Plugin *string `android:"arch_variant"` + // list of directories that will be added to the protoc include paths. Include_dirs []string diff --git a/cc/builder.go b/cc/builder.go index 6b139f48..24c9377d 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -260,7 +260,6 @@ type builderFlags struct { stripAddGnuDebuglink bool stripUseGnuStrip bool - protoDeps android.Paths proto android.ProtoFlags protoC bool protoOptionsFile bool @@ -163,7 +163,6 @@ type Flags struct { GroupStaticLibs bool proto android.ProtoFlags - protoDeps android.Paths protoC bool // Whether to use C instead of C++ protoOptionsFile bool // Whether to look for a .options file next to the .proto } @@ -1594,6 +1593,10 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { return } + if depTag == android.ProtoPluginDepTag { + return + } + if dep.Target().Os != ctx.Os() { ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) return diff --git a/cc/cc_test.go b/cc/cc_test.go index 8c0bcfe8..05d74b99 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -54,6 +54,7 @@ func TestMain(m *testing.M) { func createTestContext(t *testing.T, config android.Config, bp string, os android.OsType) *android.TestContext { ctx := android.NewTestArchContext() ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(BinaryFactory)) + ctx.RegisterModuleType("cc_binary_host", android.ModuleFactoryAdaptor(binaryHostFactory)) ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory)) ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory)) ctx.RegisterModuleType("cc_library_static", android.ModuleFactoryAdaptor(LibraryStaticFactory)) diff --git a/cc/compiler.go b/cc/compiler.go index fe46a3c3..f9af4d82 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -221,6 +221,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...) deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...) + android.ProtoDeps(ctx, &compiler.Proto) if compiler.hasSrcExt(".proto") { deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static)) } diff --git a/cc/proto.go b/cc/proto.go index 5a96ae78..f818edc9 100644 --- a/cc/proto.go +++ b/cc/proto.go @@ -39,7 +39,7 @@ func genProto(ctx android.ModuleContext, protoFile android.Path, flags builderFl headerFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.h")) } - protoDeps := flags.protoDeps + protoDeps := flags.proto.Deps if flags.protoOptionsFile { optionsFile := pathtools.ReplaceExtension(protoFile.String(), "options") optionsPath := android.PathForSource(ctx, optionsFile) @@ -59,53 +59,55 @@ func genProto(ctx android.ModuleContext, protoFile android.Path, flags builderFl return ccFile, headerFile } -func protoDeps(ctx BaseModuleContext, deps Deps, p *android.ProtoProperties, static bool) Deps { +func protoDeps(ctx DepsContext, deps Deps, p *android.ProtoProperties, static bool) Deps { var lib string - switch String(p.Proto.Type) { - case "full": - if ctx.useSdk() { - lib = "libprotobuf-cpp-full-ndk" + if String(p.Proto.Plugin) == "" { + switch String(p.Proto.Type) { + case "full": + if ctx.useSdk() { + lib = "libprotobuf-cpp-full-ndk" + static = true + } else { + lib = "libprotobuf-cpp-full" + } + case "lite", "": + if ctx.useSdk() { + lib = "libprotobuf-cpp-lite-ndk" + static = true + } else { + lib = "libprotobuf-cpp-lite" + } + case "nanopb-c": + lib = "libprotobuf-c-nano" static = true - } else { - lib = "libprotobuf-cpp-full" - } - case "lite", "": - if ctx.useSdk() { - lib = "libprotobuf-cpp-lite-ndk" + case "nanopb-c-enable_malloc": + lib = "libprotobuf-c-nano-enable_malloc" static = true - } else { - lib = "libprotobuf-cpp-lite" + case "nanopb-c-16bit": + lib = "libprotobuf-c-nano-16bit" + static = true + case "nanopb-c-enable_malloc-16bit": + lib = "libprotobuf-c-nano-enable_malloc-16bit" + static = true + case "nanopb-c-32bit": + lib = "libprotobuf-c-nano-32bit" + static = true + case "nanopb-c-enable_malloc-32bit": + lib = "libprotobuf-c-nano-enable_malloc-32bit" + static = true + default: + ctx.PropertyErrorf("proto.type", "unknown proto type %q", + String(p.Proto.Type)) } - case "nanopb-c": - lib = "libprotobuf-c-nano" - static = true - case "nanopb-c-enable_malloc": - lib = "libprotobuf-c-nano-enable_malloc" - static = true - case "nanopb-c-16bit": - lib = "libprotobuf-c-nano-16bit" - static = true - case "nanopb-c-enable_malloc-16bit": - lib = "libprotobuf-c-nano-enable_malloc-16bit" - static = true - case "nanopb-c-32bit": - lib = "libprotobuf-c-nano-32bit" - static = true - case "nanopb-c-enable_malloc-32bit": - lib = "libprotobuf-c-nano-enable_malloc-32bit" - static = true - default: - ctx.PropertyErrorf("proto.type", "unknown proto type %q", - String(p.Proto.Type)) - } - if static { - deps.StaticLibs = append(deps.StaticLibs, lib) - deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, lib) - } else { - deps.SharedLibs = append(deps.SharedLibs, lib) - deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, lib) + if static { + deps.StaticLibs = append(deps.StaticLibs, lib) + deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, lib) + } else { + deps.SharedLibs = append(deps.SharedLibs, lib) + deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, lib) + } } return deps @@ -120,33 +122,35 @@ func protoFlags(ctx ModuleContext, flags Flags, p *android.ProtoProperties) Flag } flags.GlobalFlags = append(flags.GlobalFlags, "-I"+flags.proto.Dir.String()) - var plugin string - - switch String(p.Proto.Type) { - case "nanopb-c", "nanopb-c-enable_malloc", "nanopb-c-16bit", "nanopb-c-enable_malloc-16bit", "nanopb-c-32bit", "nanopb-c-enable_malloc-32bit": - flags.protoC = true - flags.protoOptionsFile = true - flags.proto.OutTypeFlag = "--nanopb_out" - plugin = "protoc-gen-nanopb" - case "full": - flags.proto.OutTypeFlag = "--cpp_out" - case "lite": - flags.proto.OutTypeFlag = "--cpp_out" - flags.proto.OutParams = append(flags.proto.OutParams, "lite") - case "": - // TODO(b/119714316): this should be equivalent to "lite" in - // order to match protoDeps, but some modules are depending on - // this behavior - flags.proto.OutTypeFlag = "--cpp_out" - default: - ctx.PropertyErrorf("proto.type", "unknown proto type %q", - String(p.Proto.Type)) - } + if String(p.Proto.Plugin) == "" { + var plugin string + + switch String(p.Proto.Type) { + case "nanopb-c", "nanopb-c-enable_malloc", "nanopb-c-16bit", "nanopb-c-enable_malloc-16bit", "nanopb-c-32bit", "nanopb-c-enable_malloc-32bit": + flags.protoC = true + flags.protoOptionsFile = true + flags.proto.OutTypeFlag = "--nanopb_out" + plugin = "protoc-gen-nanopb" + case "full": + flags.proto.OutTypeFlag = "--cpp_out" + case "lite": + flags.proto.OutTypeFlag = "--cpp_out" + flags.proto.OutParams = append(flags.proto.OutParams, "lite") + case "": + // TODO(b/119714316): this should be equivalent to "lite" in + // order to match protoDeps, but some modules are depending on + // this behavior + flags.proto.OutTypeFlag = "--cpp_out" + default: + ctx.PropertyErrorf("proto.type", "unknown proto type %q", + String(p.Proto.Type)) + } - if plugin != "" { - path := ctx.Config().HostToolPath(ctx, plugin) - flags.protoDeps = append(flags.protoDeps, path) - flags.proto.Flags = append(flags.proto.Flags, "--plugin="+path.String()) + if plugin != "" { + path := ctx.Config().HostToolPath(ctx, plugin) + flags.proto.Deps = append(flags.proto.Deps, path) + flags.proto.Flags = append(flags.proto.Flags, "--plugin="+path.String()) + } } return flags diff --git a/cc/proto_test.go b/cc/proto_test.go index 6fee9241..4f0de780 100644 --- a/cc/proto_test.go +++ b/cc/proto_test.go @@ -17,6 +17,8 @@ package cc import ( "strings" "testing" + + "android/soong/android" ) func TestProto(t *testing.T) { @@ -33,4 +35,37 @@ func TestProto(t *testing.T) { t.Errorf("expected '--cpp_out' in %q", cmd) } }) + + t.Run("plugin", func(t *testing.T) { + ctx := testCc(t, ` + cc_binary_host { + name: "protoc-gen-foobar", + stl: "none", + } + + cc_library_shared { + name: "libfoo", + srcs: ["a.proto"], + proto: { + plugin: "foobar", + }, + }`) + + buildOS := android.BuildOs.String() + + proto := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_core_shared").Output("proto/a.pb.cc") + foobar := ctx.ModuleForTests("protoc-gen-foobar", buildOS+"_x86_64") + + cmd := proto.RuleParams.Command + if w := "--foobar_out="; !strings.Contains(cmd, w) { + t.Errorf("expected %q in %q", w, cmd) + } + + foobarPath := foobar.Module().(android.HostToolProvider).HostToolPath().String() + + if w := "--plugin=protoc-gen-foobar=" + foobarPath; !strings.Contains(cmd, w) { + t.Errorf("expected %q in %q", w, cmd) + } + }) + } @@ -84,7 +84,6 @@ func flagsToBuilderFlags(in Flags) builderFlags { groupStaticLibs: in.GroupStaticLibs, - protoDeps: in.protoDeps, proto: in.proto, protoC: in.protoC, protoOptionsFile: in.protoOptionsFile, diff --git a/genrule/genrule.go b/genrule/genrule.go index 32acd8c8..e259b1d9 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -49,8 +49,10 @@ type SourceFileGenerator interface { GeneratedDeps() android.Paths } +// Alias for android.HostToolProvider +// Deprecated: use android.HostToolProvider instead. type HostToolProvider interface { - HostToolPath() android.OptionalPath + android.HostToolProvider } type hostToolDependencyTag struct { @@ -193,7 +195,7 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { tool := ctx.OtherModuleName(module) var path android.OptionalPath - if t, ok := module.(HostToolProvider); ok { + if t, ok := module.(android.HostToolProvider); ok { if !t.(android.Module).Enabled() { if ctx.Config().AllowMissingDependencies() { ctx.AddMissingDependencies([]string{tool}) diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go index 19b22f76..5cb51b8b 100644 --- a/genrule/genrule_test.go +++ b/genrule/genrule_test.go @@ -527,4 +527,4 @@ func (t *testTool) HostToolPath() android.OptionalPath { return android.OptionalPathForPath(t.outputFile) } -var _ HostToolProvider = (*testTool)(nil) +var _ android.HostToolProvider = (*testTool)(nil) diff --git a/java/gen.go b/java/gen.go index 83625561..500d887e 100644 --- a/java/gen.go +++ b/java/gen.go @@ -118,7 +118,7 @@ func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths, javaFile := genLogtags(ctx, srcFile) outSrcFiles = append(outSrcFiles, javaFile) case ".proto": - srcJarFile := genProto(ctx, srcFile, flags) + srcJarFile := genProto(ctx, srcFile, flags.proto) outSrcFiles = append(outSrcFiles, srcJarFile) case ".sysprop": srcJarFile := genSysprop(ctx, srcFile) diff --git a/java/java.go b/java/java.go index beee1a5b..0417dee8 100644 --- a/java/java.go +++ b/java/java.go @@ -481,6 +481,7 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { {Mutator: "arch", Variation: ctx.Config().BuildOsCommonVariant}, }, pluginTag, j.properties.Plugins...) + android.ProtoDeps(ctx, &j.protoProperties) if j.hasSrcExt(".proto") { protoDeps(ctx, &j.protoProperties) } @@ -768,12 +769,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { deps.classpath = append(deps.classpath, dep.Srcs()...) deps.staticJars = append(deps.staticJars, dep.Srcs()...) deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...) - case android.DefaultsDepTag, android.SourceDepTag: - // Nothing to do - case publicApiFileTag, systemApiFileTag, testApiFileTag: - // Nothing to do - default: - ctx.ModuleErrorf("dependency on genrule %q may only be in srcs, libs, or static_libs", otherName) } default: switch tag { diff --git a/java/proto.go b/java/proto.go index 8de9e26d..37de1d28 100644 --- a/java/proto.go +++ b/java/proto.go @@ -18,7 +18,7 @@ import ( "android/soong/android" ) -func genProto(ctx android.ModuleContext, protoFile android.Path, flags javaBuilderFlags) android.Path { +func genProto(ctx android.ModuleContext, protoFile android.Path, flags android.ProtoFlags) android.Path { srcJarFile := android.GenPathWithExt(ctx, "proto", protoFile, "srcjar") outDir := srcJarFile.ReplaceExtension(ctx, "tmp") @@ -29,7 +29,7 @@ func genProto(ctx android.ModuleContext, protoFile android.Path, flags javaBuild rule.Command().Text("rm -rf").Flag(outDir.String()) rule.Command().Text("mkdir -p").Flag(outDir.String()) - android.ProtoRule(ctx, rule, protoFile, flags.proto, nil, outDir, depFile, nil) + android.ProtoRule(ctx, rule, protoFile, flags, flags.Deps, outDir, depFile, nil) // Proto generated java files have an unknown package name in the path, so package the entire output directory // into a srcjar. @@ -48,22 +48,24 @@ func genProto(ctx android.ModuleContext, protoFile android.Path, flags javaBuild } func protoDeps(ctx android.BottomUpMutatorContext, p *android.ProtoProperties) { - switch String(p.Proto.Type) { - case "micro": - ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-micro") - case "nano": - ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-nano") - case "lite", "": - ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-lite") - case "full": - if ctx.Host() { - ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-full") - } else { - ctx.PropertyErrorf("proto.type", "full java protos only supported on the host") + if String(p.Proto.Plugin) == "" { + switch String(p.Proto.Type) { + case "micro": + ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-micro") + case "nano": + ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-nano") + case "lite", "": + ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-lite") + case "full": + if ctx.Host() { + ctx.AddVariationDependencies(nil, staticLibTag, "libprotobuf-java-full") + } else { + ctx.PropertyErrorf("proto.type", "full java protos only supported on the host") + } + default: + ctx.PropertyErrorf("proto.type", "unknown proto type %q", + String(p.Proto.Type)) } - default: - ctx.PropertyErrorf("proto.type", "unknown proto type %q", - String(p.Proto.Type)) } } @@ -72,19 +74,21 @@ func protoFlags(ctx android.ModuleContext, j *CompilerProperties, p *android.Pro flags.proto = android.GetProtoFlags(ctx, p) - switch String(p.Proto.Type) { - case "micro": - flags.proto.OutTypeFlag = "--javamicro_out" - case "nano": - flags.proto.OutTypeFlag = "--javanano_out" - case "lite": - flags.proto.OutTypeFlag = "--java_out" - flags.proto.OutParams = append(flags.proto.OutParams, "lite") - case "full", "": - flags.proto.OutTypeFlag = "--java_out" - default: - ctx.PropertyErrorf("proto.type", "unknown proto type %q", - String(p.Proto.Type)) + if String(p.Proto.Plugin) == "" { + switch String(p.Proto.Type) { + case "micro": + flags.proto.OutTypeFlag = "--javamicro_out" + case "nano": + flags.proto.OutTypeFlag = "--javanano_out" + case "lite": + flags.proto.OutTypeFlag = "--java_out" + flags.proto.OutParams = append(flags.proto.OutParams, "lite") + case "full", "": + flags.proto.OutTypeFlag = "--java_out" + default: + ctx.PropertyErrorf("proto.type", "unknown proto type %q", + String(p.Proto.Type)) + } } flags.proto.OutParams = append(flags.proto.OutParams, j.Proto.Output_params...) diff --git a/python/proto.go b/python/proto.go index 813e91dd..b3ffaa67 100644 --- a/python/proto.go +++ b/python/proto.go @@ -29,7 +29,7 @@ func genProto(ctx android.ModuleContext, protoFile android.Path, flags android.P rule.Command().Text("rm -rf").Flag(outDir.String()) rule.Command().Text("mkdir -p").Flag(outDir.String()) - android.ProtoRule(ctx, rule, protoFile, flags, nil, outDir, depFile, nil) + android.ProtoRule(ctx, rule, protoFile, flags, flags.Deps, outDir, depFile, nil) // Proto generated python files have an unknown package name in the path, so package the entire output directory // into a srcszip. diff --git a/python/python.go b/python/python.go index 3c3c396a..ad089090 100644 --- a/python/python.go +++ b/python/python.go @@ -288,6 +288,8 @@ func (p *Module) hasSrcExt(ctx android.BottomUpMutatorContext, ext string) bool } func (p *Module) DepsMutator(ctx android.BottomUpMutatorContext) { + android.ProtoDeps(ctx, &p.protoProperties) + if p.hasSrcExt(ctx, protoExt) && p.Name() != "libprotobuf-python" { ctx.AddVariationDependencies(nil, pythonLibTag, "libprotobuf-python") } |