blob: efa275222698297a39ae3fa092678fb7cf7ac60c [file] [log] [blame]
Jingwen Chen91220d72021-03-24 02:18:33 -04001// Copyright 2021 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.
14package cc
15
16import (
17 "android/soong/android"
18 "android/soong/bazel"
Jingwen Chened9c17d2021-04-13 07:14:55 +000019 "path/filepath"
Jingwen Chen91220d72021-03-24 02:18:33 -040020)
21
22// bp2build functions and helpers for converting cc_* modules to Bazel.
23
24func init() {
25 android.DepsBp2BuildMutators(RegisterDepsBp2Build)
26}
27
28func RegisterDepsBp2Build(ctx android.RegisterMutatorsContext) {
29 ctx.BottomUp("cc_bp2build_deps", depsBp2BuildMutator)
30}
31
32// A naive deps mutator to add deps on all modules across all combinations of
33// target props for cc modules. This is needed to make module -> bazel label
34// resolution work in the bp2build mutator later. This is probably
35// the wrong way to do it, but it works.
36//
37// TODO(jingwen): can we create a custom os mutator in depsBp2BuildMutator to do this?
38func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) {
39 module, ok := ctx.Module().(*Module)
40 if !ok {
41 // Not a cc module
42 return
43 }
44
45 if !module.ConvertWithBp2build(ctx) {
46 return
47 }
48
49 var allDeps []string
50
51 for _, p := range module.GetTargetProperties(&BaseLinkerProperties{}) {
52 // arch specific linker props
53 if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
54 allDeps = append(allDeps, baseLinkerProps.Header_libs...)
55 allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...)
Jingwen Chened9c17d2021-04-13 07:14:55 +000056 allDeps = append(allDeps, baseLinkerProps.Static_libs...)
57 allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...)
58 }
59 }
60
61 for _, p := range module.GetArchProperties(&BaseLinkerProperties{}) {
62 // arch specific linker props
63 if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
64 allDeps = append(allDeps, baseLinkerProps.Header_libs...)
65 allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...)
66 allDeps = append(allDeps, baseLinkerProps.Static_libs...)
67 allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...)
Jingwen Chen91220d72021-03-24 02:18:33 -040068 }
69 }
70
71 ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
72}
73
Jingwen Chen107c0de2021-04-09 10:43:12 +000074// Convenience struct to hold all attributes parsed from compiler properties.
75type compilerAttributes struct {
Jingwen Chened9c17d2021-04-13 07:14:55 +000076 copts bazel.StringListAttribute
77 srcs bazel.LabelListAttribute
78 includes bazel.StringListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +000079}
80
Jingwen Chen63930982021-03-24 10:04:33 -040081// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +000082func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
Jingwen Chened9c17d2021-04-13 07:14:55 +000083 var localHdrs, srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +000084 var copts bazel.StringListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -040085
Jingwen Chened9c17d2021-04-13 07:14:55 +000086 // Creates the -I flag for a directory, while making the directory relative
87 // to the exec root for Bazel to work.
88 includeFlag := func(dir string) string {
89 // filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
90 return "-I" + filepath.Join(ctx.ModuleDir(), dir)
91 }
92
93 // Parse the list of srcs, excluding files from exclude_srcs.
94 parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
95 return android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
96 }
97
98 // Parse the list of module-relative include directories (-I).
99 parseLocalIncludeDirs := func(baseCompilerProps *BaseCompilerProperties) []string {
100 // include_dirs are root-relative, not module-relative.
101 includeDirs := bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
102 return append(includeDirs, baseCompilerProps.Local_include_dirs...)
103 }
104
105 // Parse the list of copts.
106 parseCopts := func(baseCompilerProps *BaseCompilerProperties) []string {
107 copts := append([]string{}, baseCompilerProps.Cflags...)
108 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
109 copts = append(copts, includeFlag(dir))
110 }
111 return copts
Jingwen Chen63930982021-03-24 10:04:33 -0400112 }
113
Jingwen Chenc1c26502021-04-05 10:35:13 +0000114 for _, props := range module.compiler.compilerProps() {
115 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000116 srcs.Value = parseSrcs(baseCompilerProps)
117 copts.Value = parseCopts(baseCompilerProps)
Jingwen Chenc1c26502021-04-05 10:35:13 +0000118 break
119 }
120 }
121
Jingwen Chened9c17d2021-04-13 07:14:55 +0000122 if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
123 copts.Value = append(copts.Value, includeFlag("."))
124 localHdrs.Value = bp2BuildListHeadersInDir(ctx, ".")
125 } else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
126 copts.Value = append(copts.Value, includeFlag("."))
127 localHdrs.Value = bp2BuildListHeadersInDir(ctx, ".")
128 }
129
Jingwen Chenc1c26502021-04-05 10:35:13 +0000130 for arch, props := range module.GetArchProperties(&BaseCompilerProperties{}) {
131 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000132 srcsList := parseSrcs(baseCompilerProps)
133 srcs.SetValueForArch(arch.Name, bazel.SubtractBazelLabelList(srcsList, srcs.Value))
134 copts.SetValueForArch(arch.Name, parseCopts(baseCompilerProps))
Jingwen Chenc1c26502021-04-05 10:35:13 +0000135 }
136 }
137
138 for os, props := range module.GetTargetProperties(&BaseCompilerProperties{}) {
139 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000140 srcsList := parseSrcs(baseCompilerProps)
141 srcs.SetValueForOS(os.Name, bazel.SubtractBazelLabelList(srcsList, srcs.Value))
142 copts.SetValueForOS(os.Name, parseCopts(baseCompilerProps))
Jingwen Chenc1c26502021-04-05 10:35:13 +0000143 }
144 }
145
Jingwen Chened9c17d2021-04-13 07:14:55 +0000146 // Combine local, non-exported hdrs into srcs
147 srcs.Append(localHdrs)
148
Jingwen Chen107c0de2021-04-09 10:43:12 +0000149 return compilerAttributes{
Jingwen Chen107c0de2021-04-09 10:43:12 +0000150 srcs: srcs,
151 copts: copts,
152 }
153}
154
155// Convenience struct to hold all attributes parsed from linker properties.
156type linkerAttributes struct {
157 deps bazel.LabelListAttribute
158 linkopts bazel.StringListAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000159}
160
Jingwen Chen63930982021-03-24 10:04:33 -0400161// bp2BuildParseLinkerProps creates a label list attribute containing the header library deps of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400162// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000163func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Jingwen Chen63930982021-03-24 10:04:33 -0400164 var deps bazel.LabelListAttribute
165 var linkopts bazel.StringListAttribute
166
Jingwen Chen91220d72021-03-24 02:18:33 -0400167 for _, linkerProps := range module.linker.linkerProps() {
168 if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
169 libs := baseLinkerProps.Header_libs
170 libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000171 libs = append(libs, baseLinkerProps.Static_libs...)
172 libs = append(libs, baseLinkerProps.Whole_static_libs...)
173 libs = android.SortedUniqueStrings(libs)
174 deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, libs))
Jingwen Chen63930982021-03-24 10:04:33 -0400175 linkopts.Value = baseLinkerProps.Ldflags
Jingwen Chen91220d72021-03-24 02:18:33 -0400176 break
177 }
178 }
179
Jingwen Chen63930982021-03-24 10:04:33 -0400180 for arch, p := range module.GetArchProperties(&BaseLinkerProperties{}) {
181 if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
182 libs := baseLinkerProps.Header_libs
183 libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000184 libs = append(libs, baseLinkerProps.Static_libs...)
185 libs = append(libs, baseLinkerProps.Whole_static_libs...)
Jingwen Chen63930982021-03-24 10:04:33 -0400186 libs = android.SortedUniqueStrings(libs)
187 deps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, libs))
188 linkopts.SetValueForArch(arch.Name, baseLinkerProps.Ldflags)
189 }
190 }
191
Jingwen Chen91220d72021-03-24 02:18:33 -0400192 for os, p := range module.GetTargetProperties(&BaseLinkerProperties{}) {
193 if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
194 libs := baseLinkerProps.Header_libs
195 libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000196 libs = append(libs, baseLinkerProps.Static_libs...)
197 libs = append(libs, baseLinkerProps.Whole_static_libs...)
Jingwen Chen91220d72021-03-24 02:18:33 -0400198 libs = android.SortedUniqueStrings(libs)
Jingwen Chen63930982021-03-24 10:04:33 -0400199 deps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
200 linkopts.SetValueForOS(os.Name, baseLinkerProps.Ldflags)
Jingwen Chen91220d72021-03-24 02:18:33 -0400201 }
202 }
203
Jingwen Chen107c0de2021-04-09 10:43:12 +0000204 return linkerAttributes{
205 deps: deps,
206 linkopts: linkopts,
207 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400208}
209
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000210func bp2BuildListHeadersInDir(ctx android.TopDownMutatorContext, includeDir string) bazel.LabelList {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000211 globs := bazel.GlobsInDir(includeDir, true, headerExts)
Jingwen Chen63930982021-03-24 10:04:33 -0400212 return android.BazelLabelForModuleSrc(ctx, globs)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000213}
214
Jingwen Chened9c17d2021-04-13 07:14:55 +0000215// Relativize a list of root-relative paths with respect to the module's
216// directory.
217//
218// include_dirs Soong prop are root-relative (b/183742505), but
219// local_include_dirs, export_include_dirs and export_system_include_dirs are
220// module dir relative. This function makes a list of paths entirely module dir
221// relative.
222//
223// For the `include` attribute, Bazel wants the paths to be relative to the
224// module.
225func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000226 var relativePaths []string
227 for _, path := range paths {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000228 // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
229 relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
230 if err != nil {
231 panic(err)
232 }
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000233 relativePaths = append(relativePaths, relativePath)
234 }
235 return relativePaths
236}
237
Jingwen Chened9c17d2021-04-13 07:14:55 +0000238// bp2BuildParseExportedIncludes creates a string list attribute contains the
239// exported included directories of a module, and a label list attribute
240// containing the exported headers of a module.
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000241func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) (bazel.StringListAttribute, bazel.LabelListAttribute) {
Jingwen Chen91220d72021-03-24 02:18:33 -0400242 libraryDecorator := module.linker.(*libraryDecorator)
243
Jingwen Chened9c17d2021-04-13 07:14:55 +0000244 // Export_system_include_dirs and export_include_dirs are already module dir
245 // relative, so they don't need to be relativized like include_dirs, which
246 // are root-relative.
Jingwen Chen91220d72021-03-24 02:18:33 -0400247 includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
248 includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000249 includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
Jingwen Chen91220d72021-03-24 02:18:33 -0400250
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000251 var headersAttribute bazel.LabelListAttribute
252 var headers bazel.LabelList
Jingwen Chen91220d72021-03-24 02:18:33 -0400253 for _, includeDir := range includeDirs {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000254 headers.Append(bp2BuildListHeadersInDir(ctx, includeDir))
255 }
256 headers = bazel.UniqueBazelLabelList(headers)
257 headersAttribute.Value = headers
258
259 for arch, props := range module.GetArchProperties(&FlagExporterProperties{}) {
260 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
261 archIncludeDirs := flagExporterProperties.Export_system_include_dirs
262 archIncludeDirs = append(archIncludeDirs, flagExporterProperties.Export_include_dirs...)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000263
264 // To avoid duplicate includes when base includes + arch includes are combined
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400265 // FIXME: This doesn't take conflicts between arch and os includes into account
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000266 archIncludeDirs = bazel.SubtractStrings(archIncludeDirs, includeDirs)
267
268 if len(archIncludeDirs) > 0 {
269 includeDirsAttribute.SetValueForArch(arch.Name, archIncludeDirs)
270 }
271
272 var archHeaders bazel.LabelList
273 for _, archIncludeDir := range archIncludeDirs {
274 archHeaders.Append(bp2BuildListHeadersInDir(ctx, archIncludeDir))
275 }
276 archHeaders = bazel.UniqueBazelLabelList(archHeaders)
277
278 // To avoid duplicate headers when base headers + arch headers are combined
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400279 // FIXME: This doesn't take conflicts between arch and os includes into account
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000280 archHeaders = bazel.SubtractBazelLabelList(archHeaders, headers)
281
282 if len(archHeaders.Includes) > 0 || len(archHeaders.Excludes) > 0 {
283 headersAttribute.SetValueForArch(arch.Name, archHeaders)
284 }
285 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400286 }
287
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400288 for os, props := range module.GetTargetProperties(&FlagExporterProperties{}) {
289 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
290 osIncludeDirs := flagExporterProperties.Export_system_include_dirs
291 osIncludeDirs = append(osIncludeDirs, flagExporterProperties.Export_include_dirs...)
292
293 // To avoid duplicate includes when base includes + os includes are combined
294 // FIXME: This doesn't take conflicts between arch and os includes into account
295 osIncludeDirs = bazel.SubtractStrings(osIncludeDirs, includeDirs)
296
297 if len(osIncludeDirs) > 0 {
298 includeDirsAttribute.SetValueForOS(os.Name, osIncludeDirs)
299 }
300
301 var osHeaders bazel.LabelList
302 for _, osIncludeDir := range osIncludeDirs {
303 osHeaders.Append(bp2BuildListHeadersInDir(ctx, osIncludeDir))
304 }
305 osHeaders = bazel.UniqueBazelLabelList(osHeaders)
306
307 // To avoid duplicate headers when base headers + os headers are combined
308 // FIXME: This doesn't take conflicts between arch and os includes into account
309 osHeaders = bazel.SubtractBazelLabelList(osHeaders, headers)
310
311 if len(osHeaders.Includes) > 0 || len(osHeaders.Excludes) > 0 {
312 headersAttribute.SetValueForOS(os.Name, osHeaders)
313 }
314 }
315 }
316
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000317 return includeDirsAttribute, headersAttribute
Jingwen Chen91220d72021-03-24 02:18:33 -0400318}