proto.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright 2016 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package cc
  15. import (
  16. "github.com/google/blueprint/pathtools"
  17. "github.com/google/blueprint/proptools"
  18. "android/soong/android"
  19. "android/soong/bazel"
  20. )
  21. const (
  22. protoTypeDefault = "lite"
  23. )
  24. // genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns
  25. // the paths to the generated files.
  26. func genProto(ctx android.ModuleContext, protoFile android.Path, flags builderFlags) (cc, header android.WritablePath) {
  27. var ccFile, headerFile android.ModuleGenPath
  28. srcSuffix := ".cc"
  29. if flags.protoC {
  30. srcSuffix = ".c"
  31. }
  32. if flags.proto.CanonicalPathFromRoot {
  33. ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb"+srcSuffix)
  34. headerFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.h")
  35. } else {
  36. rel := protoFile.Rel()
  37. ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb"+srcSuffix))
  38. headerFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.h"))
  39. }
  40. protoDeps := flags.proto.Deps
  41. if flags.protoOptionsFile {
  42. optionsFile := pathtools.ReplaceExtension(protoFile.String(), "options")
  43. optionsPath := android.PathForSource(ctx, optionsFile)
  44. protoDeps = append(android.Paths{optionsPath}, protoDeps...)
  45. }
  46. outDir := flags.proto.Dir
  47. depFile := ccFile.ReplaceExtension(ctx, "d")
  48. outputs := android.WritablePaths{ccFile, headerFile}
  49. rule := android.NewRuleBuilder(pctx, ctx)
  50. android.ProtoRule(rule, protoFile, flags.proto, protoDeps, outDir, depFile, outputs)
  51. rule.Build("protoc_"+protoFile.Rel(), "protoc "+protoFile.Rel())
  52. return ccFile, headerFile
  53. }
  54. func protoDeps(ctx DepsContext, deps Deps, p *android.ProtoProperties, static bool) Deps {
  55. var lib string
  56. if String(p.Proto.Plugin) == "" {
  57. switch proptools.StringDefault(p.Proto.Type, protoTypeDefault) {
  58. case "full":
  59. if ctx.useSdk() {
  60. lib = "libprotobuf-cpp-full-ndk"
  61. static = true
  62. } else {
  63. lib = "libprotobuf-cpp-full"
  64. }
  65. case "lite":
  66. if ctx.useSdk() {
  67. lib = "libprotobuf-cpp-lite-ndk"
  68. static = true
  69. } else {
  70. lib = "libprotobuf-cpp-lite"
  71. }
  72. case "nanopb-c":
  73. lib = "libprotobuf-c-nano"
  74. static = true
  75. case "nanopb-c-enable_malloc":
  76. lib = "libprotobuf-c-nano-enable_malloc"
  77. static = true
  78. case "nanopb-c-16bit":
  79. lib = "libprotobuf-c-nano-16bit"
  80. static = true
  81. case "nanopb-c-enable_malloc-16bit":
  82. lib = "libprotobuf-c-nano-enable_malloc-16bit"
  83. static = true
  84. case "nanopb-c-32bit":
  85. lib = "libprotobuf-c-nano-32bit"
  86. static = true
  87. case "nanopb-c-enable_malloc-32bit":
  88. lib = "libprotobuf-c-nano-enable_malloc-32bit"
  89. static = true
  90. default:
  91. ctx.PropertyErrorf("proto.type", "unknown proto type %q",
  92. String(p.Proto.Type))
  93. }
  94. if static {
  95. deps.StaticLibs = append(deps.StaticLibs, lib)
  96. deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, lib)
  97. } else {
  98. deps.SharedLibs = append(deps.SharedLibs, lib)
  99. deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, lib)
  100. }
  101. }
  102. return deps
  103. }
  104. func protoFlags(ctx ModuleContext, flags Flags, p *android.ProtoProperties) Flags {
  105. flags.Local.CFlags = append(flags.Local.CFlags, "-DGOOGLE_PROTOBUF_NO_RTTI")
  106. flags.proto = android.GetProtoFlags(ctx, p)
  107. if flags.proto.CanonicalPathFromRoot {
  108. flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+flags.proto.SubDir.String())
  109. }
  110. flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I"+flags.proto.Dir.String())
  111. if String(p.Proto.Plugin) == "" {
  112. var plugin string
  113. switch String(p.Proto.Type) {
  114. case "nanopb-c", "nanopb-c-enable_malloc", "nanopb-c-16bit", "nanopb-c-enable_malloc-16bit", "nanopb-c-32bit", "nanopb-c-enable_malloc-32bit":
  115. flags.protoC = true
  116. flags.protoOptionsFile = true
  117. flags.proto.OutTypeFlag = "--nanopb_out"
  118. // Disable nanopb timestamps to support remote caching.
  119. flags.proto.OutParams = append(flags.proto.OutParams, "-T")
  120. plugin = "protoc-gen-nanopb"
  121. case "full":
  122. flags.proto.OutTypeFlag = "--cpp_out"
  123. case "lite":
  124. flags.proto.OutTypeFlag = "--cpp_out"
  125. flags.proto.OutParams = append(flags.proto.OutParams, "lite")
  126. case "":
  127. // TODO(b/119714316): this should be equivalent to "lite" in
  128. // order to match protoDeps, but some modules are depending on
  129. // this behavior
  130. flags.proto.OutTypeFlag = "--cpp_out"
  131. default:
  132. ctx.PropertyErrorf("proto.type", "unknown proto type %q",
  133. String(p.Proto.Type))
  134. }
  135. if plugin != "" {
  136. path := ctx.Config().HostToolPath(ctx, plugin)
  137. flags.proto.Deps = append(flags.proto.Deps, path)
  138. flags.proto.Flags = append(flags.proto.Flags, "--plugin="+path.String())
  139. }
  140. }
  141. return flags
  142. }
  143. type protoAttributes struct {
  144. Deps bazel.LabelListAttribute
  145. Min_sdk_version *string
  146. }
  147. type bp2buildProtoDeps struct {
  148. wholeStaticLib *bazel.LabelAttribute
  149. implementationWholeStaticLib *bazel.LabelAttribute
  150. protoDep *bazel.LabelAttribute
  151. }
  152. func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute) bp2buildProtoDeps {
  153. var ret bp2buildProtoDeps
  154. protoInfo, ok := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, protoSrcs)
  155. if !ok || protoInfo.Proto_libs.IsEmpty() {
  156. return ret
  157. }
  158. var depName string
  159. typ := proptools.StringDefault(protoInfo.Type, protoTypeDefault)
  160. var rule_class string
  161. suffix := "_cc_proto"
  162. switch typ {
  163. case "lite":
  164. suffix += "_lite"
  165. rule_class = "cc_lite_proto_library"
  166. depName = "libprotobuf-cpp-lite"
  167. case "full":
  168. rule_class = "cc_proto_library"
  169. depName = "libprotobuf-cpp-full"
  170. default:
  171. ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
  172. }
  173. dep := android.BazelLabelForModuleDepSingle(ctx, depName)
  174. ret.protoDep = &bazel.LabelAttribute{Value: &dep}
  175. var protoAttrs protoAttributes
  176. protoAttrs.Deps.SetValue(protoInfo.Proto_libs)
  177. protoAttrs.Min_sdk_version = m.Properties.Min_sdk_version
  178. name := m.Name() + suffix
  179. tags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), m)
  180. ctx.CreateBazelTargetModule(
  181. bazel.BazelTargetModuleProperties{
  182. Rule_class: rule_class,
  183. Bzl_load_location: "//build/bazel/rules/cc:cc_proto.bzl",
  184. },
  185. android.CommonAttributes{Name: name, Tags: tags},
  186. &protoAttrs)
  187. var privateHdrs bool
  188. if lib, ok := m.linker.(*libraryDecorator); ok {
  189. privateHdrs = !proptools.Bool(lib.Properties.Proto.Export_proto_headers)
  190. }
  191. labelAttr := &bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + name}}
  192. if privateHdrs {
  193. ret.implementationWholeStaticLib = labelAttr
  194. } else {
  195. ret.wholeStaticLib = labelAttr
  196. }
  197. return ret
  198. }