blob: 0bca30a7569aa3d8e2fb6b869b6294ce1a800f07 [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"
Rupert Shuttleworthb8151682021-04-06 20:06:21 +000019 "strings"
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...)
56 }
57 }
58
59 ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
60}
61
Jingwen Chen107c0de2021-04-09 10:43:12 +000062// Convenience struct to hold all attributes parsed from compiler properties.
63type compilerAttributes struct {
64 copts bazel.StringListAttribute
65 srcs bazel.LabelListAttribute
66 hdrs bazel.LabelListAttribute
67}
68
Jingwen Chen63930982021-03-24 10:04:33 -040069// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +000070func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
71 var hdrs, srcs bazel.LabelListAttribute
72 var copts bazel.StringListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -040073
74 hdrsAndSrcs := func(baseCompilerProps *BaseCompilerProperties) (bazel.LabelList, bazel.LabelList) {
75 srcsList := android.BazelLabelForModuleSrcExcludes(
76 ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
77 hdrsList := android.BazelLabelForModuleSrc(ctx, srcsList.LooseHdrsGlobs(headerExts))
78 return hdrsList, srcsList
79 }
80
Jingwen Chenc1c26502021-04-05 10:35:13 +000081 for _, props := range module.compiler.compilerProps() {
82 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Jingwen Chen63930982021-03-24 10:04:33 -040083 hdrs.Value, srcs.Value = hdrsAndSrcs(baseCompilerProps)
84 copts.Value = baseCompilerProps.Cflags
Jingwen Chenc1c26502021-04-05 10:35:13 +000085 break
86 }
87 }
88
89 for arch, props := range module.GetArchProperties(&BaseCompilerProperties{}) {
90 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Jingwen Chen63930982021-03-24 10:04:33 -040091 hdrsList, srcsList := hdrsAndSrcs(baseCompilerProps)
92 hdrs.SetValueForArch(arch.Name, bazel.SubtractBazelLabelList(hdrsList, hdrs.Value))
93 srcs.SetValueForArch(arch.Name, srcsList)
94 copts.SetValueForArch(arch.Name, baseCompilerProps.Cflags)
Jingwen Chenc1c26502021-04-05 10:35:13 +000095 }
96 }
97
98 for os, props := range module.GetTargetProperties(&BaseCompilerProperties{}) {
99 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Jingwen Chen63930982021-03-24 10:04:33 -0400100 hdrsList, srcsList := hdrsAndSrcs(baseCompilerProps)
101 hdrs.SetValueForOS(os.Name, bazel.SubtractBazelLabelList(hdrsList, hdrs.Value))
102 srcs.SetValueForOS(os.Name, srcsList)
103 copts.SetValueForOS(os.Name, baseCompilerProps.Cflags)
Jingwen Chenc1c26502021-04-05 10:35:13 +0000104 }
105 }
106
Jingwen Chen107c0de2021-04-09 10:43:12 +0000107 return compilerAttributes{
108 hdrs: hdrs,
109 srcs: srcs,
110 copts: copts,
111 }
112}
113
114// Convenience struct to hold all attributes parsed from linker properties.
115type linkerAttributes struct {
116 deps bazel.LabelListAttribute
117 linkopts bazel.StringListAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000118}
119
Jingwen Chen63930982021-03-24 10:04:33 -0400120// bp2BuildParseLinkerProps creates a label list attribute containing the header library deps of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400121// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000122func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Jingwen Chen63930982021-03-24 10:04:33 -0400123
124 var deps bazel.LabelListAttribute
125 var linkopts bazel.StringListAttribute
126
Jingwen Chen91220d72021-03-24 02:18:33 -0400127 for _, linkerProps := range module.linker.linkerProps() {
128 if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
129 libs := baseLinkerProps.Header_libs
130 libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
Jingwen Chen63930982021-03-24 10:04:33 -0400131 deps = bazel.MakeLabelListAttribute(
Jingwen Chen91220d72021-03-24 02:18:33 -0400132 android.BazelLabelForModuleDeps(ctx, android.SortedUniqueStrings(libs)))
Jingwen Chen63930982021-03-24 10:04:33 -0400133 linkopts.Value = baseLinkerProps.Ldflags
Jingwen Chen91220d72021-03-24 02:18:33 -0400134 break
135 }
136 }
137
Jingwen Chen63930982021-03-24 10:04:33 -0400138 for arch, p := range module.GetArchProperties(&BaseLinkerProperties{}) {
139 if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
140 libs := baseLinkerProps.Header_libs
141 libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
142 libs = android.SortedUniqueStrings(libs)
143 deps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, libs))
144 linkopts.SetValueForArch(arch.Name, baseLinkerProps.Ldflags)
145 }
146 }
147
Jingwen Chen91220d72021-03-24 02:18:33 -0400148 for os, p := range module.GetTargetProperties(&BaseLinkerProperties{}) {
149 if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
150 libs := baseLinkerProps.Header_libs
151 libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
152 libs = android.SortedUniqueStrings(libs)
Jingwen Chen63930982021-03-24 10:04:33 -0400153 deps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
154 linkopts.SetValueForOS(os.Name, baseLinkerProps.Ldflags)
Jingwen Chen91220d72021-03-24 02:18:33 -0400155 }
156 }
157
Jingwen Chen107c0de2021-04-09 10:43:12 +0000158 return linkerAttributes{
159 deps: deps,
160 linkopts: linkopts,
161 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400162}
163
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000164func bp2BuildListHeadersInDir(ctx android.TopDownMutatorContext, includeDir string) bazel.LabelList {
Jingwen Chen63930982021-03-24 10:04:33 -0400165 globs := bazel.GlobsInDir(includeDir, includeDir != ".", headerExts)
166 return android.BazelLabelForModuleSrc(ctx, globs)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000167}
168
169// Bazel wants include paths to be relative to the module
170func bp2BuildMakePathsRelativeToModule(ctx android.TopDownMutatorContext, paths []string) []string {
171 var relativePaths []string
172 for _, path := range paths {
173 relativePath := strings.TrimPrefix(path, ctx.ModuleDir()+"/")
174 relativePaths = append(relativePaths, relativePath)
175 }
176 return relativePaths
177}
178
Jingwen Chen91220d72021-03-24 02:18:33 -0400179// bp2BuildParseExportedIncludes creates a label list attribute contains the
180// exported included directories of a module.
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000181func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) (bazel.StringListAttribute, bazel.LabelListAttribute) {
Jingwen Chen91220d72021-03-24 02:18:33 -0400182 libraryDecorator := module.linker.(*libraryDecorator)
183
184 includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
185 includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000186 includeDirs = bp2BuildMakePathsRelativeToModule(ctx, includeDirs)
187 includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
Jingwen Chen91220d72021-03-24 02:18:33 -0400188
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000189 var headersAttribute bazel.LabelListAttribute
190 var headers bazel.LabelList
Jingwen Chen91220d72021-03-24 02:18:33 -0400191 for _, includeDir := range includeDirs {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000192 headers.Append(bp2BuildListHeadersInDir(ctx, includeDir))
193 }
194 headers = bazel.UniqueBazelLabelList(headers)
195 headersAttribute.Value = headers
196
197 for arch, props := range module.GetArchProperties(&FlagExporterProperties{}) {
198 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
199 archIncludeDirs := flagExporterProperties.Export_system_include_dirs
200 archIncludeDirs = append(archIncludeDirs, flagExporterProperties.Export_include_dirs...)
201 archIncludeDirs = bp2BuildMakePathsRelativeToModule(ctx, archIncludeDirs)
202
203 // To avoid duplicate includes when base includes + arch includes are combined
204 archIncludeDirs = bazel.SubtractStrings(archIncludeDirs, includeDirs)
205
206 if len(archIncludeDirs) > 0 {
207 includeDirsAttribute.SetValueForArch(arch.Name, archIncludeDirs)
208 }
209
210 var archHeaders bazel.LabelList
211 for _, archIncludeDir := range archIncludeDirs {
212 archHeaders.Append(bp2BuildListHeadersInDir(ctx, archIncludeDir))
213 }
214 archHeaders = bazel.UniqueBazelLabelList(archHeaders)
215
216 // To avoid duplicate headers when base headers + arch headers are combined
217 archHeaders = bazel.SubtractBazelLabelList(archHeaders, headers)
218
219 if len(archHeaders.Includes) > 0 || len(archHeaders.Excludes) > 0 {
220 headersAttribute.SetValueForArch(arch.Name, archHeaders)
221 }
222 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400223 }
224
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000225 return includeDirsAttribute, headersAttribute
Jingwen Chen91220d72021-03-24 02:18:33 -0400226}