blob: 4d38068fdbae3e810caa149de6d3f5acfa33a755 [file] [log] [blame]
Paul Duffin1c6c1c72020-02-21 10:28:43 +00001// 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
Rupert Shuttleworth54e78412021-02-15 11:04:32 +000017import (
Spandan Das4238c652022-09-09 01:38:47 +000018 "github.com/google/blueprint/proptools"
19
Rupert Shuttleworth54e78412021-02-15 11:04:32 +000020 "android/soong/android"
21 "android/soong/bazel"
Chris Parsonsf874e462022-05-10 13:50:12 -040022 "android/soong/bazel/cquery"
Rupert Shuttleworth54e78412021-02-15 11:04:32 +000023)
Paul Duffin1c6c1c72020-02-21 10:28:43 +000024
25func init() {
26 RegisterLibraryHeadersBuildComponents(android.InitRegistrationContext)
Paul Duffin91756d22020-02-21 16:29:57 +000027
28 // Register sdk member types.
29 android.RegisterSdkMemberType(headersLibrarySdkMemberType)
Rupert Shuttleworth54e78412021-02-15 11:04:32 +000030
Paul Duffin91756d22020-02-21 16:29:57 +000031}
32
33var headersLibrarySdkMemberType = &librarySdkMemberType{
34 SdkMemberTypeBase: android.SdkMemberTypeBase{
Martin Stjernholmcaa47d72020-07-11 04:52:24 +010035 PropertyName: "native_header_libs",
36 SupportsSdk: true,
37 HostOsDependent: true,
Paul Duffin93b750e2019-11-19 19:44:10 +000038 Traits: []android.SdkMemberTrait{
39 nativeBridgeSdkTrait,
Paul Duffin12a0a312021-09-15 17:25:10 +010040 ramdiskImageRequiredSdkTrait,
Paul Duffin63696222021-09-06 10:28:34 +010041 recoveryImageRequiredSdkTrait,
Paul Duffin93b750e2019-11-19 19:44:10 +000042 },
Paul Duffin91756d22020-02-21 16:29:57 +000043 },
44 prebuiltModuleType: "cc_prebuilt_library_headers",
Martin Stjernholmcd07bce2020-03-10 22:37:59 +000045 noOutputFiles: true,
Paul Duffin1c6c1c72020-02-21 10:28:43 +000046}
47
48func RegisterLibraryHeadersBuildComponents(ctx android.RegistrationContext) {
49 ctx.RegisterModuleType("cc_library_headers", LibraryHeaderFactory)
Paul Duffinf5ea9e12020-02-21 10:57:00 +000050 ctx.RegisterModuleType("cc_prebuilt_library_headers", prebuiltLibraryHeaderFactory)
Paul Duffin1c6c1c72020-02-21 10:28:43 +000051}
52
Chris Parsonsf874e462022-05-10 13:50:12 -040053type libraryHeaderBazelHandler struct {
Liz Kammerb6a55bf2021-04-12 15:42:51 -040054 module *Module
55 library *libraryDecorator
56}
57
Chris Parsons6ce2cf92022-05-20 10:54:17 -040058var _ BazelHandler = (*libraryHeaderBazelHandler)(nil)
59
Chris Parsonsf874e462022-05-10 13:50:12 -040060func (handler *libraryHeaderBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
Liz Kammerb6a55bf2021-04-12 15:42:51 -040061 bazelCtx := ctx.Config().BazelContext
Chris Parsonsf874e462022-05-10 13:50:12 -040062 bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKey(ctx))
63}
64
65func (h *libraryHeaderBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
66 bazelCtx := ctx.Config().BazelContext
67 ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
Liz Kammerb6a55bf2021-04-12 15:42:51 -040068 if err != nil {
Chris Parsonsf874e462022-05-10 13:50:12 -040069 ctx.ModuleErrorf(err.Error())
70 return
Liz Kammerb6a55bf2021-04-12 15:42:51 -040071 }
72
73 outputPaths := ccInfo.OutputFiles
74 if len(outputPaths) != 1 {
75 ctx.ModuleErrorf("expected exactly one output file for %q, but got %q", label, outputPaths)
Chris Parsonsf874e462022-05-10 13:50:12 -040076 return
Liz Kammerb6a55bf2021-04-12 15:42:51 -040077 }
78
79 outputPath := android.PathForBazelOut(ctx, outputPaths[0])
80 h.module.outputFile = android.OptionalPathForPath(outputPath)
81
82 // HeaderLibraryInfo is an empty struct to indicate to dependencies that this is a header library
83 ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{})
84
Chris Parsons94a0bba2021-06-04 15:03:47 -040085 h.library.setFlagExporterInfoFromCcInfo(ctx, ccInfo)
Liz Kammerb6a55bf2021-04-12 15:42:51 -040086
87 // Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
88 // validation will fail. For now, set this to an empty list.
89 // TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation.
90 h.library.collectedSnapshotHeaders = android.Paths{}
Liz Kammerb6a55bf2021-04-12 15:42:51 -040091}
92
Paul Duffin1c6c1c72020-02-21 10:28:43 +000093// cc_library_headers contains a set of c/c++ headers which are imported by
94// other soong cc modules using the header_libs property. For best practices,
95// use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for
96// Make.
97func LibraryHeaderFactory() android.Module {
98 module, library := NewLibrary(android.HostAndDeviceSupported)
99 library.HeaderOnly()
Paul Duffin91756d22020-02-21 16:29:57 +0000100 module.sdkMemberTypes = []android.SdkMemberType{headersLibrarySdkMemberType}
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400101 module.bazelable = true
Chris Parsonsf874e462022-05-10 13:50:12 -0400102 module.bazelHandler = &libraryHeaderBazelHandler{module: module, library: library}
Paul Duffin1c6c1c72020-02-21 10:28:43 +0000103 return module.Init()
104}
Paul Duffinf5ea9e12020-02-21 10:57:00 +0000105
106// cc_prebuilt_library_headers is a prebuilt version of cc_library_headers
107func prebuiltLibraryHeaderFactory() android.Module {
Martin Stjernholme65c3ae2021-11-23 01:24:06 +0000108 module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "")
Paul Duffinf5ea9e12020-02-21 10:57:00 +0000109 library.HeaderOnly()
Liz Kammer3d3b35c2022-01-11 16:02:50 +0000110 module.bazelable = true
111 module.bazelHandler = &ccLibraryBazelHandler{module: module}
Paul Duffinf5ea9e12020-02-21 10:57:00 +0000112 return module.Init()
113}
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000114
115type bazelCcLibraryHeadersAttributes struct {
Liz Kammer1263d9b2021-12-10 14:28:20 -0500116 Hdrs bazel.LabelListAttribute
117 Export_includes bazel.StringListAttribute
118 Export_absolute_includes bazel.StringListAttribute
119 Export_system_includes bazel.StringListAttribute
120 Deps bazel.LabelListAttribute
121 Implementation_deps bazel.LabelListAttribute
122 System_dynamic_deps bazel.LabelListAttribute
Yu Liufc603162022-03-01 15:44:08 -0800123 sdkAttributes
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000124}
125
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400126func libraryHeadersBp2Build(ctx android.TopDownMutatorContext, module *Module) {
Liz Kammere6583482021-10-19 13:56:10 -0400127 baseAttributes := bp2BuildParseBaseProps(ctx, module)
Liz Kammer54549442022-05-11 13:55:06 -0400128 exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, &baseAttributes.includes)
Liz Kammere6583482021-10-19 13:56:10 -0400129 linkerAttrs := baseAttributes.linkerAttributes
Trevor Radcliffe2be7f542022-06-22 20:30:55 +0000130 (&linkerAttrs.deps).Append(linkerAttrs.dynamicDeps)
Trevor Radcliffe7f897fc2022-08-18 15:53:00 +0000131 (&linkerAttrs.deps).Append(linkerAttrs.wholeArchiveDeps)
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000132
133 attrs := &bazelCcLibraryHeadersAttributes{
Liz Kammer1263d9b2021-12-10 14:28:20 -0500134 Export_includes: exportedIncludes.Includes,
135 Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
136 Export_system_includes: exportedIncludes.SystemIncludes,
Liz Kammer1263d9b2021-12-10 14:28:20 -0500137 Deps: linkerAttrs.deps,
138 System_dynamic_deps: linkerAttrs.systemDynamicDeps,
139 Hdrs: baseAttributes.hdrs,
Yu Liufc603162022-03-01 15:44:08 -0800140 sdkAttributes: bp2BuildParseSdkAttributes(module),
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000141 }
142
Liz Kammerfc46bc12021-02-19 11:06:17 -0500143 props := bazel.BazelTargetModuleProperties{
144 Rule_class: "cc_library_headers",
Liz Kammer2b376bc2022-01-12 12:00:49 -0500145 Bzl_load_location: "//build/bazel/rules/cc:cc_library_headers.bzl",
Liz Kammerfc46bc12021-02-19 11:06:17 -0500146 }
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000147
Sam Delmericoeddd3c02022-12-02 17:31:58 -0500148 tags := android.ApexAvailableTags(module)
149
150 ctx.CreateBazelTargetModule(props, android.CommonAttributes{
151 Name: module.Name(),
152 Tags: tags,
153 }, attrs)
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000154}
Spandan Das4238c652022-09-09 01:38:47 +0000155
156// Append .contribution suffix to input labels
157func apiBazelTargets(ll bazel.LabelList) bazel.LabelList {
158 labels := make([]bazel.Label, 0)
159 for _, l := range ll.Includes {
160 labels = append(labels, bazel.Label{
161 Label: android.ApiContributionTargetName(l.Label),
162 })
163 }
164 return bazel.MakeLabelList(labels)
165}
166
167func apiLibraryHeadersBp2Build(ctx android.TopDownMutatorContext, module *Module) {
168 // cc_api_library_headers have a 1:1 mapping to arch/no-arch
169 // For API export, create a top-level arch-agnostic target and list the arch-specific targets as its deps
170
171 // arch-agnostic includes
172 apiIncludes := getSystemApiIncludes(ctx, module)
173 // arch and os specific includes
174 archApiIncludes, androidOsIncludes := archOsSpecificApiIncludes(ctx, module)
175 for _, arch := range allArches { // sorted iteration
176 archApiInclude := archApiIncludes[arch]
177 if !archApiInclude.isEmpty() {
178 createApiHeaderTarget(ctx, archApiInclude)
179 apiIncludes.addDep(archApiInclude.name)
180 }
181 }
182 // os==android includes
183 if !androidOsIncludes.isEmpty() {
184 createApiHeaderTarget(ctx, androidOsIncludes)
185 apiIncludes.addDep(androidOsIncludes.name)
186 }
187
188 if !apiIncludes.isEmpty() {
189 // override the name from <mod>.systemapi.headers --> <mod>.contribution
190 apiIncludes.name = android.ApiContributionTargetName(module.Name())
191 createApiHeaderTarget(ctx, apiIncludes)
192 }
193}
194
195func createApiHeaderTarget(ctx android.TopDownMutatorContext, includes apiIncludes) {
196 props := bazel.BazelTargetModuleProperties{
197 Rule_class: "cc_api_library_headers",
198 Bzl_load_location: "//build/bazel/rules/apis:cc_api_contribution.bzl",
199 }
200 ctx.CreateBazelTargetModule(
201 props,
202 android.CommonAttributes{
203 Name: includes.name,
204 SkipData: proptools.BoolPtr(true),
205 },
206 &includes.attrs,
207 )
208}
209
210var (
211 allArches = []string{"arm", "arm64", "x86", "x86_64"}
212)
213
214type archApiIncludes map[string]apiIncludes
215
216func archOsSpecificApiIncludes(ctx android.TopDownMutatorContext, module *Module) (archApiIncludes, apiIncludes) {
217 baseProps := bp2BuildParseBaseProps(ctx, module)
218 i := bp2BuildParseExportedIncludes(ctx, module, &baseProps.includes)
219 archRet := archApiIncludes{}
220 for _, arch := range allArches {
221 includes := i.Includes.SelectValue(
222 bazel.ArchConfigurationAxis,
223 arch)
224 systemIncludes := i.SystemIncludes.SelectValue(
225 bazel.ArchConfigurationAxis,
226 arch)
227 deps := baseProps.deps.SelectValue(
228 bazel.ArchConfigurationAxis,
229 arch)
230 attrs := bazelCcLibraryHeadersAttributes{
231 Export_includes: bazel.MakeStringListAttribute(includes),
232 Export_system_includes: bazel.MakeStringListAttribute(systemIncludes),
233 }
234 apiDeps := apiBazelTargets(deps)
235 if !apiDeps.IsEmpty() {
236 attrs.Deps = bazel.MakeLabelListAttribute(apiDeps)
237 }
238 apiIncludes := apiIncludes{
239 name: android.ApiContributionTargetName(module.Name()) + "." + arch,
240 attrs: bazelCcApiLibraryHeadersAttributes{
241 bazelCcLibraryHeadersAttributes: attrs,
242 Arch: proptools.StringPtr(arch),
243 },
244 }
245 archRet[arch] = apiIncludes
246 }
247
248 // apiIncludes for os == Android
249 androidOsDeps := baseProps.deps.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid)
250 androidOsAttrs := bazelCcLibraryHeadersAttributes{
251 Export_includes: bazel.MakeStringListAttribute(
252 i.Includes.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid),
253 ),
254 Export_system_includes: bazel.MakeStringListAttribute(
255 i.SystemIncludes.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid),
256 ),
257 }
258 androidOsApiDeps := apiBazelTargets(androidOsDeps)
259 if !androidOsApiDeps.IsEmpty() {
260 androidOsAttrs.Deps = bazel.MakeLabelListAttribute(androidOsApiDeps)
261 }
262 osRet := apiIncludes{
263 name: android.ApiContributionTargetName(module.Name()) + ".androidos",
264 attrs: bazelCcApiLibraryHeadersAttributes{
265 bazelCcLibraryHeadersAttributes: androidOsAttrs,
266 },
267 }
268 return archRet, osRet
269}