diff --git a/android/config.go b/android/config.go index 367b42c0c..50c141385 100644 --- a/android/config.go +++ b/android/config.go @@ -351,6 +351,10 @@ func (c *config) BlueprintToolLocation() string { var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil) +func (c *config) HostToolPath(ctx PathContext, tool string) Path { + return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool) +} + // HostSystemTool looks for non-hermetic tools from the system we're running on. // Generally shouldn't be used, but useful to find the XCode SDK, etc. func (c *config) HostSystemTool(name string) string { diff --git a/cc/builder.go b/cc/builder.go index 6d5b59594..bf35f84da 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -231,8 +231,6 @@ type builderFlags struct { ldFlags string libFlags string yaccFlags string - protoFlags string - protoOutParams string tidyFlags string sAbiFlags string yasmFlags string @@ -242,7 +240,6 @@ type builderFlags struct { tidy bool coverage bool sAbiDump bool - protoRoot bool systemIncludeFlags string @@ -252,6 +249,14 @@ type builderFlags struct { stripKeepMiniDebugInfo bool stripAddGnuDebuglink bool stripUseLlvmStrip bool + + protoDeps android.Paths + protoFlags string + protoOutTypeFlag string + protoOutParams string + protoC bool + protoOptionsFile bool + protoRoot bool } type Objects struct { diff --git a/cc/cc.go b/cc/cc.go index 4a432f4ea..ed65aa657 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -130,8 +130,6 @@ type Flags struct { CppFlags []string // Flags that apply to C++ source files ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools YaccFlags []string // Flags that apply to Yacc source files - protoFlags []string // Flags that apply to proto source files - protoOutParams []string // Flags that modify the output of proto generated files aidlFlags []string // Flags that apply to aidl source files rsFlags []string // Flags that apply to renderscript source files LdFlags []string // Flags that apply to linker command lines @@ -148,7 +146,6 @@ type Flags struct { Tidy bool Coverage bool SAbiDump bool - ProtoRoot bool RequiredInstructionSet string DynamicLinker string @@ -157,6 +154,14 @@ type Flags struct { LdFlagsDeps android.Paths // Files depended on by linker flags GroupStaticLibs bool + + protoDeps android.Paths + protoFlags []string // Flags that apply to proto source files + protoOutTypeFlag string // The output type, --cpp_out for example + protoOutParams []string // Flags that modify the output of proto generated files + protoC bool // Whether to use C instead of C++ + protoOptionsFile bool // Whether to look for a .options file next to the .proto + ProtoRoot bool } type ObjectLinkerProperties struct { diff --git a/cc/gen.go b/cc/gen.go index 29a2bb206..485279411 100644 --- a/cc/gen.go +++ b/cc/gen.go @@ -182,8 +182,7 @@ func genSources(ctx android.ModuleContext, srcFiles android.Paths, srcFiles[i] = cppFile genLex(ctx, srcFile, cppFile) case ".proto": - ccFile, headerFile := genProto(ctx, srcFile, buildFlags.protoFlags, - buildFlags.protoOutParams, buildFlags.protoRoot) + ccFile, headerFile := genProto(ctx, srcFile, buildFlags) srcFiles[i] = ccFile deps = append(deps, headerFile) case ".aidl": diff --git a/cc/proto.go b/cc/proto.go index 6e6f95ee9..61fd607f5 100644 --- a/cc/proto.go +++ b/cc/proto.go @@ -31,41 +31,56 @@ func init() { var ( proto = pctx.AndroidStaticRule("protoc", blueprint.RuleParams{ - Command: "$protocCmd --cpp_out=$protoOutParams:$outDir --dependency_out=$out.d -I $protoBase $protoFlags $in && " + + Command: "$protocCmd $protoOut=$protoOutParams:$outDir --dependency_out=$out.d -I $protoBase $protoFlags $in && " + `$depFixCmd $out.d`, CommandDeps: []string{"$protocCmd", "$depFixCmd"}, Depfile: "${out}.d", Deps: blueprint.DepsGCC, - }, "protoFlags", "protoOutParams", "protoBase", "outDir") + }, "protoFlags", "protoOut", "protoOutParams", "protoBase", "outDir") ) // genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns // the paths to the generated files. -func genProto(ctx android.ModuleContext, protoFile android.Path, - protoFlags, protoOutParams string, root bool) (ccFile, headerFile android.WritablePath) { +func genProto(ctx android.ModuleContext, protoFile android.Path, flags builderFlags) (ccFile, headerFile android.WritablePath) { + + srcSuffix := ".cc" + if flags.protoC { + srcSuffix = ".c" + } var protoBase string - if root { + if flags.protoRoot { protoBase = "." - ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.cc") + ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb"+srcSuffix) headerFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.h") } else { rel := protoFile.Rel() protoBase = strings.TrimSuffix(protoFile.String(), rel) - ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.cc")) + ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb"+srcSuffix)) headerFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.h")) } + protoDeps := flags.protoDeps + if flags.protoOptionsFile { + optionsFile := pathtools.ReplaceExtension(protoFile.String(), "options") + optionsPath := android.ExistentPathForSource(ctx, optionsFile) + if optionsPath.Valid() { + protoDeps = append(android.Paths{optionsPath.Path()}, protoDeps...) + } + } + ctx.Build(pctx, android.BuildParams{ Rule: proto, Description: "protoc " + protoFile.Rel(), Output: ccFile, ImplicitOutput: headerFile, Input: protoFile, + Implicits: protoDeps, Args: map[string]string{ "outDir": android.ProtoDir(ctx).String(), - "protoFlags": protoFlags, - "protoOutParams": protoOutParams, + "protoFlags": flags.protoFlags, + "protoOut": flags.protoOutTypeFlag, + "protoOutParams": flags.protoOutParams, "protoBase": protoBase, }, }) @@ -91,6 +106,12 @@ func protoDeps(ctx BaseModuleContext, deps Deps, p *android.ProtoProperties, sta } else { lib = "libprotobuf-cpp-lite" } + case "nanopb-c": + lib = "libprotobuf-c-nano" + static = true + case "nanopb-c-enable_malloc": + lib = "libprotobuf-c-nano-enable_malloc" + static = true default: ctx.PropertyErrorf("proto.type", "unknown proto type %q", String(p.Proto.Type)) @@ -118,8 +139,33 @@ func protoFlags(ctx ModuleContext, flags Flags, p *android.ProtoProperties) Flag flags.protoFlags = android.ProtoFlags(ctx, p) - if String(p.Proto.Type) == "lite" { + var plugin string + + switch String(p.Proto.Type) { + case "nanopb-c", "nanopb-c-enable_malloc": + flags.protoC = true + flags.protoOptionsFile = true + flags.protoOutTypeFlag = "--nanopb_out" + plugin = "protoc-gen-nanopb" + case "full": + flags.protoOutTypeFlag = "--cpp_out" + case "lite": + flags.protoOutTypeFlag = "--cpp_out" flags.protoOutParams = append(flags.protoOutParams, "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.protoOutTypeFlag = "--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.protoFlags = append(flags.protoFlags, "--plugin="+path.String()) } return flags diff --git a/cc/util.go b/cc/util.go index c900423bb..925dd7416 100644 --- a/cc/util.go +++ b/cc/util.go @@ -68,8 +68,6 @@ func flagsToBuilderFlags(in Flags) builderFlags { conlyFlags: strings.Join(in.ConlyFlags, " "), cppFlags: strings.Join(in.CppFlags, " "), yaccFlags: strings.Join(in.YaccFlags, " "), - protoFlags: strings.Join(in.protoFlags, " "), - protoOutParams: strings.Join(in.protoOutParams, ","), aidlFlags: strings.Join(in.aidlFlags, " "), rsFlags: strings.Join(in.rsFlags, " "), ldFlags: strings.Join(in.LdFlags, " "), @@ -81,11 +79,18 @@ func flagsToBuilderFlags(in Flags) builderFlags { coverage: in.Coverage, tidy: in.Tidy, sAbiDump: in.SAbiDump, - protoRoot: in.ProtoRoot, systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "), groupStaticLibs: in.GroupStaticLibs, + + protoDeps: in.protoDeps, + protoFlags: strings.Join(in.protoFlags, " "), + protoOutTypeFlag: in.protoOutTypeFlag, + protoOutParams: strings.Join(in.protoOutParams, ","), + protoC: in.protoC, + protoOptionsFile: in.protoOptionsFile, + protoRoot: in.ProtoRoot, } }