blob: 68afd0db5e31049288abab0ce2317078b6a76c40 [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
Liz Kammer2222c6b2021-05-24 15:41:47 -040027// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
Jingwen Chenbcf53042021-05-26 04:42:42 +000028// properties which apply to either the shared or static version of a cc_library module.
Liz Kammer2222c6b2021-05-24 15:41:47 -040029type staticOrSharedAttributes struct {
Jingwen Chenc4dc9b42021-06-11 12:51:48 +000030 Srcs bazel.LabelListAttribute
31 Srcs_c bazel.LabelListAttribute
32 Srcs_as bazel.LabelListAttribute
33 Copts bazel.StringListAttribute
Jingwen Chen14a8bda2021-06-02 11:10:02 +000034
Jingwen Chenc4dc9b42021-06-11 12:51:48 +000035 Static_deps bazel.LabelListAttribute
36 Dynamic_deps bazel.LabelListAttribute
37 Whole_archive_deps bazel.LabelListAttribute
Jingwen Chen53681ef2021-04-29 08:15:13 +000038}
39
Jingwen Chen14a8bda2021-06-02 11:10:02 +000040func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) {
41 // Branch srcs into three language-specific groups.
42 // C++ is the "catch-all" group, and comprises generated sources because we don't
43 // know the language of these sources until the genrule is executed.
44 // TODO(b/190006308): Handle language detection of sources in a Bazel rule.
45 isCSrcOrFilegroup := func(s string) bool {
46 return strings.HasSuffix(s, ".c") || strings.HasSuffix(s, "_c_srcs")
47 }
48
49 isAsmSrcOrFilegroup := func(s string) bool {
50 return strings.HasSuffix(s, ".S") || strings.HasSuffix(s, ".s") || strings.HasSuffix(s, "_as_srcs")
51 }
52
53 // Check that a module is a filegroup type named <label>.
54 isFilegroupNamed := func(m android.Module, fullLabel string) bool {
55 if ctx.OtherModuleType(m) != "filegroup" {
56 return false
57 }
58 labelParts := strings.Split(fullLabel, ":")
59 if len(labelParts) > 2 {
60 // There should not be more than one colon in a label.
61 panic(fmt.Errorf("%s is not a valid Bazel label for a filegroup", fullLabel))
62 } else {
63 return m.Name() == labelParts[len(labelParts)-1]
64 }
65 }
66
67 // Convert the filegroup dependencies into the extension-specific filegroups
68 // filtered in the filegroup.bzl macro.
69 cppFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040070 m, exists := ctx.ModuleFromName(label)
71 if exists {
72 aModule, _ := m.(android.Module)
73 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000074 label = label + "_cpp_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000075 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040076 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000077 return label
78 }
79 cFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040080 m, exists := ctx.ModuleFromName(label)
81 if exists {
82 aModule, _ := m.(android.Module)
83 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000084 label = label + "_c_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000085 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040086 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000087 return label
88 }
89 asFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040090 m, exists := ctx.ModuleFromName(label)
91 if exists {
92 aModule, _ := m.(android.Module)
93 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000094 label = label + "_as_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000095 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040096 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000097 return label
98 }
99
100 cSrcs = bazel.MapLabelListAttribute(srcs, cFilegroup)
101 cSrcs = bazel.FilterLabelListAttribute(cSrcs, isCSrcOrFilegroup)
102
103 asSrcs = bazel.MapLabelListAttribute(srcs, asFilegroup)
104 asSrcs = bazel.FilterLabelListAttribute(asSrcs, isAsmSrcOrFilegroup)
105
106 cppSrcs = bazel.MapLabelListAttribute(srcs, cppFilegroup)
107 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, cSrcs)
108 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, asSrcs)
109 return
110}
111
Jingwen Chen53681ef2021-04-29 08:15:13 +0000112// bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400113func bp2BuildParseSharedProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
Jingwen Chen53681ef2021-04-29 08:15:13 +0000114 lib, ok := module.compiler.(*libraryDecorator)
115 if !ok {
Liz Kammer2222c6b2021-05-24 15:41:47 -0400116 return staticOrSharedAttributes{}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000117 }
118
Jingwen Chenbcf53042021-05-26 04:42:42 +0000119 return bp2buildParseStaticOrSharedProps(ctx, module, lib, false)
Jingwen Chen53681ef2021-04-29 08:15:13 +0000120}
121
122// bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400123func bp2BuildParseStaticProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
Jingwen Chen53681ef2021-04-29 08:15:13 +0000124 lib, ok := module.compiler.(*libraryDecorator)
125 if !ok {
Liz Kammer2222c6b2021-05-24 15:41:47 -0400126 return staticOrSharedAttributes{}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000127 }
128
Jingwen Chenbcf53042021-05-26 04:42:42 +0000129 return bp2buildParseStaticOrSharedProps(ctx, module, lib, true)
Liz Kammer2222c6b2021-05-24 15:41:47 -0400130}
131
Jingwen Chenbcf53042021-05-26 04:42:42 +0000132func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
133 var props StaticOrSharedProperties
134 if isStatic {
135 props = lib.StaticProperties.Static
136 } else {
137 props = lib.SharedProperties.Shared
Jingwen Chen53681ef2021-04-29 08:15:13 +0000138 }
Jingwen Chenbcf53042021-05-26 04:42:42 +0000139
140 attrs := staticOrSharedAttributes{
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000141 Copts: bazel.StringListAttribute{Value: props.Cflags},
142 Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)),
143 Static_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)),
Chris Parsons69fa9f92021-07-13 11:47:44 -0400144 Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, append(props.Shared_libs, props.System_shared_libs...))),
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000145 Whole_archive_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)),
Jingwen Chenbcf53042021-05-26 04:42:42 +0000146 }
147
Liz Kammer9abd62d2021-05-21 08:37:59 -0400148 setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000149 attrs.Copts.SetSelectValue(axis, config, props.Cflags)
150 attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
151 attrs.Static_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
152 attrs.Dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
153 attrs.Whole_archive_deps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs))
Jingwen Chenbcf53042021-05-26 04:42:42 +0000154 }
155
156 if isStatic {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400157 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
158 for config, props := range configToProps {
159 if staticOrSharedProps, ok := props.(*StaticProperties); ok {
160 setAttrs(axis, config, staticOrSharedProps.Static)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000161 }
162 }
163 }
164 } else {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400165 for axis, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
166 for config, props := range configToProps {
167 if staticOrSharedProps, ok := props.(*SharedProperties); ok {
168 setAttrs(axis, config, staticOrSharedProps.Shared)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000169 }
170 }
171 }
172 }
173
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000174 cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
175 attrs.Srcs = cppSrcs
176 attrs.Srcs_c = cSrcs
177 attrs.Srcs_as = asSrcs
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000178
Jingwen Chenbcf53042021-05-26 04:42:42 +0000179 return attrs
Jingwen Chen53681ef2021-04-29 08:15:13 +0000180}
181
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400182// Convenience struct to hold all attributes parsed from prebuilt properties.
183type prebuiltAttributes struct {
184 Src bazel.LabelAttribute
185}
186
187func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
188 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
189 prebuiltLinker := prebuiltLibraryLinker.prebuiltLinker
190
191 var srcLabelAttribute bazel.LabelAttribute
192
193 if len(prebuiltLinker.properties.Srcs) > 1 {
194 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file\n")
195 }
196
197 if len(prebuiltLinker.properties.Srcs) == 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400198 srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]))
199 }
200 for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
201 for config, props := range configToProps {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400202 if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
203 if len(prebuiltLinkerProperties.Srcs) > 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400204 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
205 continue
206 } else if len(prebuiltLinkerProperties.Srcs) == 0 {
207 continue
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400208 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400209 src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])
210 srcLabelAttribute.SetSelectValue(axis, config, src)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400211 }
212 }
213 }
214
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400215 return prebuiltAttributes{
216 Src: srcLabelAttribute,
217 }
218}
219
Jingwen Chen107c0de2021-04-09 10:43:12 +0000220// Convenience struct to hold all attributes parsed from compiler properties.
221type compilerAttributes struct {
Chris Parsons990c4f42021-05-25 12:10:58 -0400222 // Options for all languages
223 copts bazel.StringListAttribute
224 // Assembly options and sources
225 asFlags bazel.StringListAttribute
226 asSrcs bazel.LabelListAttribute
227 // C options and sources
228 conlyFlags bazel.StringListAttribute
229 cSrcs bazel.LabelListAttribute
230 // C++ options and sources
231 cppFlags bazel.StringListAttribute
Jingwen Chened9c17d2021-04-13 07:14:55 +0000232 srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000233}
234
Jingwen Chen63930982021-03-24 10:04:33 -0400235// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000236func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
Jingwen Chen882bcc12021-04-27 05:54:20 +0000237 var srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000238 var copts bazel.StringListAttribute
Chris Parsons990c4f42021-05-25 12:10:58 -0400239 var asFlags bazel.StringListAttribute
240 var conlyFlags bazel.StringListAttribute
241 var cppFlags bazel.StringListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400242
Chris Parsons484e50a2021-05-13 15:13:04 -0400243 // Creates the -I flags for a directory, while making the directory relative
Jingwen Chened9c17d2021-04-13 07:14:55 +0000244 // to the exec root for Bazel to work.
Chris Parsons484e50a2021-05-13 15:13:04 -0400245 includeFlags := func(dir string) []string {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000246 // filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
Chris Parsons484e50a2021-05-13 15:13:04 -0400247 moduleDirRootedPath := filepath.Join(ctx.ModuleDir(), dir)
248 return []string{
249 "-I" + moduleDirRootedPath,
250 // Include the bindir-rooted path (using make variable substitution). This most
251 // closely matches Bazel's native include path handling, which allows for dependency
252 // on generated headers in these directories.
253 // TODO(b/188084383): Handle local include directories in Bazel.
254 "-I$(BINDIR)/" + moduleDirRootedPath,
255 }
Jingwen Chened9c17d2021-04-13 07:14:55 +0000256 }
257
Jingwen Chened9c17d2021-04-13 07:14:55 +0000258 // Parse the list of module-relative include directories (-I).
259 parseLocalIncludeDirs := func(baseCompilerProps *BaseCompilerProperties) []string {
260 // include_dirs are root-relative, not module-relative.
261 includeDirs := bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
262 return append(includeDirs, baseCompilerProps.Local_include_dirs...)
263 }
264
Chris Parsons990c4f42021-05-25 12:10:58 -0400265 parseCommandLineFlags := func(soongFlags []string) []string {
266 var result []string
267 for _, flag := range soongFlags {
Colin Cross52aa4e12021-05-25 15:20:39 +0000268 // Soong's cflags can contain spaces, like `-include header.h`. For
269 // Bazel's copts, split them up to be compatible with the
270 // no_copts_tokenization feature.
Chris Parsons990c4f42021-05-25 12:10:58 -0400271 result = append(result, strings.Split(flag, " ")...)
Colin Cross52aa4e12021-05-25 15:20:39 +0000272 }
Chris Parsons990c4f42021-05-25 12:10:58 -0400273 return result
274 }
275
Liz Kammer74deed42021-06-02 13:02:03 -0400276 // Parse srcs from an arch or OS's props value.
Jingwen Chene32e9e02021-04-23 09:17:24 +0000277 parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
Chris Parsons484e50a2021-05-13 15:13:04 -0400278 // Add srcs-like dependencies such as generated files.
279 // First create a LabelList containing these dependencies, then merge the values with srcs.
280 generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
281 generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
Chris Parsons484e50a2021-05-13 15:13:04 -0400282 generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
283
Liz Kammer74deed42021-06-02 13:02:03 -0400284 allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
Chris Parsons484e50a2021-05-13 15:13:04 -0400285 return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000286 }
287
Jingwen Chenc1c26502021-04-05 10:35:13 +0000288 for _, props := range module.compiler.compilerProps() {
289 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400290 srcs.SetValue(parseSrcs(baseCompilerProps))
Chris Parsons69fa9f92021-07-13 11:47:44 -0400291 copts.Value = parseCommandLineFlags(baseCompilerProps.Cflags)
Chris Parsons990c4f42021-05-25 12:10:58 -0400292 asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
293 conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
294 cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000295
Chris Parsons69fa9f92021-07-13 11:47:44 -0400296 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
297 copts.Value = append(copts.Value, includeFlags(dir)...)
298 asFlags.Value = append(asFlags.Value, includeFlags(dir)...)
299 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000300 break
301 }
302 }
303
Jingwen Chene32e9e02021-04-23 09:17:24 +0000304 // Handle include_build_directory prop. If the property is true, then the
305 // target has access to all headers recursively in the package, and has
306 // "-I<module-dir>" in its copts.
Jingwen Chened9c17d2021-04-13 07:14:55 +0000307 if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
Chris Parsons484e50a2021-05-13 15:13:04 -0400308 copts.Value = append(copts.Value, includeFlags(".")...)
Chris Parsons69fa9f92021-07-13 11:47:44 -0400309 asFlags.Value = append(asFlags.Value, includeFlags(".")...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000310 } else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
Chris Parsons484e50a2021-05-13 15:13:04 -0400311 copts.Value = append(copts.Value, includeFlags(".")...)
Chris Parsons69fa9f92021-07-13 11:47:44 -0400312 asFlags.Value = append(asFlags.Value, includeFlags(".")...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000313 }
314
Liz Kammer9abd62d2021-05-21 08:37:59 -0400315 archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
Jingwen Chene32e9e02021-04-23 09:17:24 +0000316
Liz Kammer9abd62d2021-05-21 08:37:59 -0400317 for axis, configToProps := range archVariantCompilerProps {
318 for config, props := range configToProps {
319 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
320 // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
321 // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
322 if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
323 srcsList := parseSrcs(baseCompilerProps)
324 srcs.SetSelectValue(axis, config, srcsList)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400325 }
326
Chris Parsons69fa9f92021-07-13 11:47:44 -0400327 archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
328 archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
329 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
330 archVariantCopts = append(archVariantCopts, includeFlags(dir)...)
331 archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
332 }
333
334 copts.SetSelectValue(axis, config, archVariantCopts)
335 asFlags.SetSelectValue(axis, config, archVariantAsflags)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400336 conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
337 cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
338 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000339 }
340 }
341
Liz Kammer74deed42021-06-02 13:02:03 -0400342 srcs.ResolveExcludes()
Jingwen Chenc1c26502021-04-05 10:35:13 +0000343
Liz Kammerba7a9c52021-05-26 08:45:30 -0400344 productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
345 "Cflags": &copts,
346 "Asflags": &asFlags,
347 "CppFlags": &cppFlags,
348 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400349 productVariableProps := android.ProductVariableProperties(ctx)
Liz Kammerba7a9c52021-05-26 08:45:30 -0400350 for propName, attr := range productVarPropNameToAttribute {
351 if props, exists := productVariableProps[propName]; exists {
352 for _, prop := range props {
353 flags, ok := prop.Property.([]string)
354 if !ok {
355 ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
356 }
357 newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
Liz Kammer47535c52021-06-02 16:02:22 -0400358 attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400359 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400360 }
361 }
362
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000363 srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
364
Jingwen Chen107c0de2021-04-09 10:43:12 +0000365 return compilerAttributes{
Chris Parsons990c4f42021-05-25 12:10:58 -0400366 copts: copts,
367 srcs: srcs,
368 asFlags: asFlags,
369 asSrcs: asSrcs,
370 cSrcs: cSrcs,
371 conlyFlags: conlyFlags,
372 cppFlags: cppFlags,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000373 }
374}
375
376// Convenience struct to hold all attributes parsed from linker properties.
377type linkerAttributes struct {
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000378 deps bazel.LabelListAttribute
379 dynamicDeps bazel.LabelListAttribute
380 wholeArchiveDeps bazel.LabelListAttribute
381 exportedDeps bazel.LabelListAttribute
382 useLibcrt bazel.BoolAttribute
383 linkopts bazel.StringListAttribute
384 versionScript bazel.LabelAttribute
385 stripKeepSymbols bazel.BoolAttribute
386 stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
387 stripKeepSymbolsList bazel.StringListAttribute
388 stripAll bazel.BoolAttribute
389 stripNone bazel.BoolAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000390}
391
Rupert Shuttleworth143be942021-05-09 23:55:51 -0400392// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
393func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
394 flags := linkerProperties.Ldflags
395 if !BoolDefault(linkerProperties.Pack_relocations, true) {
396 flags = append(flags, "-Wl,--pack-dyn-relocs=none")
397 }
398 return flags
399}
400
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200401// bp2BuildParseLinkerProps parses the linker properties of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400402// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000403func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Liz Kammer47535c52021-06-02 16:02:22 -0400404 var headerDeps bazel.LabelListAttribute
405 var staticDeps bazel.LabelListAttribute
Chris Parsonsd6358772021-05-18 18:35:24 -0400406 var exportedDeps bazel.LabelListAttribute
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400407 var dynamicDeps bazel.LabelListAttribute
Chris Parsons08648312021-05-06 16:23:19 -0400408 var wholeArchiveDeps bazel.LabelListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400409 var linkopts bazel.StringListAttribute
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200410 var versionScript bazel.LabelAttribute
Liz Kammerd366c902021-06-03 13:43:01 -0400411 var useLibcrt bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400412
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000413 var stripKeepSymbols bazel.BoolAttribute
414 var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
415 var stripKeepSymbolsList bazel.StringListAttribute
416 var stripAll bazel.BoolAttribute
417 var stripNone bazel.BoolAttribute
418
419 if libraryDecorator, ok := module.linker.(*libraryDecorator); ok {
420 stripProperties := libraryDecorator.stripper.StripProperties
421 stripKeepSymbols.Value = stripProperties.Strip.Keep_symbols
422 stripKeepSymbolsList.Value = stripProperties.Strip.Keep_symbols_list
423 stripKeepSymbolsAndDebugFrame.Value = stripProperties.Strip.Keep_symbols_and_debug_frame
424 stripAll.Value = stripProperties.Strip.All
425 stripNone.Value = stripProperties.Strip.None
426 }
427
428 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
429 for config, props := range configToProps {
430 if stripProperties, ok := props.(*StripProperties); ok {
431 stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
432 stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
433 stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
434 stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
435 stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
436 }
437 }
438 }
439
Jingwen Chen91220d72021-03-24 02:18:33 -0400440 for _, linkerProps := range module.linker.linkerProps() {
441 if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
Liz Kammer47535c52021-06-02 16:02:22 -0400442 // Excludes to parallel Soong:
443 // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
444 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
445 staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
446 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400447 wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons69fa9f92021-07-13 11:47:44 -0400448 // TODO(b/186024507): Handle system_shared_libs as its own attribute, so that the appropriate default
449 // may be supported.
450 sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...))
Liz Kammer47535c52021-06-02 16:02:22 -0400451 dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200452
Liz Kammer47535c52021-06-02 16:02:22 -0400453 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
454 headerDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
455 // TODO(b/188796939): also handle export_static_lib_headers, export_shared_lib_headers,
456 // export_generated_headers
457 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
458 exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
459
460 linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200461 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400462 versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200463 }
Liz Kammerd366c902021-06-03 13:43:01 -0400464 useLibcrt.Value = baseLinkerProps.libCrt()
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400465
Jingwen Chen91220d72021-03-24 02:18:33 -0400466 break
467 }
468 }
469
Liz Kammer9abd62d2021-05-21 08:37:59 -0400470 for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
471 for config, props := range configToProps {
472 if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
Liz Kammer47535c52021-06-02 16:02:22 -0400473 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
474 staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
475 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400476 wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons69fa9f92021-07-13 11:47:44 -0400477 sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...))
Liz Kammer47535c52021-06-02 16:02:22 -0400478 dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400479
Liz Kammer47535c52021-06-02 16:02:22 -0400480 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
481 headerDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, headerLibs))
482 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
483 exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
484
485 linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400486 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400487 versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400488 }
Liz Kammerd366c902021-06-03 13:43:01 -0400489 useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400490 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400491 }
492 }
493
Liz Kammer47535c52021-06-02 16:02:22 -0400494 type productVarDep struct {
495 // the name of the corresponding excludes field, if one exists
496 excludesField string
497 // reference to the bazel attribute that should be set for the given product variable config
498 attribute *bazel.LabelListAttribute
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400499
500 depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
Liz Kammer47535c52021-06-02 16:02:22 -0400501 }
502
503 productVarToDepFields := map[string]productVarDep{
504 // product variables do not support exclude_shared_libs
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400505 "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: android.BazelLabelForModuleDepsExcludes},
506 "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, android.BazelLabelForModuleDepsExcludes},
507 "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, android.BazelLabelForModuleWholeDepsExcludes},
Liz Kammer47535c52021-06-02 16:02:22 -0400508 }
509
510 productVariableProps := android.ProductVariableProperties(ctx)
511 for name, dep := range productVarToDepFields {
512 props, exists := productVariableProps[name]
513 excludeProps, excludesExists := productVariableProps[dep.excludesField]
514 // if neither an include or excludes property exists, then skip it
515 if !exists && !excludesExists {
516 continue
517 }
518 // collect all the configurations that an include or exclude property exists for.
519 // we want to iterate all configurations rather than either the include or exclude because for a
520 // particular configuration we may have only and include or only an exclude to handle
521 configs := make(map[string]bool, len(props)+len(excludeProps))
522 for config := range props {
523 configs[config] = true
524 }
525 for config := range excludeProps {
526 configs[config] = true
527 }
528
529 for config := range configs {
530 prop, includesExists := props[config]
531 excludesProp, excludesExists := excludeProps[config]
532 var includes, excludes []string
533 var ok bool
534 // if there was no includes/excludes property, casting fails and that's expected
535 if includes, ok = prop.Property.([]string); includesExists && !ok {
536 ctx.ModuleErrorf("Could not convert product variable %s property", name)
537 }
538 if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
539 ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
540 }
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400541
542 dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
Liz Kammer47535c52021-06-02 16:02:22 -0400543 }
544 }
545
546 staticDeps.ResolveExcludes()
547 dynamicDeps.ResolveExcludes()
548 wholeArchiveDeps.ResolveExcludes()
549
550 headerDeps.Append(staticDeps)
551
Jingwen Chen107c0de2021-04-09 10:43:12 +0000552 return linkerAttributes{
Liz Kammer47535c52021-06-02 16:02:22 -0400553 deps: headerDeps,
Chris Parsonsd6358772021-05-18 18:35:24 -0400554 exportedDeps: exportedDeps,
Chris Parsons08648312021-05-06 16:23:19 -0400555 dynamicDeps: dynamicDeps,
556 wholeArchiveDeps: wholeArchiveDeps,
557 linkopts: linkopts,
Liz Kammerd366c902021-06-03 13:43:01 -0400558 useLibcrt: useLibcrt,
Chris Parsons08648312021-05-06 16:23:19 -0400559 versionScript: versionScript,
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000560
561 // Strip properties
562 stripKeepSymbols: stripKeepSymbols,
563 stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
564 stripKeepSymbolsList: stripKeepSymbolsList,
565 stripAll: stripAll,
566 stripNone: stripNone,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000567 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400568}
569
Jingwen Chened9c17d2021-04-13 07:14:55 +0000570// Relativize a list of root-relative paths with respect to the module's
571// directory.
572//
573// include_dirs Soong prop are root-relative (b/183742505), but
574// local_include_dirs, export_include_dirs and export_system_include_dirs are
575// module dir relative. This function makes a list of paths entirely module dir
576// relative.
577//
578// For the `include` attribute, Bazel wants the paths to be relative to the
579// module.
580func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000581 var relativePaths []string
582 for _, path := range paths {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000583 // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
584 relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
585 if err != nil {
586 panic(err)
587 }
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000588 relativePaths = append(relativePaths, relativePath)
589 }
590 return relativePaths
591}
592
Jingwen Chen882bcc12021-04-27 05:54:20 +0000593func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
Jingwen Chen91220d72021-03-24 02:18:33 -0400594 libraryDecorator := module.linker.(*libraryDecorator)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400595 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
596}
Jingwen Chen91220d72021-03-24 02:18:33 -0400597
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400598func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
599 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
600 libraryDecorator := prebuiltLibraryLinker.libraryDecorator
601 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
602}
603
604// bp2BuildParseExportedIncludes creates a string list attribute contains the
605// exported included directories of a module.
606func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) bazel.StringListAttribute {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000607 // Export_system_include_dirs and export_include_dirs are already module dir
608 // relative, so they don't need to be relativized like include_dirs, which
609 // are root-relative.
Jingwen Chen91220d72021-03-24 02:18:33 -0400610 includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
611 includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000612 includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
Jingwen Chen91220d72021-03-24 02:18:33 -0400613
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400614 getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties) []string {
615 variantIncludeDirs := flagExporterProperties.Export_system_include_dirs
616 variantIncludeDirs = append(variantIncludeDirs, flagExporterProperties.Export_include_dirs...)
617
618 // To avoid duplicate includes when base includes + arch includes are combined
619 // TODO: This doesn't take conflicts between arch and os includes into account
620 variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
621 return variantIncludeDirs
622 }
623
Liz Kammer9abd62d2021-05-21 08:37:59 -0400624 for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
625 for config, props := range configToProps {
626 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
627 archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties)
628 if len(archVariantIncludeDirs) > 0 {
629 includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400630 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400631 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400632 }
633 }
634
Jingwen Chen882bcc12021-04-27 05:54:20 +0000635 return includeDirsAttribute
Jingwen Chen91220d72021-03-24 02:18:33 -0400636}