blob: 5357668e51a08b6f2d50215dc2085174c051b231 [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 (
Jingwen Chen14a8bda2021-06-02 11:10:02 +000017 "fmt"
Jingwen Chened9c17d2021-04-13 07:14:55 +000018 "path/filepath"
Jingwen Chen3950cd62021-05-12 04:33:00 +000019 "strings"
Chris Parsons484e50a2021-05-13 15:13:04 -040020
21 "android/soong/android"
22 "android/soong/bazel"
Liz Kammerba7a9c52021-05-26 08:45:30 -040023
24 "github.com/google/blueprint/proptools"
Jingwen Chen91220d72021-03-24 02:18:33 -040025)
26
27// bp2build functions and helpers for converting cc_* modules to Bazel.
28
29func init() {
30 android.DepsBp2BuildMutators(RegisterDepsBp2Build)
31}
32
33func RegisterDepsBp2Build(ctx android.RegisterMutatorsContext) {
34 ctx.BottomUp("cc_bp2build_deps", depsBp2BuildMutator)
35}
36
37// A naive deps mutator to add deps on all modules across all combinations of
38// target props for cc modules. This is needed to make module -> bazel label
39// resolution work in the bp2build mutator later. This is probably
40// the wrong way to do it, but it works.
41//
42// TODO(jingwen): can we create a custom os mutator in depsBp2BuildMutator to do this?
43func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) {
44 module, ok := ctx.Module().(*Module)
45 if !ok {
46 // Not a cc module
47 return
48 }
49
50 if !module.ConvertWithBp2build(ctx) {
51 return
52 }
53
54 var allDeps []string
55
Liz Kammer9abd62d2021-05-21 08:37:59 -040056 for _, configToProps := range module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) {
57 for _, props := range configToProps {
58 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -040059 allDeps = append(allDeps, baseCompilerProps.Generated_headers...)
60 allDeps = append(allDeps, baseCompilerProps.Generated_sources...)
61 }
62 }
Chris Parsons484e50a2021-05-13 15:13:04 -040063 }
64
Liz Kammer9abd62d2021-05-21 08:37:59 -040065 for _, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
66 for _, props := range configToProps {
67 if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -040068 allDeps = append(allDeps, baseLinkerProps.Header_libs...)
69 allDeps = append(allDeps, baseLinkerProps.Export_header_lib_headers...)
70 allDeps = append(allDeps, baseLinkerProps.Static_libs...)
Liz Kammer9abd62d2021-05-21 08:37:59 -040071 allDeps = append(allDeps, baseLinkerProps.Exclude_static_libs...)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -040072 allDeps = append(allDeps, baseLinkerProps.Whole_static_libs...)
Liz Kammer9abd62d2021-05-21 08:37:59 -040073 allDeps = append(allDeps, baseLinkerProps.Shared_libs...)
74 allDeps = append(allDeps, baseLinkerProps.Exclude_shared_libs...)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -040075 }
76 }
Jingwen Chened9c17d2021-04-13 07:14:55 +000077 }
78
Jingwen Chen53681ef2021-04-29 08:15:13 +000079 // Deps in the static: { .. } and shared: { .. } props of a cc_library.
80 if lib, ok := module.compiler.(*libraryDecorator); ok {
Jingwen Chenbcf53042021-05-26 04:42:42 +000081 appendDeps := func(deps []string, p StaticOrSharedProperties) []string {
82 deps = append(deps, p.Static_libs...)
83 deps = append(deps, p.Whole_static_libs...)
84 deps = append(deps, p.Shared_libs...)
85 return deps
86 }
Jingwen Chen53681ef2021-04-29 08:15:13 +000087
Jingwen Chenbcf53042021-05-26 04:42:42 +000088 allDeps = appendDeps(allDeps, lib.SharedProperties.Shared)
89 allDeps = appendDeps(allDeps, lib.StaticProperties.Static)
Jingwen Chen45dec102021-05-19 10:30:29 +000090
91 // TODO(b/186024507, b/186489250): Temporarily exclude adding
92 // system_shared_libs deps until libc and libm builds.
93 // allDeps = append(allDeps, lib.SharedProperties.Shared.System_shared_libs...)
94 // allDeps = append(allDeps, lib.StaticProperties.Static.System_shared_libs...)
Jingwen Chenbcf53042021-05-26 04:42:42 +000095
96 // Deps in the target/arch nested static: { .. } and shared: { .. } props of a cc_library.
97 // target: { <target>: shared: { ... } }
Liz Kammer9abd62d2021-05-21 08:37:59 -040098 for _, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
99 for _, props := range configToProps {
100 if p, ok := props.(*SharedProperties); ok {
Jingwen Chenbcf53042021-05-26 04:42:42 +0000101 allDeps = appendDeps(allDeps, p.Shared)
102 }
103 }
104 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400105
106 for _, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
107 for _, props := range configToProps {
108 if p, ok := props.(*StaticProperties); ok {
Jingwen Chenbcf53042021-05-26 04:42:42 +0000109 allDeps = appendDeps(allDeps, p.Static)
110 }
111 }
112 }
Jingwen Chen53681ef2021-04-29 08:15:13 +0000113 }
114
Liz Kammer47535c52021-06-02 16:02:22 -0400115 // product variables only support a limited set of fields, this is the full list of field names
116 // related to cc module dependency management that are supported.
117 productVariableDepFields := [4]string{
118 "Shared_libs",
119 "Static_libs",
120 "Exclude_static_libs",
121 "Whole_static_libs",
122 }
123
124 productVariableProps := android.ProductVariableProperties(ctx)
125 for _, name := range productVariableDepFields {
126 props, exists := productVariableProps[name]
127 if !exists {
128 continue
129 }
130 for _, prop := range props {
131 if p, ok := prop.Property.([]string); !ok {
132 ctx.ModuleErrorf("Could not convert product variable %s property", name)
133 } else {
134 allDeps = append(allDeps, p...)
135 }
136 }
137 }
138
Jingwen Chen91220d72021-03-24 02:18:33 -0400139 ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
140}
141
Liz Kammer2222c6b2021-05-24 15:41:47 -0400142// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
Jingwen Chenbcf53042021-05-26 04:42:42 +0000143// properties which apply to either the shared or static version of a cc_library module.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400144type staticOrSharedAttributes struct {
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000145 srcs bazel.LabelListAttribute
146 srcs_c bazel.LabelListAttribute
147 srcs_as bazel.LabelListAttribute
148
149 copts bazel.StringListAttribute
150
Chris Parsons08648312021-05-06 16:23:19 -0400151 staticDeps bazel.LabelListAttribute
152 dynamicDeps bazel.LabelListAttribute
153 wholeArchiveDeps bazel.LabelListAttribute
Jingwen Chen53681ef2021-04-29 08:15:13 +0000154}
155
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000156func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) {
157 // Branch srcs into three language-specific groups.
158 // C++ is the "catch-all" group, and comprises generated sources because we don't
159 // know the language of these sources until the genrule is executed.
160 // TODO(b/190006308): Handle language detection of sources in a Bazel rule.
161 isCSrcOrFilegroup := func(s string) bool {
162 return strings.HasSuffix(s, ".c") || strings.HasSuffix(s, "_c_srcs")
163 }
164
165 isAsmSrcOrFilegroup := func(s string) bool {
166 return strings.HasSuffix(s, ".S") || strings.HasSuffix(s, ".s") || strings.HasSuffix(s, "_as_srcs")
167 }
168
169 // Check that a module is a filegroup type named <label>.
170 isFilegroupNamed := func(m android.Module, fullLabel string) bool {
171 if ctx.OtherModuleType(m) != "filegroup" {
172 return false
173 }
174 labelParts := strings.Split(fullLabel, ":")
175 if len(labelParts) > 2 {
176 // There should not be more than one colon in a label.
177 panic(fmt.Errorf("%s is not a valid Bazel label for a filegroup", fullLabel))
178 } else {
179 return m.Name() == labelParts[len(labelParts)-1]
180 }
181 }
182
183 // Convert the filegroup dependencies into the extension-specific filegroups
184 // filtered in the filegroup.bzl macro.
185 cppFilegroup := func(label string) string {
186 ctx.VisitDirectDeps(func(m android.Module) {
187 if isFilegroupNamed(m, label) {
188 label = label + "_cpp_srcs"
189 return
190 }
191 })
192 return label
193 }
194 cFilegroup := func(label string) string {
195 ctx.VisitDirectDeps(func(m android.Module) {
196 if isFilegroupNamed(m, label) {
197 label = label + "_c_srcs"
198 return
199 }
200 })
201 return label
202 }
203 asFilegroup := func(label string) string {
204 ctx.VisitDirectDeps(func(m android.Module) {
205 if isFilegroupNamed(m, label) {
206 label = label + "_as_srcs"
207 return
208 }
209 })
210 return label
211 }
212
213 cSrcs = bazel.MapLabelListAttribute(srcs, cFilegroup)
214 cSrcs = bazel.FilterLabelListAttribute(cSrcs, isCSrcOrFilegroup)
215
216 asSrcs = bazel.MapLabelListAttribute(srcs, asFilegroup)
217 asSrcs = bazel.FilterLabelListAttribute(asSrcs, isAsmSrcOrFilegroup)
218
219 cppSrcs = bazel.MapLabelListAttribute(srcs, cppFilegroup)
220 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, cSrcs)
221 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, asSrcs)
222 return
223}
224
Jingwen Chen53681ef2021-04-29 08:15:13 +0000225// bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400226func bp2BuildParseSharedProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
Jingwen Chen53681ef2021-04-29 08:15:13 +0000227 lib, ok := module.compiler.(*libraryDecorator)
228 if !ok {
Liz Kammer2222c6b2021-05-24 15:41:47 -0400229 return staticOrSharedAttributes{}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000230 }
231
Jingwen Chenbcf53042021-05-26 04:42:42 +0000232 return bp2buildParseStaticOrSharedProps(ctx, module, lib, false)
Jingwen Chen53681ef2021-04-29 08:15:13 +0000233}
234
235// bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400236func bp2BuildParseStaticProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
Jingwen Chen53681ef2021-04-29 08:15:13 +0000237 lib, ok := module.compiler.(*libraryDecorator)
238 if !ok {
Liz Kammer2222c6b2021-05-24 15:41:47 -0400239 return staticOrSharedAttributes{}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000240 }
241
Jingwen Chenbcf53042021-05-26 04:42:42 +0000242 return bp2buildParseStaticOrSharedProps(ctx, module, lib, true)
Liz Kammer2222c6b2021-05-24 15:41:47 -0400243}
244
Jingwen Chenbcf53042021-05-26 04:42:42 +0000245func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
246 var props StaticOrSharedProperties
247 if isStatic {
248 props = lib.StaticProperties.Static
249 } else {
250 props = lib.SharedProperties.Shared
Jingwen Chen53681ef2021-04-29 08:15:13 +0000251 }
Jingwen Chenbcf53042021-05-26 04:42:42 +0000252
253 attrs := staticOrSharedAttributes{
254 copts: bazel.StringListAttribute{Value: props.Cflags},
Liz Kammer9abd62d2021-05-21 08:37:59 -0400255 srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)),
256 staticDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)),
257 dynamicDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)),
258 wholeArchiveDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)),
Jingwen Chenbcf53042021-05-26 04:42:42 +0000259 }
260
Liz Kammer9abd62d2021-05-21 08:37:59 -0400261 setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
262 attrs.copts.SetSelectValue(axis, config, props.Cflags)
263 attrs.srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
264 attrs.staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
265 attrs.dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
266 attrs.wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs))
Jingwen Chenbcf53042021-05-26 04:42:42 +0000267 }
268
269 if isStatic {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400270 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
271 for config, props := range configToProps {
272 if staticOrSharedProps, ok := props.(*StaticProperties); ok {
273 setAttrs(axis, config, staticOrSharedProps.Static)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000274 }
275 }
276 }
277 } else {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400278 for axis, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
279 for config, props := range configToProps {
280 if staticOrSharedProps, ok := props.(*SharedProperties); ok {
281 setAttrs(axis, config, staticOrSharedProps.Shared)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000282 }
283 }
284 }
285 }
286
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000287 cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.srcs)
288 attrs.srcs = cppSrcs
289 attrs.srcs_c = cSrcs
290 attrs.srcs_as = asSrcs
291
Jingwen Chenbcf53042021-05-26 04:42:42 +0000292 return attrs
Jingwen Chen53681ef2021-04-29 08:15:13 +0000293}
294
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400295// Convenience struct to hold all attributes parsed from prebuilt properties.
296type prebuiltAttributes struct {
297 Src bazel.LabelAttribute
298}
299
300func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
301 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
302 prebuiltLinker := prebuiltLibraryLinker.prebuiltLinker
303
304 var srcLabelAttribute bazel.LabelAttribute
305
306 if len(prebuiltLinker.properties.Srcs) > 1 {
307 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file\n")
308 }
309
310 if len(prebuiltLinker.properties.Srcs) == 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400311 srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]))
312 }
313 for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
314 for config, props := range configToProps {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400315 if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
316 if len(prebuiltLinkerProperties.Srcs) > 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400317 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
318 continue
319 } else if len(prebuiltLinkerProperties.Srcs) == 0 {
320 continue
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400321 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400322 src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])
323 srcLabelAttribute.SetSelectValue(axis, config, src)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400324 }
325 }
326 }
327
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400328 return prebuiltAttributes{
329 Src: srcLabelAttribute,
330 }
331}
332
Jingwen Chen107c0de2021-04-09 10:43:12 +0000333// Convenience struct to hold all attributes parsed from compiler properties.
334type compilerAttributes struct {
Chris Parsons990c4f42021-05-25 12:10:58 -0400335 // Options for all languages
336 copts bazel.StringListAttribute
337 // Assembly options and sources
338 asFlags bazel.StringListAttribute
339 asSrcs bazel.LabelListAttribute
340 // C options and sources
341 conlyFlags bazel.StringListAttribute
342 cSrcs bazel.LabelListAttribute
343 // C++ options and sources
344 cppFlags bazel.StringListAttribute
Jingwen Chened9c17d2021-04-13 07:14:55 +0000345 srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000346}
347
Jingwen Chen63930982021-03-24 10:04:33 -0400348// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000349func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
Jingwen Chen882bcc12021-04-27 05:54:20 +0000350 var srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000351 var copts bazel.StringListAttribute
Chris Parsons990c4f42021-05-25 12:10:58 -0400352 var asFlags bazel.StringListAttribute
353 var conlyFlags bazel.StringListAttribute
354 var cppFlags bazel.StringListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400355
Chris Parsons484e50a2021-05-13 15:13:04 -0400356 // Creates the -I flags for a directory, while making the directory relative
Jingwen Chened9c17d2021-04-13 07:14:55 +0000357 // to the exec root for Bazel to work.
Chris Parsons484e50a2021-05-13 15:13:04 -0400358 includeFlags := func(dir string) []string {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000359 // filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
Chris Parsons484e50a2021-05-13 15:13:04 -0400360 moduleDirRootedPath := filepath.Join(ctx.ModuleDir(), dir)
361 return []string{
362 "-I" + moduleDirRootedPath,
363 // Include the bindir-rooted path (using make variable substitution). This most
364 // closely matches Bazel's native include path handling, which allows for dependency
365 // on generated headers in these directories.
366 // TODO(b/188084383): Handle local include directories in Bazel.
367 "-I$(BINDIR)/" + moduleDirRootedPath,
368 }
Jingwen Chened9c17d2021-04-13 07:14:55 +0000369 }
370
Jingwen Chened9c17d2021-04-13 07:14:55 +0000371 // Parse the list of module-relative include directories (-I).
372 parseLocalIncludeDirs := func(baseCompilerProps *BaseCompilerProperties) []string {
373 // include_dirs are root-relative, not module-relative.
374 includeDirs := bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
375 return append(includeDirs, baseCompilerProps.Local_include_dirs...)
376 }
377
Chris Parsons990c4f42021-05-25 12:10:58 -0400378 parseCommandLineFlags := func(soongFlags []string) []string {
379 var result []string
380 for _, flag := range soongFlags {
Colin Cross52aa4e12021-05-25 15:20:39 +0000381 // Soong's cflags can contain spaces, like `-include header.h`. For
382 // Bazel's copts, split them up to be compatible with the
383 // no_copts_tokenization feature.
Chris Parsons990c4f42021-05-25 12:10:58 -0400384 result = append(result, strings.Split(flag, " ")...)
Colin Cross52aa4e12021-05-25 15:20:39 +0000385 }
Chris Parsons990c4f42021-05-25 12:10:58 -0400386 return result
387 }
388
389 // Parse the list of copts.
390 parseCopts := func(baseCompilerProps *BaseCompilerProperties) []string {
391 var copts []string
392 copts = append(copts, parseCommandLineFlags(baseCompilerProps.Cflags)...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000393 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
Chris Parsons484e50a2021-05-13 15:13:04 -0400394 copts = append(copts, includeFlags(dir)...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000395 }
396 return copts
Jingwen Chen63930982021-03-24 10:04:33 -0400397 }
398
Liz Kammer74deed42021-06-02 13:02:03 -0400399 // Parse srcs from an arch or OS's props value.
Jingwen Chene32e9e02021-04-23 09:17:24 +0000400 parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
Chris Parsons484e50a2021-05-13 15:13:04 -0400401 // Add srcs-like dependencies such as generated files.
402 // First create a LabelList containing these dependencies, then merge the values with srcs.
403 generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
404 generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
Chris Parsons484e50a2021-05-13 15:13:04 -0400405 generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
406
Liz Kammer74deed42021-06-02 13:02:03 -0400407 allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
Chris Parsons484e50a2021-05-13 15:13:04 -0400408 return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000409 }
410
Jingwen Chenc1c26502021-04-05 10:35:13 +0000411 for _, props := range module.compiler.compilerProps() {
412 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400413 srcs.SetValue(parseSrcs(baseCompilerProps))
Jingwen Chened9c17d2021-04-13 07:14:55 +0000414 copts.Value = parseCopts(baseCompilerProps)
Chris Parsons990c4f42021-05-25 12:10:58 -0400415 asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
416 conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
417 cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000418
Jingwen Chenc1c26502021-04-05 10:35:13 +0000419 break
420 }
421 }
422
Jingwen Chene32e9e02021-04-23 09:17:24 +0000423 // Handle include_build_directory prop. If the property is true, then the
424 // target has access to all headers recursively in the package, and has
425 // "-I<module-dir>" in its copts.
Jingwen Chened9c17d2021-04-13 07:14:55 +0000426 if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
Chris Parsons484e50a2021-05-13 15:13:04 -0400427 copts.Value = append(copts.Value, includeFlags(".")...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000428 } else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
Chris Parsons484e50a2021-05-13 15:13:04 -0400429 copts.Value = append(copts.Value, includeFlags(".")...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000430 }
431
Liz Kammer9abd62d2021-05-21 08:37:59 -0400432 archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
Jingwen Chene32e9e02021-04-23 09:17:24 +0000433
Liz Kammer9abd62d2021-05-21 08:37:59 -0400434 for axis, configToProps := range archVariantCompilerProps {
435 for config, props := range configToProps {
436 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
437 // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
438 // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
439 if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
440 srcsList := parseSrcs(baseCompilerProps)
441 srcs.SetSelectValue(axis, config, srcsList)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400442 }
443
444 copts.SetSelectValue(axis, config, parseCopts(baseCompilerProps))
445 asFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Asflags))
446 conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
447 cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
448 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000449 }
450 }
451
Liz Kammer74deed42021-06-02 13:02:03 -0400452 srcs.ResolveExcludes()
Jingwen Chenc1c26502021-04-05 10:35:13 +0000453
Liz Kammerba7a9c52021-05-26 08:45:30 -0400454 productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
455 "Cflags": &copts,
456 "Asflags": &asFlags,
457 "CppFlags": &cppFlags,
458 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400459 productVariableProps := android.ProductVariableProperties(ctx)
Liz Kammerba7a9c52021-05-26 08:45:30 -0400460 for propName, attr := range productVarPropNameToAttribute {
461 if props, exists := productVariableProps[propName]; exists {
462 for _, prop := range props {
463 flags, ok := prop.Property.([]string)
464 if !ok {
465 ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
466 }
467 newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
Liz Kammer47535c52021-06-02 16:02:22 -0400468 attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400469 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400470 }
471 }
472
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000473 srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
474
Jingwen Chen107c0de2021-04-09 10:43:12 +0000475 return compilerAttributes{
Chris Parsons990c4f42021-05-25 12:10:58 -0400476 copts: copts,
477 srcs: srcs,
478 asFlags: asFlags,
479 asSrcs: asSrcs,
480 cSrcs: cSrcs,
481 conlyFlags: conlyFlags,
482 cppFlags: cppFlags,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000483 }
484}
485
486// Convenience struct to hold all attributes parsed from linker properties.
487type linkerAttributes struct {
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000488 deps bazel.LabelListAttribute
489 dynamicDeps bazel.LabelListAttribute
490 wholeArchiveDeps bazel.LabelListAttribute
491 exportedDeps bazel.LabelListAttribute
492 useLibcrt bazel.BoolAttribute
493 linkopts bazel.StringListAttribute
494 versionScript bazel.LabelAttribute
495 stripKeepSymbols bazel.BoolAttribute
496 stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
497 stripKeepSymbolsList bazel.StringListAttribute
498 stripAll bazel.BoolAttribute
499 stripNone bazel.BoolAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000500}
501
Rupert Shuttleworth143be942021-05-09 23:55:51 -0400502// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
503func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
504 flags := linkerProperties.Ldflags
505 if !BoolDefault(linkerProperties.Pack_relocations, true) {
506 flags = append(flags, "-Wl,--pack-dyn-relocs=none")
507 }
508 return flags
509}
510
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200511// bp2BuildParseLinkerProps parses the linker properties of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400512// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000513func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Liz Kammer47535c52021-06-02 16:02:22 -0400514 var headerDeps bazel.LabelListAttribute
515 var staticDeps bazel.LabelListAttribute
Chris Parsonsd6358772021-05-18 18:35:24 -0400516 var exportedDeps bazel.LabelListAttribute
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400517 var dynamicDeps bazel.LabelListAttribute
Chris Parsons08648312021-05-06 16:23:19 -0400518 var wholeArchiveDeps bazel.LabelListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400519 var linkopts bazel.StringListAttribute
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200520 var versionScript bazel.LabelAttribute
Liz Kammerd366c902021-06-03 13:43:01 -0400521 var useLibcrt bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400522
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000523 var stripKeepSymbols bazel.BoolAttribute
524 var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
525 var stripKeepSymbolsList bazel.StringListAttribute
526 var stripAll bazel.BoolAttribute
527 var stripNone bazel.BoolAttribute
528
529 if libraryDecorator, ok := module.linker.(*libraryDecorator); ok {
530 stripProperties := libraryDecorator.stripper.StripProperties
531 stripKeepSymbols.Value = stripProperties.Strip.Keep_symbols
532 stripKeepSymbolsList.Value = stripProperties.Strip.Keep_symbols_list
533 stripKeepSymbolsAndDebugFrame.Value = stripProperties.Strip.Keep_symbols_and_debug_frame
534 stripAll.Value = stripProperties.Strip.All
535 stripNone.Value = stripProperties.Strip.None
536 }
537
538 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
539 for config, props := range configToProps {
540 if stripProperties, ok := props.(*StripProperties); ok {
541 stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
542 stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
543 stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
544 stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
545 stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
546 }
547 }
548 }
549
Jingwen Chen91220d72021-03-24 02:18:33 -0400550 for _, linkerProps := range module.linker.linkerProps() {
551 if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
Liz Kammer47535c52021-06-02 16:02:22 -0400552 // Excludes to parallel Soong:
553 // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
554 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
555 staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
556 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
557 wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
558 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
559 dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200560
Liz Kammer47535c52021-06-02 16:02:22 -0400561 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
562 headerDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
563 // TODO(b/188796939): also handle export_static_lib_headers, export_shared_lib_headers,
564 // export_generated_headers
565 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
566 exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
567
568 linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200569 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400570 versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200571 }
Liz Kammerd366c902021-06-03 13:43:01 -0400572 useLibcrt.Value = baseLinkerProps.libCrt()
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400573
Jingwen Chen91220d72021-03-24 02:18:33 -0400574 break
575 }
576 }
577
Liz Kammer9abd62d2021-05-21 08:37:59 -0400578 for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
579 for config, props := range configToProps {
580 if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
Liz Kammer47535c52021-06-02 16:02:22 -0400581 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
582 staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
583 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
584 wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
585 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
586 dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400587
Liz Kammer47535c52021-06-02 16:02:22 -0400588 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
589 headerDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, headerLibs))
590 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
591 exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
592
593 linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400594 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400595 versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400596 }
Liz Kammerd366c902021-06-03 13:43:01 -0400597 useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400598 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400599 }
600 }
601
Liz Kammer47535c52021-06-02 16:02:22 -0400602 type productVarDep struct {
603 // the name of the corresponding excludes field, if one exists
604 excludesField string
605 // reference to the bazel attribute that should be set for the given product variable config
606 attribute *bazel.LabelListAttribute
607 }
608
609 productVarToDepFields := map[string]productVarDep{
610 // product variables do not support exclude_shared_libs
611 "Shared_libs": productVarDep{attribute: &dynamicDeps},
612 "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps},
613 "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps},
614 }
615
616 productVariableProps := android.ProductVariableProperties(ctx)
617 for name, dep := range productVarToDepFields {
618 props, exists := productVariableProps[name]
619 excludeProps, excludesExists := productVariableProps[dep.excludesField]
620 // if neither an include or excludes property exists, then skip it
621 if !exists && !excludesExists {
622 continue
623 }
624 // collect all the configurations that an include or exclude property exists for.
625 // we want to iterate all configurations rather than either the include or exclude because for a
626 // particular configuration we may have only and include or only an exclude to handle
627 configs := make(map[string]bool, len(props)+len(excludeProps))
628 for config := range props {
629 configs[config] = true
630 }
631 for config := range excludeProps {
632 configs[config] = true
633 }
634
635 for config := range configs {
636 prop, includesExists := props[config]
637 excludesProp, excludesExists := excludeProps[config]
638 var includes, excludes []string
639 var ok bool
640 // if there was no includes/excludes property, casting fails and that's expected
641 if includes, ok = prop.Property.([]string); includesExists && !ok {
642 ctx.ModuleErrorf("Could not convert product variable %s property", name)
643 }
644 if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
645 ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
646 }
647 dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, android.BazelLabelForModuleDepsExcludes(ctx, android.FirstUniqueStrings(includes), excludes))
648 }
649 }
650
651 staticDeps.ResolveExcludes()
652 dynamicDeps.ResolveExcludes()
653 wholeArchiveDeps.ResolveExcludes()
654
655 headerDeps.Append(staticDeps)
656
Jingwen Chen107c0de2021-04-09 10:43:12 +0000657 return linkerAttributes{
Liz Kammer47535c52021-06-02 16:02:22 -0400658 deps: headerDeps,
Chris Parsonsd6358772021-05-18 18:35:24 -0400659 exportedDeps: exportedDeps,
Chris Parsons08648312021-05-06 16:23:19 -0400660 dynamicDeps: dynamicDeps,
661 wholeArchiveDeps: wholeArchiveDeps,
662 linkopts: linkopts,
Liz Kammerd366c902021-06-03 13:43:01 -0400663 useLibcrt: useLibcrt,
Chris Parsons08648312021-05-06 16:23:19 -0400664 versionScript: versionScript,
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000665
666 // Strip properties
667 stripKeepSymbols: stripKeepSymbols,
668 stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
669 stripKeepSymbolsList: stripKeepSymbolsList,
670 stripAll: stripAll,
671 stripNone: stripNone,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000672 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400673}
674
Jingwen Chened9c17d2021-04-13 07:14:55 +0000675// Relativize a list of root-relative paths with respect to the module's
676// directory.
677//
678// include_dirs Soong prop are root-relative (b/183742505), but
679// local_include_dirs, export_include_dirs and export_system_include_dirs are
680// module dir relative. This function makes a list of paths entirely module dir
681// relative.
682//
683// For the `include` attribute, Bazel wants the paths to be relative to the
684// module.
685func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000686 var relativePaths []string
687 for _, path := range paths {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000688 // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
689 relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
690 if err != nil {
691 panic(err)
692 }
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000693 relativePaths = append(relativePaths, relativePath)
694 }
695 return relativePaths
696}
697
Jingwen Chen882bcc12021-04-27 05:54:20 +0000698func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
Jingwen Chen91220d72021-03-24 02:18:33 -0400699 libraryDecorator := module.linker.(*libraryDecorator)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400700 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
701}
Jingwen Chen91220d72021-03-24 02:18:33 -0400702
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400703func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
704 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
705 libraryDecorator := prebuiltLibraryLinker.libraryDecorator
706 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
707}
708
709// bp2BuildParseExportedIncludes creates a string list attribute contains the
710// exported included directories of a module.
711func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) bazel.StringListAttribute {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000712 // Export_system_include_dirs and export_include_dirs are already module dir
713 // relative, so they don't need to be relativized like include_dirs, which
714 // are root-relative.
Jingwen Chen91220d72021-03-24 02:18:33 -0400715 includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
716 includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000717 includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
Jingwen Chen91220d72021-03-24 02:18:33 -0400718
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400719 getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties) []string {
720 variantIncludeDirs := flagExporterProperties.Export_system_include_dirs
721 variantIncludeDirs = append(variantIncludeDirs, flagExporterProperties.Export_include_dirs...)
722
723 // To avoid duplicate includes when base includes + arch includes are combined
724 // TODO: This doesn't take conflicts between arch and os includes into account
725 variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
726 return variantIncludeDirs
727 }
728
Liz Kammer9abd62d2021-05-21 08:37:59 -0400729 for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
730 for config, props := range configToProps {
731 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
732 archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties)
733 if len(archVariantIncludeDirs) > 0 {
734 includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400735 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400736 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400737 }
738 }
739
Jingwen Chen882bcc12021-04-27 05:54:20 +0000740 return includeDirsAttribute
Jingwen Chen91220d72021-03-24 02:18:33 -0400741}