library_headers.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. // Copyright 2020 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/proptools"
  17. "android/soong/android"
  18. "android/soong/bazel"
  19. "android/soong/bazel/cquery"
  20. )
  21. func init() {
  22. RegisterLibraryHeadersBuildComponents(android.InitRegistrationContext)
  23. // Register sdk member types.
  24. android.RegisterSdkMemberType(headersLibrarySdkMemberType)
  25. }
  26. var headersLibrarySdkMemberType = &librarySdkMemberType{
  27. SdkMemberTypeBase: android.SdkMemberTypeBase{
  28. PropertyName: "native_header_libs",
  29. SupportsSdk: true,
  30. HostOsDependent: true,
  31. Traits: []android.SdkMemberTrait{
  32. nativeBridgeSdkTrait,
  33. ramdiskImageRequiredSdkTrait,
  34. recoveryImageRequiredSdkTrait,
  35. },
  36. },
  37. prebuiltModuleType: "cc_prebuilt_library_headers",
  38. noOutputFiles: true,
  39. }
  40. func RegisterLibraryHeadersBuildComponents(ctx android.RegistrationContext) {
  41. ctx.RegisterModuleType("cc_library_headers", LibraryHeaderFactory)
  42. ctx.RegisterModuleType("cc_prebuilt_library_headers", prebuiltLibraryHeaderFactory)
  43. }
  44. type libraryHeaderBazelHandler struct {
  45. module *Module
  46. library *libraryDecorator
  47. }
  48. var _ BazelHandler = (*libraryHeaderBazelHandler)(nil)
  49. func (handler *libraryHeaderBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
  50. bazelCtx := ctx.Config().BazelContext
  51. bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
  52. }
  53. func (h *libraryHeaderBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
  54. bazelCtx := ctx.Config().BazelContext
  55. ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
  56. if err != nil {
  57. ctx.ModuleErrorf(err.Error())
  58. return
  59. }
  60. outputPaths := ccInfo.OutputFiles
  61. if len(outputPaths) != 1 {
  62. ctx.ModuleErrorf("expected exactly one output file for %q, but got %q", label, outputPaths)
  63. return
  64. }
  65. var outputPath android.Path = android.PathForBazelOut(ctx, outputPaths[0])
  66. if len(ccInfo.TidyFiles) > 0 {
  67. h.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
  68. outputPath = android.AttachValidationActions(ctx, outputPath, h.module.tidyFiles)
  69. }
  70. h.module.outputFile = android.OptionalPathForPath(outputPath)
  71. // HeaderLibraryInfo is an empty struct to indicate to dependencies that this is a header library
  72. ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{})
  73. h.library.setFlagExporterInfoFromCcInfo(ctx, ccInfo)
  74. // Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
  75. // validation will fail. For now, set this to an empty list.
  76. // TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation.
  77. h.library.collectedSnapshotHeaders = android.Paths{}
  78. h.module.setAndroidMkVariablesFromCquery(ccInfo.CcAndroidMkInfo)
  79. }
  80. // cc_library_headers contains a set of c/c++ headers which are imported by
  81. // other soong cc modules using the header_libs property. For best practices,
  82. // use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for
  83. // Make.
  84. func LibraryHeaderFactory() android.Module {
  85. module, library := NewLibrary(android.HostAndDeviceSupported)
  86. library.HeaderOnly()
  87. module.sdkMemberTypes = []android.SdkMemberType{headersLibrarySdkMemberType}
  88. module.bazelable = true
  89. module.bazelHandler = &libraryHeaderBazelHandler{module: module, library: library}
  90. return module.Init()
  91. }
  92. // cc_prebuilt_library_headers is a prebuilt version of cc_library_headers
  93. func prebuiltLibraryHeaderFactory() android.Module {
  94. module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "")
  95. library.HeaderOnly()
  96. module.bazelable = true
  97. module.bazelHandler = &ccLibraryBazelHandler{module: module}
  98. return module.Init()
  99. }
  100. type bazelCcLibraryHeadersAttributes struct {
  101. Hdrs bazel.LabelListAttribute
  102. Export_includes bazel.StringListAttribute
  103. Export_absolute_includes bazel.StringListAttribute
  104. Export_system_includes bazel.StringListAttribute
  105. Deps bazel.LabelListAttribute
  106. Implementation_deps bazel.LabelListAttribute
  107. System_dynamic_deps bazel.LabelListAttribute
  108. sdkAttributes
  109. }
  110. func libraryHeadersBp2Build(ctx android.TopDownMutatorContext, module *Module) {
  111. baseAttributes := bp2BuildParseBaseProps(ctx, module)
  112. exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, &baseAttributes.includes)
  113. linkerAttrs := baseAttributes.linkerAttributes
  114. (&linkerAttrs.deps).Append(linkerAttrs.dynamicDeps)
  115. (&linkerAttrs.deps).Append(linkerAttrs.wholeArchiveDeps)
  116. attrs := &bazelCcLibraryHeadersAttributes{
  117. Export_includes: exportedIncludes.Includes,
  118. Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
  119. Export_system_includes: exportedIncludes.SystemIncludes,
  120. Deps: linkerAttrs.deps,
  121. System_dynamic_deps: linkerAttrs.systemDynamicDeps,
  122. Hdrs: baseAttributes.hdrs,
  123. sdkAttributes: bp2BuildParseSdkAttributes(module),
  124. }
  125. props := bazel.BazelTargetModuleProperties{
  126. Rule_class: "cc_library_headers",
  127. Bzl_load_location: "//build/bazel/rules/cc:cc_library_headers.bzl",
  128. }
  129. tags := android.ApexAvailableTagsWithoutTestApexes(ctx, module)
  130. ctx.CreateBazelTargetModule(props, android.CommonAttributes{
  131. Name: module.Name(),
  132. Tags: tags,
  133. }, attrs)
  134. }
  135. // Append .contribution suffix to input labels
  136. func apiBazelTargets(ll bazel.LabelList) bazel.LabelList {
  137. labels := make([]bazel.Label, 0)
  138. for _, l := range ll.Includes {
  139. labels = append(labels, bazel.Label{
  140. Label: android.ApiContributionTargetName(l.Label),
  141. })
  142. }
  143. return bazel.MakeLabelList(labels)
  144. }
  145. func apiLibraryHeadersBp2Build(ctx android.TopDownMutatorContext, module *Module) {
  146. // cc_api_library_headers have a 1:1 mapping to arch/no-arch
  147. // For API export, create a top-level arch-agnostic target and list the arch-specific targets as its deps
  148. // arch-agnostic includes
  149. apiIncludes := getModuleLibApiIncludes(ctx, module)
  150. // arch and os specific includes
  151. archApiIncludes, androidOsIncludes := archOsSpecificApiIncludes(ctx, module)
  152. for _, arch := range allArches { // sorted iteration
  153. archApiInclude := archApiIncludes[arch]
  154. if !archApiInclude.isEmpty() {
  155. createApiHeaderTarget(ctx, archApiInclude)
  156. apiIncludes.addDep(archApiInclude.name)
  157. }
  158. }
  159. // os==android includes
  160. if !androidOsIncludes.isEmpty() {
  161. createApiHeaderTarget(ctx, androidOsIncludes)
  162. apiIncludes.addDep(androidOsIncludes.name)
  163. }
  164. if !apiIncludes.isEmpty() {
  165. // override the name from <mod>.module-libapi.headers --> <mod>.contribution
  166. apiIncludes.name = android.ApiContributionTargetName(module.Name())
  167. createApiHeaderTarget(ctx, apiIncludes)
  168. }
  169. }
  170. func createApiHeaderTarget(ctx android.TopDownMutatorContext, includes apiIncludes) {
  171. props := bazel.BazelTargetModuleProperties{
  172. Rule_class: "cc_api_library_headers",
  173. Bzl_load_location: "//build/bazel/rules/apis:cc_api_contribution.bzl",
  174. }
  175. ctx.CreateBazelTargetModule(
  176. props,
  177. android.CommonAttributes{
  178. Name: includes.name,
  179. SkipData: proptools.BoolPtr(true),
  180. },
  181. &includes.attrs,
  182. )
  183. }
  184. var (
  185. allArches = []string{"arm", "arm64", "x86", "x86_64"}
  186. )
  187. type archApiIncludes map[string]apiIncludes
  188. func archOsSpecificApiIncludes(ctx android.TopDownMutatorContext, module *Module) (archApiIncludes, apiIncludes) {
  189. baseProps := bp2BuildParseBaseProps(ctx, module)
  190. i := bp2BuildParseExportedIncludes(ctx, module, &baseProps.includes)
  191. archRet := archApiIncludes{}
  192. for _, arch := range allArches {
  193. includes := i.Includes.SelectValue(
  194. bazel.ArchConfigurationAxis,
  195. arch)
  196. systemIncludes := i.SystemIncludes.SelectValue(
  197. bazel.ArchConfigurationAxis,
  198. arch)
  199. deps := baseProps.deps.SelectValue(
  200. bazel.ArchConfigurationAxis,
  201. arch)
  202. attrs := bazelCcLibraryHeadersAttributes{
  203. Export_includes: bazel.MakeStringListAttribute(includes),
  204. Export_system_includes: bazel.MakeStringListAttribute(systemIncludes),
  205. }
  206. apiDeps := apiBazelTargets(deps)
  207. if !apiDeps.IsEmpty() {
  208. attrs.Deps = bazel.MakeLabelListAttribute(apiDeps)
  209. }
  210. apiIncludes := apiIncludes{
  211. name: android.ApiContributionTargetName(module.Name()) + "." + arch,
  212. attrs: bazelCcApiLibraryHeadersAttributes{
  213. bazelCcLibraryHeadersAttributes: attrs,
  214. Arch: proptools.StringPtr(arch),
  215. },
  216. }
  217. archRet[arch] = apiIncludes
  218. }
  219. // apiIncludes for os == Android
  220. androidOsDeps := baseProps.deps.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid)
  221. androidOsAttrs := bazelCcLibraryHeadersAttributes{
  222. Export_includes: bazel.MakeStringListAttribute(
  223. i.Includes.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid),
  224. ),
  225. Export_system_includes: bazel.MakeStringListAttribute(
  226. i.SystemIncludes.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid),
  227. ),
  228. }
  229. androidOsApiDeps := apiBazelTargets(androidOsDeps)
  230. if !androidOsApiDeps.IsEmpty() {
  231. androidOsAttrs.Deps = bazel.MakeLabelListAttribute(androidOsApiDeps)
  232. }
  233. osRet := apiIncludes{
  234. name: android.ApiContributionTargetName(module.Name()) + ".androidos",
  235. attrs: bazelCcApiLibraryHeadersAttributes{
  236. bazelCcLibraryHeadersAttributes: androidOsAttrs,
  237. },
  238. }
  239. return archRet, osRet
  240. }