blob: 7a57477e3bf3a79a947042b657b4aa2913659cad [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
Jingwen Chen107c0de2021-04-09 10:43:12 +0000243}
244
Jingwen Chen63930982021-03-24 10:04:33 -0400245// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000246func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
Jingwen Chen882bcc12021-04-27 05:54:20 +0000247 var srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000248 var copts bazel.StringListAttribute
Chris Parsons990c4f42021-05-25 12:10:58 -0400249 var asFlags bazel.StringListAttribute
250 var conlyFlags bazel.StringListAttribute
251 var cppFlags bazel.StringListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400252
Chris Parsons484e50a2021-05-13 15:13:04 -0400253 // Creates the -I flags for a directory, while making the directory relative
Jingwen Chened9c17d2021-04-13 07:14:55 +0000254 // to the exec root for Bazel to work.
Chris Parsons484e50a2021-05-13 15:13:04 -0400255 includeFlags := func(dir string) []string {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000256 // filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
Chris Parsons484e50a2021-05-13 15:13:04 -0400257 moduleDirRootedPath := filepath.Join(ctx.ModuleDir(), dir)
258 return []string{
259 "-I" + moduleDirRootedPath,
260 // Include the bindir-rooted path (using make variable substitution). This most
261 // closely matches Bazel's native include path handling, which allows for dependency
262 // on generated headers in these directories.
263 // TODO(b/188084383): Handle local include directories in Bazel.
264 "-I$(BINDIR)/" + moduleDirRootedPath,
265 }
Jingwen Chened9c17d2021-04-13 07:14:55 +0000266 }
267
Jingwen Chened9c17d2021-04-13 07:14:55 +0000268 // Parse the list of module-relative include directories (-I).
269 parseLocalIncludeDirs := func(baseCompilerProps *BaseCompilerProperties) []string {
270 // include_dirs are root-relative, not module-relative.
271 includeDirs := bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
272 return append(includeDirs, baseCompilerProps.Local_include_dirs...)
273 }
274
Chris Parsons990c4f42021-05-25 12:10:58 -0400275 parseCommandLineFlags := func(soongFlags []string) []string {
276 var result []string
277 for _, flag := range soongFlags {
Colin Cross52aa4e12021-05-25 15:20:39 +0000278 // Soong's cflags can contain spaces, like `-include header.h`. For
279 // Bazel's copts, split them up to be compatible with the
280 // no_copts_tokenization feature.
Chris Parsons990c4f42021-05-25 12:10:58 -0400281 result = append(result, strings.Split(flag, " ")...)
Colin Cross52aa4e12021-05-25 15:20:39 +0000282 }
Chris Parsons990c4f42021-05-25 12:10:58 -0400283 return result
284 }
285
Liz Kammer74deed42021-06-02 13:02:03 -0400286 // Parse srcs from an arch or OS's props value.
Jingwen Chene32e9e02021-04-23 09:17:24 +0000287 parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
Chris Parsons484e50a2021-05-13 15:13:04 -0400288 // Add srcs-like dependencies such as generated files.
289 // First create a LabelList containing these dependencies, then merge the values with srcs.
290 generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
291 generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
Chris Parsons484e50a2021-05-13 15:13:04 -0400292 generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
293
Liz Kammer74deed42021-06-02 13:02:03 -0400294 allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
Chris Parsons484e50a2021-05-13 15:13:04 -0400295 return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000296 }
297
Jingwen Chenc1c26502021-04-05 10:35:13 +0000298 for _, props := range module.compiler.compilerProps() {
299 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400300 srcs.SetValue(parseSrcs(baseCompilerProps))
Chris Parsons69fa9f92021-07-13 11:47:44 -0400301 copts.Value = parseCommandLineFlags(baseCompilerProps.Cflags)
Chris Parsons990c4f42021-05-25 12:10:58 -0400302 asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags)
303 conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags)
304 cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000305
Chris Parsons69fa9f92021-07-13 11:47:44 -0400306 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
307 copts.Value = append(copts.Value, includeFlags(dir)...)
308 asFlags.Value = append(asFlags.Value, includeFlags(dir)...)
309 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000310 break
311 }
312 }
313
Jingwen Chene32e9e02021-04-23 09:17:24 +0000314 // Handle include_build_directory prop. If the property is true, then the
315 // target has access to all headers recursively in the package, and has
316 // "-I<module-dir>" in its copts.
Jingwen Chened9c17d2021-04-13 07:14:55 +0000317 if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() {
Chris Parsons484e50a2021-05-13 15:13:04 -0400318 copts.Value = append(copts.Value, includeFlags(".")...)
Chris Parsons69fa9f92021-07-13 11:47:44 -0400319 asFlags.Value = append(asFlags.Value, includeFlags(".")...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000320 } else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() {
Chris Parsons484e50a2021-05-13 15:13:04 -0400321 copts.Value = append(copts.Value, includeFlags(".")...)
Chris Parsons69fa9f92021-07-13 11:47:44 -0400322 asFlags.Value = append(asFlags.Value, includeFlags(".")...)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000323 }
324
Liz Kammer9abd62d2021-05-21 08:37:59 -0400325 archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
Jingwen Chene32e9e02021-04-23 09:17:24 +0000326
Liz Kammer9abd62d2021-05-21 08:37:59 -0400327 for axis, configToProps := range archVariantCompilerProps {
328 for config, props := range configToProps {
329 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
330 // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
331 // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
332 if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
333 srcsList := parseSrcs(baseCompilerProps)
334 srcs.SetSelectValue(axis, config, srcsList)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400335 }
336
Chris Parsons69fa9f92021-07-13 11:47:44 -0400337 archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
338 archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
339 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
340 archVariantCopts = append(archVariantCopts, includeFlags(dir)...)
341 archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
342 }
343
344 copts.SetSelectValue(axis, config, archVariantCopts)
345 asFlags.SetSelectValue(axis, config, archVariantAsflags)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400346 conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
347 cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
348 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000349 }
350 }
351
Liz Kammer74deed42021-06-02 13:02:03 -0400352 srcs.ResolveExcludes()
Jingwen Chenc1c26502021-04-05 10:35:13 +0000353
Liz Kammerba7a9c52021-05-26 08:45:30 -0400354 productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
355 "Cflags": &copts,
356 "Asflags": &asFlags,
357 "CppFlags": &cppFlags,
358 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400359 productVariableProps := android.ProductVariableProperties(ctx)
Liz Kammerba7a9c52021-05-26 08:45:30 -0400360 for propName, attr := range productVarPropNameToAttribute {
361 if props, exists := productVariableProps[propName]; exists {
362 for _, prop := range props {
363 flags, ok := prop.Property.([]string)
364 if !ok {
365 ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
366 }
367 newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
Liz Kammer47535c52021-06-02 16:02:22 -0400368 attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400369 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400370 }
371 }
372
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000373 srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
374
Jingwen Chen107c0de2021-04-09 10:43:12 +0000375 return compilerAttributes{
Chris Parsons990c4f42021-05-25 12:10:58 -0400376 copts: copts,
377 srcs: srcs,
378 asFlags: asFlags,
379 asSrcs: asSrcs,
380 cSrcs: cSrcs,
381 conlyFlags: conlyFlags,
382 cppFlags: cppFlags,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000383 }
384}
385
386// Convenience struct to hold all attributes parsed from linker properties.
387type linkerAttributes struct {
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000388 deps bazel.LabelListAttribute
389 dynamicDeps bazel.LabelListAttribute
Chris Parsons51f8c392021-08-03 21:01:05 -0400390 systemDynamicDeps bazel.LabelListAttribute
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000391 wholeArchiveDeps bazel.LabelListAttribute
392 exportedDeps bazel.LabelListAttribute
393 useLibcrt bazel.BoolAttribute
394 linkopts bazel.StringListAttribute
395 versionScript bazel.LabelAttribute
396 stripKeepSymbols bazel.BoolAttribute
397 stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
398 stripKeepSymbolsList bazel.StringListAttribute
399 stripAll bazel.BoolAttribute
400 stripNone bazel.BoolAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000401}
402
Rupert Shuttleworth143be942021-05-09 23:55:51 -0400403// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
404func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
405 flags := linkerProperties.Ldflags
406 if !BoolDefault(linkerProperties.Pack_relocations, true) {
407 flags = append(flags, "-Wl,--pack-dyn-relocs=none")
408 }
409 return flags
410}
411
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200412// bp2BuildParseLinkerProps parses the linker properties of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400413// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000414func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Liz Kammer47535c52021-06-02 16:02:22 -0400415 var headerDeps bazel.LabelListAttribute
416 var staticDeps bazel.LabelListAttribute
Chris Parsonsd6358772021-05-18 18:35:24 -0400417 var exportedDeps bazel.LabelListAttribute
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400418 var dynamicDeps bazel.LabelListAttribute
Chris Parsons08648312021-05-06 16:23:19 -0400419 var wholeArchiveDeps bazel.LabelListAttribute
Chris Parsons51f8c392021-08-03 21:01:05 -0400420 var systemSharedDeps bazel.LabelListAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400421 var linkopts bazel.StringListAttribute
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200422 var versionScript bazel.LabelAttribute
Liz Kammerd366c902021-06-03 13:43:01 -0400423 var useLibcrt bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400424
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000425 var stripKeepSymbols bazel.BoolAttribute
426 var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
427 var stripKeepSymbolsList bazel.StringListAttribute
428 var stripAll bazel.BoolAttribute
429 var stripNone bazel.BoolAttribute
430
431 if libraryDecorator, ok := module.linker.(*libraryDecorator); ok {
432 stripProperties := libraryDecorator.stripper.StripProperties
433 stripKeepSymbols.Value = stripProperties.Strip.Keep_symbols
434 stripKeepSymbolsList.Value = stripProperties.Strip.Keep_symbols_list
435 stripKeepSymbolsAndDebugFrame.Value = stripProperties.Strip.Keep_symbols_and_debug_frame
436 stripAll.Value = stripProperties.Strip.All
437 stripNone.Value = stripProperties.Strip.None
438 }
439
440 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
441 for config, props := range configToProps {
442 if stripProperties, ok := props.(*StripProperties); ok {
443 stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
444 stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
445 stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
446 stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
447 stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
448 }
449 }
450 }
451
Jingwen Chen91220d72021-03-24 02:18:33 -0400452 for _, linkerProps := range module.linker.linkerProps() {
453 if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
Liz Kammer47535c52021-06-02 16:02:22 -0400454 // Excludes to parallel Soong:
455 // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
456 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
457 staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)
458 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400459 wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400460
461 systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs)
462 systemSharedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
463 systemSharedDeps.ForceSpecifyEmptyList = true
464 if systemSharedDeps.Value.IsNil() && baseLinkerProps.System_shared_libs != nil {
465 systemSharedDeps.Value.Includes = []bazel.Label{}
466 }
467
468 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
469
Liz Kammer47535c52021-06-02 16:02:22 -0400470 dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200471
Liz Kammer47535c52021-06-02 16:02:22 -0400472 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
473 headerDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, headerLibs))
474 // TODO(b/188796939): also handle export_static_lib_headers, export_shared_lib_headers,
475 // export_generated_headers
476 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
477 exportedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, exportedLibs))
478
479 linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200480 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400481 versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200482 }
Liz Kammerd366c902021-06-03 13:43:01 -0400483 useLibcrt.Value = baseLinkerProps.libCrt()
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400484
Jingwen Chen91220d72021-03-24 02:18:33 -0400485 break
486 }
487 }
488
Liz Kammer9abd62d2021-05-21 08:37:59 -0400489 for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
490 for config, props := range configToProps {
491 if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
Liz Kammer47535c52021-06-02 16:02:22 -0400492 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
493 staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
494 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400495 wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400496
497 systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs)
498 if len(systemSharedLibs) == 0 && baseLinkerProps.System_shared_libs != nil {
499 systemSharedLibs = baseLinkerProps.System_shared_libs
500 }
501 systemSharedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
502
503 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
Liz Kammer47535c52021-06-02 16:02:22 -0400504 dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400505
Liz Kammer47535c52021-06-02 16:02:22 -0400506 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
507 headerDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, headerLibs))
508 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
509 exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
510
511 linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400512 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400513 versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400514 }
Liz Kammerd366c902021-06-03 13:43:01 -0400515 useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400516 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400517 }
518 }
519
Liz Kammer47535c52021-06-02 16:02:22 -0400520 type productVarDep struct {
521 // the name of the corresponding excludes field, if one exists
522 excludesField string
523 // reference to the bazel attribute that should be set for the given product variable config
524 attribute *bazel.LabelListAttribute
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400525
526 depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
Liz Kammer47535c52021-06-02 16:02:22 -0400527 }
528
529 productVarToDepFields := map[string]productVarDep{
530 // product variables do not support exclude_shared_libs
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400531 "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: android.BazelLabelForModuleDepsExcludes},
532 "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, android.BazelLabelForModuleDepsExcludes},
533 "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, android.BazelLabelForModuleWholeDepsExcludes},
Liz Kammer47535c52021-06-02 16:02:22 -0400534 }
535
536 productVariableProps := android.ProductVariableProperties(ctx)
537 for name, dep := range productVarToDepFields {
538 props, exists := productVariableProps[name]
539 excludeProps, excludesExists := productVariableProps[dep.excludesField]
540 // if neither an include or excludes property exists, then skip it
541 if !exists && !excludesExists {
542 continue
543 }
544 // collect all the configurations that an include or exclude property exists for.
545 // we want to iterate all configurations rather than either the include or exclude because for a
546 // particular configuration we may have only and include or only an exclude to handle
547 configs := make(map[string]bool, len(props)+len(excludeProps))
548 for config := range props {
549 configs[config] = true
550 }
551 for config := range excludeProps {
552 configs[config] = true
553 }
554
555 for config := range configs {
556 prop, includesExists := props[config]
557 excludesProp, excludesExists := excludeProps[config]
558 var includes, excludes []string
559 var ok bool
560 // if there was no includes/excludes property, casting fails and that's expected
561 if includes, ok = prop.Property.([]string); includesExists && !ok {
562 ctx.ModuleErrorf("Could not convert product variable %s property", name)
563 }
564 if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
565 ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
566 }
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400567
568 dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
Liz Kammer47535c52021-06-02 16:02:22 -0400569 }
570 }
571
572 staticDeps.ResolveExcludes()
573 dynamicDeps.ResolveExcludes()
574 wholeArchiveDeps.ResolveExcludes()
575
576 headerDeps.Append(staticDeps)
577
Jingwen Chen107c0de2021-04-09 10:43:12 +0000578 return linkerAttributes{
Chris Parsons51f8c392021-08-03 21:01:05 -0400579 deps: headerDeps,
580 exportedDeps: exportedDeps,
581 dynamicDeps: dynamicDeps,
582 systemDynamicDeps: systemSharedDeps,
583 wholeArchiveDeps: wholeArchiveDeps,
584 linkopts: linkopts,
585 useLibcrt: useLibcrt,
586 versionScript: versionScript,
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000587
588 // Strip properties
589 stripKeepSymbols: stripKeepSymbols,
590 stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
591 stripKeepSymbolsList: stripKeepSymbolsList,
592 stripAll: stripAll,
593 stripNone: stripNone,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000594 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400595}
596
Jingwen Chened9c17d2021-04-13 07:14:55 +0000597// Relativize a list of root-relative paths with respect to the module's
598// directory.
599//
600// include_dirs Soong prop are root-relative (b/183742505), but
601// local_include_dirs, export_include_dirs and export_system_include_dirs are
602// module dir relative. This function makes a list of paths entirely module dir
603// relative.
604//
605// For the `include` attribute, Bazel wants the paths to be relative to the
606// module.
607func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000608 var relativePaths []string
609 for _, path := range paths {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000610 // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
611 relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
612 if err != nil {
613 panic(err)
614 }
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000615 relativePaths = append(relativePaths, relativePath)
616 }
617 return relativePaths
618}
619
Jingwen Chen882bcc12021-04-27 05:54:20 +0000620func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
Jingwen Chen91220d72021-03-24 02:18:33 -0400621 libraryDecorator := module.linker.(*libraryDecorator)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400622 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
623}
Jingwen Chen91220d72021-03-24 02:18:33 -0400624
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400625func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
626 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
627 libraryDecorator := prebuiltLibraryLinker.libraryDecorator
628 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
629}
630
631// bp2BuildParseExportedIncludes creates a string list attribute contains the
632// exported included directories of a module.
633func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) bazel.StringListAttribute {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000634 // Export_system_include_dirs and export_include_dirs are already module dir
635 // relative, so they don't need to be relativized like include_dirs, which
636 // are root-relative.
Jingwen Chen91220d72021-03-24 02:18:33 -0400637 includeDirs := libraryDecorator.flagExporter.Properties.Export_system_include_dirs
638 includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...)
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000639 includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs)
Jingwen Chen91220d72021-03-24 02:18:33 -0400640
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400641 getVariantIncludeDirs := func(includeDirs []string, flagExporterProperties *FlagExporterProperties) []string {
642 variantIncludeDirs := flagExporterProperties.Export_system_include_dirs
643 variantIncludeDirs = append(variantIncludeDirs, flagExporterProperties.Export_include_dirs...)
644
645 // To avoid duplicate includes when base includes + arch includes are combined
646 // TODO: This doesn't take conflicts between arch and os includes into account
647 variantIncludeDirs = bazel.SubtractStrings(variantIncludeDirs, includeDirs)
648 return variantIncludeDirs
649 }
650
Liz Kammer9abd62d2021-05-21 08:37:59 -0400651 for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
652 for config, props := range configToProps {
653 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
654 archVariantIncludeDirs := getVariantIncludeDirs(includeDirs, flagExporterProperties)
655 if len(archVariantIncludeDirs) > 0 {
656 includeDirsAttribute.SetSelectValue(axis, config, archVariantIncludeDirs)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400657 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400658 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400659 }
660 }
661
Jingwen Chen882bcc12021-04-27 05:54:20 +0000662 return includeDirsAttribute
Jingwen Chen91220d72021-03-24 02:18:33 -0400663}