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 15package cc 16 17import ( 18 "android/soong/android" 19 "android/soong/bazel" 20) 21 22func init() { 23 RegisterLibraryHeadersBuildComponents(android.InitRegistrationContext) 24 25 // Register sdk member types. 26 android.RegisterSdkMemberType(headersLibrarySdkMemberType) 27 28 android.RegisterBp2BuildMutator("cc_library_headers", CcLibraryHeadersBp2Build) 29} 30 31var headersLibrarySdkMemberType = &librarySdkMemberType{ 32 SdkMemberTypeBase: android.SdkMemberTypeBase{ 33 PropertyName: "native_header_libs", 34 SupportsSdk: true, 35 HostOsDependent: true, 36 }, 37 prebuiltModuleType: "cc_prebuilt_library_headers", 38 noOutputFiles: true, 39} 40 41func RegisterLibraryHeadersBuildComponents(ctx android.RegistrationContext) { 42 ctx.RegisterModuleType("cc_library_headers", LibraryHeaderFactory) 43 ctx.RegisterModuleType("cc_prebuilt_library_headers", prebuiltLibraryHeaderFactory) 44} 45 46type libraryHeaderBazelHander struct { 47 bazelHandler 48 49 module *Module 50 library *libraryDecorator 51} 52 53func (h *libraryHeaderBazelHander) generateBazelBuildActions(ctx android.ModuleContext, label string) bool { 54 bazelCtx := ctx.Config().BazelContext 55 ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType) 56 if err != nil { 57 ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err) 58 return false 59 } 60 if !ok { 61 return false 62 } 63 64 outputPaths := ccInfo.OutputFiles 65 if len(outputPaths) != 1 { 66 ctx.ModuleErrorf("expected exactly one output file for %q, but got %q", label, outputPaths) 67 return false 68 } 69 70 outputPath := android.PathForBazelOut(ctx, outputPaths[0]) 71 h.module.outputFile = android.OptionalPathForPath(outputPath) 72 73 // HeaderLibraryInfo is an empty struct to indicate to dependencies that this is a header library 74 ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{}) 75 76 flagExporterInfo := flagExporterInfoFromCcInfo(ctx, ccInfo) 77 // Store flag info to be passed along to androimk 78 // TODO(b/184387147): Androidmk should be done in Bazel, not Soong. 79 h.library.flagExporterInfo = &flagExporterInfo 80 // flag exporters consolidates properties like includes, flags, dependencies that should be 81 // exported from this module to other modules 82 ctx.SetProvider(FlagExporterInfoProvider, flagExporterInfo) 83 84 // Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise 85 // validation will fail. For now, set this to an empty list. 86 // TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation. 87 h.library.collectedSnapshotHeaders = android.Paths{} 88 89 return true 90} 91 92// cc_library_headers contains a set of c/c++ headers which are imported by 93// other soong cc modules using the header_libs property. For best practices, 94// use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for 95// Make. 96func LibraryHeaderFactory() android.Module { 97 module, library := NewLibrary(android.HostAndDeviceSupported) 98 library.HeaderOnly() 99 module.sdkMemberTypes = []android.SdkMemberType{headersLibrarySdkMemberType} 100 module.bazelHandler = &libraryHeaderBazelHander{module: module, library: library} 101 return module.Init() 102} 103 104// cc_prebuilt_library_headers is a prebuilt version of cc_library_headers 105func prebuiltLibraryHeaderFactory() android.Module { 106 module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported) 107 library.HeaderOnly() 108 return module.Init() 109} 110 111type bazelCcLibraryHeadersAttributes struct { 112 Copts bazel.StringListAttribute 113 Hdrs bazel.LabelListAttribute 114 Includes bazel.StringListAttribute 115 Deps bazel.LabelListAttribute 116} 117 118type bazelCcLibraryHeaders struct { 119 android.BazelTargetModuleBase 120 bazelCcLibraryHeadersAttributes 121} 122 123func BazelCcLibraryHeadersFactory() android.Module { 124 module := &bazelCcLibraryHeaders{} 125 module.AddProperties(&module.bazelCcLibraryHeadersAttributes) 126 android.InitBazelTargetModule(module) 127 return module 128} 129 130func CcLibraryHeadersBp2Build(ctx android.TopDownMutatorContext) { 131 module, ok := ctx.Module().(*Module) 132 if !ok { 133 // Not a cc module 134 return 135 } 136 137 if !module.ConvertWithBp2build(ctx) { 138 return 139 } 140 141 if ctx.ModuleType() != "cc_library_headers" { 142 return 143 } 144 145 exportedIncludes := bp2BuildParseExportedIncludes(ctx, module) 146 compilerAttrs := bp2BuildParseCompilerProps(ctx, module) 147 linkerAttrs := bp2BuildParseLinkerProps(ctx, module) 148 149 attrs := &bazelCcLibraryHeadersAttributes{ 150 Copts: compilerAttrs.copts, 151 Includes: exportedIncludes, 152 Deps: linkerAttrs.deps, 153 } 154 155 props := bazel.BazelTargetModuleProperties{ 156 Rule_class: "cc_library_headers", 157 Bzl_load_location: "//build/bazel/rules:cc_library_headers.bzl", 158 } 159 160 ctx.CreateBazelTargetModule(BazelCcLibraryHeadersFactory, module.Name(), props, attrs) 161} 162 163func (m *bazelCcLibraryHeaders) Name() string { 164 return m.BaseModuleName() 165} 166 167func (m *bazelCcLibraryHeaders) GenerateAndroidBuildActions(ctx android.ModuleContext) {} 168