blob: cffeb24748d49a7c9767d15da7b2baa9ac48bf96 [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 Chenc1c26502021-04-05 10:35:13 +000062// bp2buildParseCflags creates a label list attribute containing the cflags of a module, including
63func bp2BuildParseCflags(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
64 var ret bazel.StringListAttribute
65 for _, props := range module.compiler.compilerProps() {
66 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
67 ret.Value = baseCompilerProps.Cflags
68 break
69 }
70 }
71
72 for arch, props := range module.GetArchProperties(&BaseCompilerProperties{}) {
73 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
74 ret.SetValueForArch(arch.Name, baseCompilerProps.Cflags)
75 }
76 }
77
78 for os, props := range module.GetTargetProperties(&BaseCompilerProperties{}) {
79 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
80 ret.SetValueForOS(os.Name, baseCompilerProps.Cflags)
81 }
82 }
83
84 return ret
85}
86
Jingwen Chen91220d72021-03-24 02:18:33 -040087// bp2BuildParseHeaderLibs creates a label list attribute containing the header library deps of a module, including
88// configurable attribute values.
89func bp2BuildParseHeaderLibs(ctx android.TopDownMutatorContext, module *Module) bazel.LabelListAttribute {
90 var ret bazel.LabelListAttribute
91 for _, linkerProps := range module.linker.linkerProps() {
92 if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
93 libs := baseLinkerProps.Header_libs
94 libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
95 ret = bazel.MakeLabelListAttribute(
96 android.BazelLabelForModuleDeps(ctx, android.SortedUniqueStrings(libs)))
97 break
98 }
99 }
100
101 for os, p := range module.GetTargetProperties(&BaseLinkerProperties{}) {
102 if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
103 libs := baseLinkerProps.Header_libs
104 libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
105 libs = android.SortedUniqueStrings(libs)
106 ret.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
107 }
108 }
109
110 return ret
111}
112
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000113func bp2BuildListHeadersInDir(ctx android.TopDownMutatorContext, includeDir string) bazel.LabelList {
114 var globInfix string
115
116 if includeDir == "." {
117 globInfix = ""
118 } else {
119 globInfix = "/**"
120 }
121
122 var includeDirGlobs []string
123 includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.h")
124 includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.inc")
125 includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.hpp")
126
127 return android.BazelLabelForModuleSrc(ctx, includeDirGlobs)
128}
129
130// Bazel wants include paths to be relative to the module
131func bp2BuildMakePathsRelativeToModule(ctx android.TopDownMutatorContext, paths []string) []string {
132 var relativePaths []string
133 for _, path := range paths {
134 relativePath := strings.TrimPrefix(path, ctx.ModuleDir()+"/")
135 relativePaths = append(relativePaths, relativePath)
136 }
137 return relativePaths
138}
139
Jingwen Chen91220d72021-03-24 02:18:33 -0400140// bp2BuildParseExportedIncludes creates a label list attribute contains the
141// exported included directories of a module.
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000142func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) (bazel.StringListAttribute, bazel.LabelListAttribute) {
Jingwen Chen91220d72021-03-24 02:18:33 -0400143 libraryDecorator := module.linker.(*libraryDecorator)
144
145 includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
146 includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000147 includeDirs = bp2BuildMakePathsRelativeToModule(ctx, includeDirs)
148 includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
Jingwen Chen91220d72021-03-24 02:18:33 -0400149
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000150 var headersAttribute bazel.LabelListAttribute
151 var headers bazel.LabelList
Jingwen Chen91220d72021-03-24 02:18:33 -0400152 for _, includeDir := range includeDirs {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000153 headers.Append(bp2BuildListHeadersInDir(ctx, includeDir))
154 }
155 headers = bazel.UniqueBazelLabelList(headers)
156 headersAttribute.Value = headers
157
158 for arch, props := range module.GetArchProperties(&FlagExporterProperties{}) {
159 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
160 archIncludeDirs := flagExporterProperties.Export_system_include_dirs
161 archIncludeDirs = append(archIncludeDirs, flagExporterProperties.Export_include_dirs...)
162 archIncludeDirs = bp2BuildMakePathsRelativeToModule(ctx, archIncludeDirs)
163
164 // To avoid duplicate includes when base includes + arch includes are combined
165 archIncludeDirs = bazel.SubtractStrings(archIncludeDirs, includeDirs)
166
167 if len(archIncludeDirs) > 0 {
168 includeDirsAttribute.SetValueForArch(arch.Name, archIncludeDirs)
169 }
170
171 var archHeaders bazel.LabelList
172 for _, archIncludeDir := range archIncludeDirs {
173 archHeaders.Append(bp2BuildListHeadersInDir(ctx, archIncludeDir))
174 }
175 archHeaders = bazel.UniqueBazelLabelList(archHeaders)
176
177 // To avoid duplicate headers when base headers + arch headers are combined
178 archHeaders = bazel.SubtractBazelLabelList(archHeaders, headers)
179
180 if len(archHeaders.Includes) > 0 || len(archHeaders.Excludes) > 0 {
181 headersAttribute.SetValueForArch(arch.Name, archHeaders)
182 }
183 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400184 }
185
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000186 return includeDirsAttribute, headersAttribute
Jingwen Chen91220d72021-03-24 02:18:33 -0400187}