blob: ce9c4aacf74978480201876fd8317f159c125df5 [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
Yu Liue4312402023-01-18 09:15:31 -080062 bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
Chris Parsonsf874e462022-05-10 13:50:12 -040063}
64
65func (h *libraryHeaderBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
66 bazelCtx := ctx.Config().BazelContext
Yu Liue4312402023-01-18 09:15:31 -080067 ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(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
Sam Delmerico4ed95e22023-02-03 18:12:15 -050079 var outputPath android.Path = android.PathForBazelOut(ctx, outputPaths[0])
80 if len(ccInfo.TidyFiles) > 0 {
81 h.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
82 outputPath = android.AttachValidationActions(ctx, outputPath, h.module.tidyFiles)
83 }
Liz Kammerb6a55bf2021-04-12 15:42:51 -040084 h.module.outputFile = android.OptionalPathForPath(outputPath)
85
86 // HeaderLibraryInfo is an empty struct to indicate to dependencies that this is a header library
87 ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{})
88
Chris Parsons94a0bba2021-06-04 15:03:47 -040089 h.library.setFlagExporterInfoFromCcInfo(ctx, ccInfo)
Liz Kammerb6a55bf2021-04-12 15:42:51 -040090
91 // Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
92 // validation will fail. For now, set this to an empty list.
93 // TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation.
94 h.library.collectedSnapshotHeaders = android.Paths{}
Sam Delmerico5fb794a2023-01-27 16:01:37 -050095
96 h.module.setAndroidMkVariablesFromCquery(ccInfo.CcAndroidMkInfo)
Liz Kammerb6a55bf2021-04-12 15:42:51 -040097}
98
Paul Duffin1c6c1c72020-02-21 10:28:43 +000099// cc_library_headers contains a set of c/c++ headers which are imported by
100// other soong cc modules using the header_libs property. For best practices,
101// use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for
102// Make.
103func LibraryHeaderFactory() android.Module {
104 module, library := NewLibrary(android.HostAndDeviceSupported)
105 library.HeaderOnly()
Paul Duffin91756d22020-02-21 16:29:57 +0000106 module.sdkMemberTypes = []android.SdkMemberType{headersLibrarySdkMemberType}
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400107 module.bazelable = true
Chris Parsonsf874e462022-05-10 13:50:12 -0400108 module.bazelHandler = &libraryHeaderBazelHandler{module: module, library: library}
Paul Duffin1c6c1c72020-02-21 10:28:43 +0000109 return module.Init()
110}
Paul Duffinf5ea9e12020-02-21 10:57:00 +0000111
112// cc_prebuilt_library_headers is a prebuilt version of cc_library_headers
113func prebuiltLibraryHeaderFactory() android.Module {
Martin Stjernholme65c3ae2021-11-23 01:24:06 +0000114 module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "")
Paul Duffinf5ea9e12020-02-21 10:57:00 +0000115 library.HeaderOnly()
Liz Kammer3d3b35c2022-01-11 16:02:50 +0000116 module.bazelable = true
117 module.bazelHandler = &ccLibraryBazelHandler{module: module}
Paul Duffinf5ea9e12020-02-21 10:57:00 +0000118 return module.Init()
119}
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000120
121type bazelCcLibraryHeadersAttributes struct {
Liz Kammer1263d9b2021-12-10 14:28:20 -0500122 Hdrs bazel.LabelListAttribute
123 Export_includes bazel.StringListAttribute
124 Export_absolute_includes bazel.StringListAttribute
125 Export_system_includes bazel.StringListAttribute
126 Deps bazel.LabelListAttribute
127 Implementation_deps bazel.LabelListAttribute
128 System_dynamic_deps bazel.LabelListAttribute
Yu Liufc603162022-03-01 15:44:08 -0800129 sdkAttributes
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000130}
131
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400132func libraryHeadersBp2Build(ctx android.TopDownMutatorContext, module *Module) {
Liz Kammere6583482021-10-19 13:56:10 -0400133 baseAttributes := bp2BuildParseBaseProps(ctx, module)
Liz Kammer54549442022-05-11 13:55:06 -0400134 exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, &baseAttributes.includes)
Liz Kammere6583482021-10-19 13:56:10 -0400135 linkerAttrs := baseAttributes.linkerAttributes
Trevor Radcliffe2be7f542022-06-22 20:30:55 +0000136 (&linkerAttrs.deps).Append(linkerAttrs.dynamicDeps)
Trevor Radcliffe7f897fc2022-08-18 15:53:00 +0000137 (&linkerAttrs.deps).Append(linkerAttrs.wholeArchiveDeps)
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000138
139 attrs := &bazelCcLibraryHeadersAttributes{
Liz Kammer1263d9b2021-12-10 14:28:20 -0500140 Export_includes: exportedIncludes.Includes,
141 Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
142 Export_system_includes: exportedIncludes.SystemIncludes,
Liz Kammer1263d9b2021-12-10 14:28:20 -0500143 Deps: linkerAttrs.deps,
144 System_dynamic_deps: linkerAttrs.systemDynamicDeps,
145 Hdrs: baseAttributes.hdrs,
Yu Liufc603162022-03-01 15:44:08 -0800146 sdkAttributes: bp2BuildParseSdkAttributes(module),
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000147 }
148
Liz Kammerfc46bc12021-02-19 11:06:17 -0500149 props := bazel.BazelTargetModuleProperties{
150 Rule_class: "cc_library_headers",
Liz Kammer2b376bc2022-01-12 12:00:49 -0500151 Bzl_load_location: "//build/bazel/rules/cc:cc_library_headers.bzl",
Liz Kammerfc46bc12021-02-19 11:06:17 -0500152 }
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000153
Spandan Das39b6cc52023-04-12 19:05:49 +0000154 tags := android.ApexAvailableTagsWithoutTestApexes(ctx, module)
Sam Delmericoeddd3c02022-12-02 17:31:58 -0500155
156 ctx.CreateBazelTargetModule(props, android.CommonAttributes{
157 Name: module.Name(),
158 Tags: tags,
159 }, attrs)
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000160}
Spandan Das4238c652022-09-09 01:38:47 +0000161
162// Append .contribution suffix to input labels
163func apiBazelTargets(ll bazel.LabelList) bazel.LabelList {
164 labels := make([]bazel.Label, 0)
165 for _, l := range ll.Includes {
166 labels = append(labels, bazel.Label{
167 Label: android.ApiContributionTargetName(l.Label),
168 })
169 }
170 return bazel.MakeLabelList(labels)
171}
172
173func apiLibraryHeadersBp2Build(ctx android.TopDownMutatorContext, module *Module) {
174 // cc_api_library_headers have a 1:1 mapping to arch/no-arch
175 // For API export, create a top-level arch-agnostic target and list the arch-specific targets as its deps
176
177 // arch-agnostic includes
Spandan Das627fc3e2023-01-26 23:02:00 +0000178 apiIncludes := getModuleLibApiIncludes(ctx, module)
Spandan Das4238c652022-09-09 01:38:47 +0000179 // arch and os specific includes
180 archApiIncludes, androidOsIncludes := archOsSpecificApiIncludes(ctx, module)
181 for _, arch := range allArches { // sorted iteration
182 archApiInclude := archApiIncludes[arch]
183 if !archApiInclude.isEmpty() {
184 createApiHeaderTarget(ctx, archApiInclude)
185 apiIncludes.addDep(archApiInclude.name)
186 }
187 }
188 // os==android includes
189 if !androidOsIncludes.isEmpty() {
190 createApiHeaderTarget(ctx, androidOsIncludes)
191 apiIncludes.addDep(androidOsIncludes.name)
192 }
193
194 if !apiIncludes.isEmpty() {
Spandan Das627fc3e2023-01-26 23:02:00 +0000195 // override the name from <mod>.module-libapi.headers --> <mod>.contribution
Spandan Das4238c652022-09-09 01:38:47 +0000196 apiIncludes.name = android.ApiContributionTargetName(module.Name())
197 createApiHeaderTarget(ctx, apiIncludes)
198 }
199}
200
201func createApiHeaderTarget(ctx android.TopDownMutatorContext, includes apiIncludes) {
202 props := bazel.BazelTargetModuleProperties{
203 Rule_class: "cc_api_library_headers",
204 Bzl_load_location: "//build/bazel/rules/apis:cc_api_contribution.bzl",
205 }
206 ctx.CreateBazelTargetModule(
207 props,
208 android.CommonAttributes{
209 Name: includes.name,
210 SkipData: proptools.BoolPtr(true),
211 },
212 &includes.attrs,
213 )
214}
215
216var (
217 allArches = []string{"arm", "arm64", "x86", "x86_64"}
218)
219
220type archApiIncludes map[string]apiIncludes
221
222func archOsSpecificApiIncludes(ctx android.TopDownMutatorContext, module *Module) (archApiIncludes, apiIncludes) {
223 baseProps := bp2BuildParseBaseProps(ctx, module)
224 i := bp2BuildParseExportedIncludes(ctx, module, &baseProps.includes)
225 archRet := archApiIncludes{}
226 for _, arch := range allArches {
227 includes := i.Includes.SelectValue(
228 bazel.ArchConfigurationAxis,
229 arch)
230 systemIncludes := i.SystemIncludes.SelectValue(
231 bazel.ArchConfigurationAxis,
232 arch)
233 deps := baseProps.deps.SelectValue(
234 bazel.ArchConfigurationAxis,
235 arch)
236 attrs := bazelCcLibraryHeadersAttributes{
237 Export_includes: bazel.MakeStringListAttribute(includes),
238 Export_system_includes: bazel.MakeStringListAttribute(systemIncludes),
239 }
240 apiDeps := apiBazelTargets(deps)
241 if !apiDeps.IsEmpty() {
242 attrs.Deps = bazel.MakeLabelListAttribute(apiDeps)
243 }
244 apiIncludes := apiIncludes{
245 name: android.ApiContributionTargetName(module.Name()) + "." + arch,
246 attrs: bazelCcApiLibraryHeadersAttributes{
247 bazelCcLibraryHeadersAttributes: attrs,
248 Arch: proptools.StringPtr(arch),
249 },
250 }
251 archRet[arch] = apiIncludes
252 }
253
254 // apiIncludes for os == Android
255 androidOsDeps := baseProps.deps.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid)
256 androidOsAttrs := bazelCcLibraryHeadersAttributes{
257 Export_includes: bazel.MakeStringListAttribute(
258 i.Includes.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid),
259 ),
260 Export_system_includes: bazel.MakeStringListAttribute(
261 i.SystemIncludes.SelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid),
262 ),
263 }
264 androidOsApiDeps := apiBazelTargets(androidOsDeps)
265 if !androidOsApiDeps.IsEmpty() {
266 androidOsAttrs.Deps = bazel.MakeLabelListAttribute(androidOsApiDeps)
267 }
268 osRet := apiIncludes{
269 name: android.ApiContributionTargetName(module.Name()) + ".androidos",
270 attrs: bazelCcApiLibraryHeadersAttributes{
271 bazelCcLibraryHeadersAttributes: androidOsAttrs,
272 },
273 }
274 return archRet, osRet
275}