blob: 1706d727169edca3b3c0dab4ae8129c7519b1de6 [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
Chris Parsons51f8c392021-08-03 21:01:05 -040038
39 System_dynamic_deps bazel.LabelListAttribute
Jingwen Chen53681ef2021-04-29 08:15:13 +000040}
41
Jingwen Chen14a8bda2021-06-02 11:10:02 +000042func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) {
43 // Branch srcs into three language-specific groups.
44 // C++ is the "catch-all" group, and comprises generated sources because we don't
45 // know the language of these sources until the genrule is executed.
46 // TODO(b/190006308): Handle language detection of sources in a Bazel rule.
47 isCSrcOrFilegroup := func(s string) bool {
48 return strings.HasSuffix(s, ".c") || strings.HasSuffix(s, "_c_srcs")
49 }
50
51 isAsmSrcOrFilegroup := func(s string) bool {
52 return strings.HasSuffix(s, ".S") || strings.HasSuffix(s, ".s") || strings.HasSuffix(s, "_as_srcs")
53 }
54
55 // Check that a module is a filegroup type named <label>.
56 isFilegroupNamed := func(m android.Module, fullLabel string) bool {
57 if ctx.OtherModuleType(m) != "filegroup" {
58 return false
59 }
60 labelParts := strings.Split(fullLabel, ":")
61 if len(labelParts) > 2 {
62 // There should not be more than one colon in a label.
63 panic(fmt.Errorf("%s is not a valid Bazel label for a filegroup", fullLabel))
64 } else {
65 return m.Name() == labelParts[len(labelParts)-1]
66 }
67 }
68
69 // Convert the filegroup dependencies into the extension-specific filegroups
70 // filtered in the filegroup.bzl macro.
71 cppFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040072 m, exists := ctx.ModuleFromName(label)
73 if exists {
74 aModule, _ := m.(android.Module)
75 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000076 label = label + "_cpp_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000077 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040078 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000079 return label
80 }
81 cFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040082 m, exists := ctx.ModuleFromName(label)
83 if exists {
84 aModule, _ := m.(android.Module)
85 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000086 label = label + "_c_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000087 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040088 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000089 return label
90 }
91 asFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040092 m, exists := ctx.ModuleFromName(label)
93 if exists {
94 aModule, _ := m.(android.Module)
95 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000096 label = label + "_as_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000097 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040098 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000099 return label
100 }
101
102 cSrcs = bazel.MapLabelListAttribute(srcs, cFilegroup)
103 cSrcs = bazel.FilterLabelListAttribute(cSrcs, isCSrcOrFilegroup)
104
105 asSrcs = bazel.MapLabelListAttribute(srcs, asFilegroup)
106 asSrcs = bazel.FilterLabelListAttribute(asSrcs, isAsmSrcOrFilegroup)
107
108 cppSrcs = bazel.MapLabelListAttribute(srcs, cppFilegroup)
109 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, cSrcs)
110 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, asSrcs)
111 return
112}
113
Jingwen Chen53681ef2021-04-29 08:15:13 +0000114// bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400115func bp2BuildParseSharedProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
Jingwen Chen53681ef2021-04-29 08:15:13 +0000116 lib, ok := module.compiler.(*libraryDecorator)
117 if !ok {
Liz Kammer2222c6b2021-05-24 15:41:47 -0400118 return staticOrSharedAttributes{}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000119 }
120
Jingwen Chenbcf53042021-05-26 04:42:42 +0000121 return bp2buildParseStaticOrSharedProps(ctx, module, lib, false)
Jingwen Chen53681ef2021-04-29 08:15:13 +0000122}
123
124// bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400125func bp2BuildParseStaticProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
Jingwen Chen53681ef2021-04-29 08:15:13 +0000126 lib, ok := module.compiler.(*libraryDecorator)
127 if !ok {
Liz Kammer2222c6b2021-05-24 15:41:47 -0400128 return staticOrSharedAttributes{}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000129 }
130
Jingwen Chenbcf53042021-05-26 04:42:42 +0000131 return bp2buildParseStaticOrSharedProps(ctx, module, lib, true)
Liz Kammer2222c6b2021-05-24 15:41:47 -0400132}
133
Jingwen Chenbcf53042021-05-26 04:42:42 +0000134func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
135 var props StaticOrSharedProperties
136 if isStatic {
137 props = lib.StaticProperties.Static
138 } else {
139 props = lib.SharedProperties.Shared
Jingwen Chen53681ef2021-04-29 08:15:13 +0000140 }
Jingwen Chenbcf53042021-05-26 04:42:42 +0000141
Chris Parsons51f8c392021-08-03 21:01:05 -0400142 system_dynamic_deps := bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.System_shared_libs))
143 system_dynamic_deps.ForceSpecifyEmptyList = true
144 if system_dynamic_deps.IsEmpty() && props.System_shared_libs != nil {
145 system_dynamic_deps.Value.Includes = []bazel.Label{}
146 }
147
Jingwen Chenbcf53042021-05-26 04:42:42 +0000148 attrs := staticOrSharedAttributes{
Chris Parsons51f8c392021-08-03 21:01:05 -0400149 Copts: bazel.StringListAttribute{Value: props.Cflags},
150 Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)),
151 Static_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)),
152 Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)),
153 Whole_archive_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)),
154 System_dynamic_deps: system_dynamic_deps,
Jingwen Chenbcf53042021-05-26 04:42:42 +0000155 }
156
Liz Kammer9abd62d2021-05-21 08:37:59 -0400157 setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000158 attrs.Copts.SetSelectValue(axis, config, props.Cflags)
159 attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
160 attrs.Static_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
161 attrs.Dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
162 attrs.Whole_archive_deps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400163 attrs.System_dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.System_shared_libs))
Jingwen Chenbcf53042021-05-26 04:42:42 +0000164 }
165
166 if isStatic {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400167 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
168 for config, props := range configToProps {
169 if staticOrSharedProps, ok := props.(*StaticProperties); ok {
170 setAttrs(axis, config, staticOrSharedProps.Static)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000171 }
172 }
173 }
174 } else {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400175 for axis, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
176 for config, props := range configToProps {
177 if staticOrSharedProps, ok := props.(*SharedProperties); ok {
178 setAttrs(axis, config, staticOrSharedProps.Shared)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000179 }
180 }
181 }
182 }
183
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000184 cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
185 attrs.Srcs = cppSrcs
186 attrs.Srcs_c = cSrcs
187 attrs.Srcs_as = asSrcs
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000188
Jingwen Chenbcf53042021-05-26 04:42:42 +0000189 return attrs
Jingwen Chen53681ef2021-04-29 08:15:13 +0000190}
191
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400192// Convenience struct to hold all attributes parsed from prebuilt properties.
193type prebuiltAttributes struct {
194 Src bazel.LabelAttribute
195}
196
197func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
198 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
199 prebuiltLinker := prebuiltLibraryLinker.prebuiltLinker
200
201 var srcLabelAttribute bazel.LabelAttribute
202
203 if len(prebuiltLinker.properties.Srcs) > 1 {
204 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file\n")
205 }
206
207 if len(prebuiltLinker.properties.Srcs) == 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400208 srcLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinker.properties.Srcs[0]))
209 }
210 for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
211 for config, props := range configToProps {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400212 if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
213 if len(prebuiltLinkerProperties.Srcs) > 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400214 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
215 continue
216 } else if len(prebuiltLinkerProperties.Srcs) == 0 {
217 continue
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400218 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400219 src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])
220 srcLabelAttribute.SetSelectValue(axis, config, src)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400221 }
222 }
223 }
224
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400225 return prebuiltAttributes{
226 Src: srcLabelAttribute,
227 }
228}
229
Jingwen Chen107c0de2021-04-09 10:43:12 +0000230// Convenience struct to hold all attributes parsed from compiler properties.
231type compilerAttributes struct {
Chris Parsons990c4f42021-05-25 12:10:58 -0400232 // Options for all languages
233 copts bazel.StringListAttribute
234 // Assembly options and sources
235 asFlags bazel.StringListAttribute
236 asSrcs bazel.LabelListAttribute
237 // C options and sources
238 conlyFlags bazel.StringListAttribute
239 cSrcs bazel.LabelListAttribute
240 // C++ options and sources
241 cppFlags bazel.StringListAttribute
Jingwen Chened9c17d2021-04-13 07:14:55 +0000242 srcs bazel.LabelListAttribute
Chris Parsons2c788392021-08-10 11:58:07 -0400243
244 rtti bazel.BoolAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000245}
246
Jingwen Chen63930982021-03-24 10:04:33 -0400247// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000248func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
Jingwen Chen882bcc12021-04-27 05:54:20 +0000249 var srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000250 var copts bazel.StringListAttribute
Chris Parsons990c4f42021-05-25 12:10:58 -0400251 var asFlags bazel.StringListAttribute
252 var conlyFlags bazel.StringListAttribute
253 var cppFlags bazel.StringListAttribute
Chris Parsons2c788392021-08-10 11:58:07 -0400254 var rtti bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400255
Chris Parsons484e50a2021-05-13 15:13:04 -0400256 // Creates the -I flags for a directory, while making the directory relative
Jingwen Chened9c17d2021-04-13 07:14:55 +0000257 // to the exec root for Bazel to work.
Chris Parsons484e50a2021-05-13 15:13:04 -0400258 includeFlags := func(dir string) []string {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000259 // filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
Chris Parsons484e50a2021-05-13 15:13:04 -0400260 moduleDirRootedPath := filepath.Join(ctx.ModuleDir(), dir)
261 return []string{
262 "-I" + moduleDirRootedPath,
263 // Include the bindir-rooted path (using make variable substitution). This most
264 // closely matches Bazel's native include path handling, which allows for dependency
265 // on generated headers in these directories.
266 // TODO(b/188084383): Handle local include directories in Bazel.
267 "-I$(BINDIR)/" + moduleDirRootedPath,
268 }
Jingwen Chened9c17d2021-04-13 07:14:55 +0000269 }
270
Jingwen Chened9c17d2021-04-13 07:14:55 +0000271 // Parse the list of module-relative include directories (-I).
272 parseLocalIncludeDirs := func(baseCompilerProps *BaseCompilerProperties) []string {
273 // include_dirs are root-relative, not module-relative.
274 includeDirs := bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
275 return append(includeDirs, baseCompilerProps.Local_include_dirs...)
276 }
277
Chris Parsons990c4f42021-05-25 12:10:58 -0400278 parseCommandLineFlags := func(soongFlags []string) []string {
279 var result []string
280 for _, flag := range soongFlags {
Colin Cross52aa4e12021-05-25 15:20:39 +0000281 // Soong's cflags can contain spaces, like `-include header.h`. For
282 // Bazel's copts, split them up to be compatible with the
283 // no_copts_tokenization feature.
Chris Parsons990c4f42021-05-25 12:10:58 -0400284 result = append(result, strings.Split(flag, " ")...)
Colin Cross52aa4e12021-05-25 15:20:39 +0000285 }
Chris Parsons990c4f42021-05-25 12:10:58 -0400286 return result
287 }
288
Liz Kammer74deed42021-06-02 13:02:03 -0400289 // Parse srcs from an arch or OS's props value.
Jingwen Chene32e9e02021-04-23 09:17:24 +0000290 parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
Chris Parsons484e50a2021-05-13 15:13:04 -0400291 // Add srcs-like dependencies such as generated files.
292 // First create a LabelList containing these dependencies, then merge the values with srcs.
293 generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
294 generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
Chris Parsons484e50a2021-05-13 15:13:04 -0400295 generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
296
Liz Kammer74deed42021-06-02 13:02:03 -0400297 allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
Chris Parsons484e50a2021-05-13 15:13:04 -0400298 return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000299 }
300
Jingwen Chenc1c26502021-04-05 10:35:13 +0000301 for _, props := range module.compiler.compilerProps() {
302 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400303 srcs.SetValue(parseSrcs(baseCompilerProps))
Chris Parsons69fa9f92021-07-13 11:47:44 -0400304 copts.Value = parseCommandLineFlags(baseCompilerProps.Cflags)
Chris Parsons990c4f42021-05-25 12:10:58 -0400305 asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
306 conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
307 cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
Chris Parsons2c788392021-08-10 11:58:07 -0400308 rtti.Value = baseCompilerProps.Rtti
Jingwen Chene32e9e02021-04-23 09:17:24 +0000309
Chris Parsons69fa9f92021-07-13 11:47:44 -0400310 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
311 copts.Value = append(copts.Value, includeFlags(dir)...)
312 asFlags.Value = append(asFlags.Value, includeFlags(dir)...)
313 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000314 break
315 }
316 }
317
Jingwen Chene32e9e02021-04-23 09:17:24 +0000318 // Handle include_build_directory prop. If the property is true, then the
319 // target has access to all headers recursively in the package, and has
320 // "-I<module-dir>" in its copts.
Jingwen Chened9c17d2021-04-13 07:14:55 +0000321 if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
Chris Parsons484e50a2021-05-13 15:13:04 -0400322 copts.Value = append(copts.Value, includeFlags(".")...)
Chris Parsons69fa9f92021-07-13 11:47:44 -0400323 asFlags.Value = append(asFlags.Value, includeFlags(".")...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000324 } else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
Chris Parsons484e50a2021-05-13 15:13:04 -0400325 copts.Value = append(copts.Value, includeFlags(".")...)
Chris Parsons69fa9f92021-07-13 11:47:44 -0400326 asFlags.Value = append(asFlags.Value, includeFlags(".")...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000327 }
328
Liz Kammer9abd62d2021-05-21 08:37:59 -0400329 archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
Jingwen Chene32e9e02021-04-23 09:17:24 +0000330
Liz Kammer9abd62d2021-05-21 08:37:59 -0400331 for axis, configToProps := range archVariantCompilerProps {
332 for config, props := range configToProps {
333 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
334 // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
335 // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
336 if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
337 srcsList := parseSrcs(baseCompilerProps)
338 srcs.SetSelectValue(axis, config, srcsList)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400339 }
340
Chris Parsons69fa9f92021-07-13 11:47:44 -0400341 archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
342 archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
343 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
344 archVariantCopts = append(archVariantCopts, includeFlags(dir)...)
345 archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
346 }
347
348 copts.SetSelectValue(axis, config, archVariantCopts)
349 asFlags.SetSelectValue(axis, config, archVariantAsflags)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400350 conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
351 cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
Chris Parsons2c788392021-08-10 11:58:07 -0400352 rtti.SetSelectValue(axis, config, baseCompilerProps.Rtti)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400353 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000354 }
355 }
356
Liz Kammer74deed42021-06-02 13:02:03 -0400357 srcs.ResolveExcludes()
Jingwen Chenc1c26502021-04-05 10:35:13 +0000358
Liz Kammerba7a9c52021-05-26 08:45:30 -0400359 productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
360 "Cflags": &copts,
361 "Asflags": &asFlags,
362 "CppFlags": &cppFlags,
363 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400364 productVariableProps := android.ProductVariableProperties(ctx)
Liz Kammerba7a9c52021-05-26 08:45:30 -0400365 for propName, attr := range productVarPropNameToAttribute {
366 if props, exists := productVariableProps[propName]; exists {
367 for _, prop := range props {
368 flags, ok := prop.Property.([]string)
369 if !ok {
370 ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
371 }
372 newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
Liz Kammer47535c52021-06-02 16:02:22 -0400373 attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400374 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400375 }
376 }
377
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000378 srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
379
Jingwen Chen107c0de2021-04-09 10:43:12 +0000380 return compilerAttributes{
Chris Parsons990c4f42021-05-25 12:10:58 -0400381 copts: copts,
382 srcs: srcs,
383 asFlags: asFlags,
384 asSrcs: asSrcs,
385 cSrcs: cSrcs,
386 conlyFlags: conlyFlags,
387 cppFlags: cppFlags,
Chris Parsons2c788392021-08-10 11:58:07 -0400388 rtti: rtti,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000389 }
390}
391
392// Convenience struct to hold all attributes parsed from linker properties.
393type linkerAttributes struct {
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000394 deps bazel.LabelListAttribute
395 dynamicDeps bazel.LabelListAttribute
Chris Parsons51f8c392021-08-03 21:01:05 -0400396 systemDynamicDeps bazel.LabelListAttribute
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000397 wholeArchiveDeps bazel.LabelListAttribute
398 exportedDeps bazel.LabelListAttribute
399 useLibcrt bazel.BoolAttribute
400 linkopts bazel.StringListAttribute
401 versionScript bazel.LabelAttribute
402 stripKeepSymbols bazel.BoolAttribute
403 stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
404 stripKeepSymbolsList bazel.StringListAttribute
405 stripAll bazel.BoolAttribute
406 stripNone bazel.BoolAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000407}
408
Rupert Shuttleworth143be942021-05-09 23:55:51 -0400409// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
410func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
411 flags := linkerProperties.Ldflags
412 if !BoolDefault(linkerProperties.Pack_relocations, true) {
413 flags = append(flags, "-Wl,--pack-dyn-relocs=none")
414 }
415 return flags
416}
417
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200418// bp2BuildParseLinkerProps parses the linker properties of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400419// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000420func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Liz Kammer47535c52021-06-02 16:02:22 -0400421 var headerDeps bazel.LabelListAttribute
422 var staticDeps bazel.LabelListAttribute
Chris Parsonsd6358772021-05-18 18:35:24 -0400423 var exportedDeps bazel.LabelListAttribute
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400424 var dynamicDeps bazel.LabelListAttribute
Chris Parsons08648312021-05-06 16:23:19 -0400425 var wholeArchiveDeps bazel.LabelListAttribute
Chris Parsons51f8c392021-08-03 21:01:05 -0400426 var systemSharedDeps bazel.LabelListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400427 var linkopts bazel.StringListAttribute
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200428 var versionScript bazel.LabelAttribute
Liz Kammerd366c902021-06-03 13:43:01 -0400429 var useLibcrt bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400430
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000431 var stripKeepSymbols bazel.BoolAttribute
432 var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
433 var stripKeepSymbolsList bazel.StringListAttribute
434 var stripAll bazel.BoolAttribute
435 var stripNone bazel.BoolAttribute
436
437 if libraryDecorator, ok := module.linker.(*libraryDecorator); ok {
438 stripProperties := libraryDecorator.stripper.StripProperties
439 stripKeepSymbols.Value = stripProperties.Strip.Keep_symbols
440 stripKeepSymbolsList.Value = stripProperties.Strip.Keep_symbols_list
441 stripKeepSymbolsAndDebugFrame.Value = stripProperties.Strip.Keep_symbols_and_debug_frame
442 stripAll.Value = stripProperties.Strip.All
443 stripNone.Value = stripProperties.Strip.None
444 }
445
446 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
447 for config, props := range configToProps {
448 if stripProperties, ok := props.(*StripProperties); ok {
449 stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
450 stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
451 stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
452 stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
453 stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
454 }
455 }
456 }
457
Jingwen Chen91220d72021-03-24 02:18:33 -0400458 for _, linkerProps := range module.linker.linkerProps() {
459 if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
Liz Kammer47535c52021-06-02 16:02:22 -0400460 // Excludes to parallel Soong:
461 // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
462 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
463 staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
464 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400465 wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400466
467 systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs)
468 systemSharedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
469 systemSharedDeps.ForceSpecifyEmptyList = true
470 if systemSharedDeps.Value.IsNil() && baseLinkerProps.System_shared_libs != nil {
471 systemSharedDeps.Value.Includes = []bazel.Label{}
472 }
473
474 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
475
Liz Kammer47535c52021-06-02 16:02:22 -0400476 dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200477
Liz Kammer47535c52021-06-02 16:02:22 -0400478 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
479 headerDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
480 // TODO(b/188796939): also handle export_static_lib_headers, export_shared_lib_headers,
481 // export_generated_headers
482 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
483 exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
484
485 linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200486 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400487 versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200488 }
Liz Kammerd366c902021-06-03 13:43:01 -0400489 useLibcrt.Value = baseLinkerProps.libCrt()
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400490
Jingwen Chen91220d72021-03-24 02:18:33 -0400491 break
492 }
493 }
494
Liz Kammer9abd62d2021-05-21 08:37:59 -0400495 for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
496 for config, props := range configToProps {
497 if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
Liz Kammer47535c52021-06-02 16:02:22 -0400498 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
499 staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
500 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400501 wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400502
503 systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs)
504 if len(systemSharedLibs) == 0 && baseLinkerProps.System_shared_libs != nil {
505 systemSharedLibs = baseLinkerProps.System_shared_libs
506 }
507 systemSharedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
508
509 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
Liz Kammer47535c52021-06-02 16:02:22 -0400510 dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400511
Liz Kammer47535c52021-06-02 16:02:22 -0400512 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
513 headerDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, headerLibs))
514 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
515 exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
516
517 linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400518 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400519 versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400520 }
Liz Kammerd366c902021-06-03 13:43:01 -0400521 useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400522 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400523 }
524 }
525
Liz Kammer47535c52021-06-02 16:02:22 -0400526 type productVarDep struct {
527 // the name of the corresponding excludes field, if one exists
528 excludesField string
529 // reference to the bazel attribute that should be set for the given product variable config
530 attribute *bazel.LabelListAttribute
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400531
532 depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
Liz Kammer47535c52021-06-02 16:02:22 -0400533 }
534
535 productVarToDepFields := map[string]productVarDep{
536 // product variables do not support exclude_shared_libs
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400537 "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: android.BazelLabelForModuleDepsExcludes},
538 "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, android.BazelLabelForModuleDepsExcludes},
539 "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, android.BazelLabelForModuleWholeDepsExcludes},
Liz Kammer47535c52021-06-02 16:02:22 -0400540 }
541
542 productVariableProps := android.ProductVariableProperties(ctx)
543 for name, dep := range productVarToDepFields {
544 props, exists := productVariableProps[name]
545 excludeProps, excludesExists := productVariableProps[dep.excludesField]
546 // if neither an include or excludes property exists, then skip it
547 if !exists && !excludesExists {
548 continue
549 }
550 // collect all the configurations that an include or exclude property exists for.
551 // we want to iterate all configurations rather than either the include or exclude because for a
552 // particular configuration we may have only and include or only an exclude to handle
553 configs := make(map[string]bool, len(props)+len(excludeProps))
554 for config := range props {
555 configs[config] = true
556 }
557 for config := range excludeProps {
558 configs[config] = true
559 }
560
561 for config := range configs {
562 prop, includesExists := props[config]
563 excludesProp, excludesExists := excludeProps[config]
564 var includes, excludes []string
565 var ok bool
566 // if there was no includes/excludes property, casting fails and that's expected
567 if includes, ok = prop.Property.([]string); includesExists && !ok {
568 ctx.ModuleErrorf("Could not convert product variable %s property", name)
569 }
570 if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
571 ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
572 }
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400573
574 dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
Liz Kammer47535c52021-06-02 16:02:22 -0400575 }
576 }
577
578 staticDeps.ResolveExcludes()
579 dynamicDeps.ResolveExcludes()
580 wholeArchiveDeps.ResolveExcludes()
581
582 headerDeps.Append(staticDeps)
583
Jingwen Chen107c0de2021-04-09 10:43:12 +0000584 return linkerAttributes{
Chris Parsons51f8c392021-08-03 21:01:05 -0400585 deps: headerDeps,
586 exportedDeps: exportedDeps,
587 dynamicDeps: dynamicDeps,
588 systemDynamicDeps: systemSharedDeps,
589 wholeArchiveDeps: wholeArchiveDeps,
590 linkopts: linkopts,
591 useLibcrt: useLibcrt,
592 versionScript: versionScript,
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000593
594 // Strip properties
595 stripKeepSymbols: stripKeepSymbols,
596 stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
597 stripKeepSymbolsList: stripKeepSymbolsList,
598 stripAll: stripAll,
599 stripNone: stripNone,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000600 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400601}
602
Jingwen Chened9c17d2021-04-13 07:14:55 +0000603// Relativize a list of root-relative paths with respect to the module's
604// directory.
605//
606// include_dirs Soong prop are root-relative (b/183742505), but
607// local_include_dirs, export_include_dirs and export_system_include_dirs are
608// module dir relative. This function makes a list of paths entirely module dir
609// relative.
610//
611// For the `include` attribute, Bazel wants the paths to be relative to the
612// module.
613func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000614 var relativePaths []string
615 for _, path := range paths {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000616 // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
617 relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
618 if err != nil {
619 panic(err)
620 }
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000621 relativePaths = append(relativePaths, relativePath)
622 }
623 return relativePaths
624}
625
Jingwen Chen882bcc12021-04-27 05:54:20 +0000626func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
Jingwen Chen91220d72021-03-24 02:18:33 -0400627 libraryDecorator := module.linker.(*libraryDecorator)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400628 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
629}
Jingwen Chen91220d72021-03-24 02:18:33 -0400630
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400631func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
632 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
633 libraryDecorator := prebuiltLibraryLinker.libraryDecorator
634 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
635}
636
637// bp2BuildParseExportedIncludes creates a string list attribute contains the
638// exported included directories of a module.
639func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) bazel.StringListAttribute {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000640 // Export_system_include_dirs and export_include_dirs are already module dir
641 // relative, so they don't need to be relativized like include_dirs, which
642 // are root-relative.
Jingwen Chen91220d72021-03-24 02:18:33 -0400643 includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
644 includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000645 includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
Jingwen Chen91220d72021-03-24 02:18:33 -0400646
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400647 getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties) []string {
648 variantIncludeDirs := flagExporterProperties.Export_system_include_dirs
649 variantIncludeDirs = append(variantIncludeDirs, flagExporterProperties.Export_include_dirs...)
650
651 // To avoid duplicate includes when base includes + arch includes are combined
652 // TODO: This doesn't take conflicts between arch and os includes into account
653 variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
654 return variantIncludeDirs
655 }
656
Liz Kammer9abd62d2021-05-21 08:37:59 -0400657 for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
658 for config, props := range configToProps {
659 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
660 archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties)
661 if len(archVariantIncludeDirs) > 0 {
662 includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400663 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400664 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400665 }
666 }
667
Jingwen Chen882bcc12021-04-27 05:54:20 +0000668 return includeDirsAttribute
Jingwen Chen91220d72021-03-24 02:18:33 -0400669}