blob: fffb0933ab98d356e988213f4c18318bf69d3865 [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 {
Liz Kammer135bf552021-08-11 10:46:06 -0400135 attrs := staticOrSharedAttributes{}
Jingwen Chenbcf53042021-05-26 04:42:42 +0000136
Liz Kammer9abd62d2021-05-21 08:37:59 -0400137 setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000138 attrs.Copts.SetSelectValue(axis, config, props.Cflags)
139 attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
140 attrs.Static_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs))
141 attrs.Dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs))
142 attrs.Whole_archive_deps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400143 attrs.System_dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.System_shared_libs))
Jingwen Chenbcf53042021-05-26 04:42:42 +0000144 }
Liz Kammer135bf552021-08-11 10:46:06 -0400145 // system_dynamic_deps distinguishes between nil/empty list behavior:
146 // nil -> use default values
147 // empty list -> no values specified
148 attrs.System_dynamic_deps.ForceSpecifyEmptyList = true
Jingwen Chenbcf53042021-05-26 04:42:42 +0000149
150 if isStatic {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400151 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
152 for config, props := range configToProps {
153 if staticOrSharedProps, ok := props.(*StaticProperties); ok {
154 setAttrs(axis, config, staticOrSharedProps.Static)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000155 }
156 }
157 }
158 } else {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400159 for axis, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
160 for config, props := range configToProps {
161 if staticOrSharedProps, ok := props.(*SharedProperties); ok {
162 setAttrs(axis, config, staticOrSharedProps.Shared)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000163 }
164 }
165 }
166 }
167
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000168 cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
169 attrs.Srcs = cppSrcs
170 attrs.Srcs_c = cSrcs
171 attrs.Srcs_as = asSrcs
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000172
Jingwen Chenbcf53042021-05-26 04:42:42 +0000173 return attrs
Jingwen Chen53681ef2021-04-29 08:15:13 +0000174}
175
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400176// Convenience struct to hold all attributes parsed from prebuilt properties.
177type prebuiltAttributes struct {
178 Src bazel.LabelAttribute
179}
180
181func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400182 var srcLabelAttribute bazel.LabelAttribute
183
Liz Kammer9abd62d2021-05-21 08:37:59 -0400184 for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
185 for config, props := range configToProps {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400186 if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
187 if len(prebuiltLinkerProperties.Srcs) > 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400188 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
189 continue
190 } else if len(prebuiltLinkerProperties.Srcs) == 0 {
191 continue
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400192 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400193 src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])
194 srcLabelAttribute.SetSelectValue(axis, config, src)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400195 }
196 }
197 }
198
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400199 return prebuiltAttributes{
200 Src: srcLabelAttribute,
201 }
202}
203
Jingwen Chen107c0de2021-04-09 10:43:12 +0000204// Convenience struct to hold all attributes parsed from compiler properties.
205type compilerAttributes struct {
Chris Parsons990c4f42021-05-25 12:10:58 -0400206 // Options for all languages
207 copts bazel.StringListAttribute
208 // Assembly options and sources
209 asFlags bazel.StringListAttribute
210 asSrcs bazel.LabelListAttribute
211 // C options and sources
212 conlyFlags bazel.StringListAttribute
213 cSrcs bazel.LabelListAttribute
214 // C++ options and sources
215 cppFlags bazel.StringListAttribute
Jingwen Chened9c17d2021-04-13 07:14:55 +0000216 srcs bazel.LabelListAttribute
Chris Parsons2c788392021-08-10 11:58:07 -0400217
218 rtti bazel.BoolAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000219}
220
Jingwen Chen63930982021-03-24 10:04:33 -0400221// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000222func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
Jingwen Chen882bcc12021-04-27 05:54:20 +0000223 var srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000224 var copts bazel.StringListAttribute
Chris Parsons990c4f42021-05-25 12:10:58 -0400225 var asFlags bazel.StringListAttribute
226 var conlyFlags bazel.StringListAttribute
227 var cppFlags bazel.StringListAttribute
Chris Parsons2c788392021-08-10 11:58:07 -0400228 var rtti bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400229
Chris Parsons484e50a2021-05-13 15:13:04 -0400230 // Creates the -I flags for a directory, while making the directory relative
Jingwen Chened9c17d2021-04-13 07:14:55 +0000231 // to the exec root for Bazel to work.
Chris Parsons484e50a2021-05-13 15:13:04 -0400232 includeFlags := func(dir string) []string {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000233 // filepath.Join canonicalizes the path, i.e. it takes care of . or .. elements.
Chris Parsons484e50a2021-05-13 15:13:04 -0400234 moduleDirRootedPath := filepath.Join(ctx.ModuleDir(), dir)
235 return []string{
236 "-I" + moduleDirRootedPath,
237 // Include the bindir-rooted path (using make variable substitution). This most
238 // closely matches Bazel's native include path handling, which allows for dependency
239 // on generated headers in these directories.
240 // TODO(b/188084383): Handle local include directories in Bazel.
241 "-I$(BINDIR)/" + moduleDirRootedPath,
242 }
Jingwen Chened9c17d2021-04-13 07:14:55 +0000243 }
244
Jingwen Chened9c17d2021-04-13 07:14:55 +0000245 // Parse the list of module-relative include directories (-I).
246 parseLocalIncludeDirs := func(baseCompilerProps *BaseCompilerProperties) []string {
247 // include_dirs are root-relative, not module-relative.
248 includeDirs := bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
249 return append(includeDirs, baseCompilerProps.Local_include_dirs...)
250 }
251
Chris Parsons990c4f42021-05-25 12:10:58 -0400252 parseCommandLineFlags := func(soongFlags []string) []string {
253 var result []string
254 for _, flag := range soongFlags {
Colin Cross52aa4e12021-05-25 15:20:39 +0000255 // Soong's cflags can contain spaces, like `-include header.h`. For
256 // Bazel's copts, split them up to be compatible with the
257 // no_copts_tokenization feature.
Chris Parsons990c4f42021-05-25 12:10:58 -0400258 result = append(result, strings.Split(flag, " ")...)
Colin Cross52aa4e12021-05-25 15:20:39 +0000259 }
Chris Parsons990c4f42021-05-25 12:10:58 -0400260 return result
261 }
262
Liz Kammer74deed42021-06-02 13:02:03 -0400263 // Parse srcs from an arch or OS's props value.
Jingwen Chene32e9e02021-04-23 09:17:24 +0000264 parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
Chris Parsons484e50a2021-05-13 15:13:04 -0400265 // Add srcs-like dependencies such as generated files.
266 // First create a LabelList containing these dependencies, then merge the values with srcs.
267 generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
268 generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
Chris Parsons484e50a2021-05-13 15:13:04 -0400269 generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
270
Liz Kammer74deed42021-06-02 13:02:03 -0400271 allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
Chris Parsons484e50a2021-05-13 15:13:04 -0400272 return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000273 }
274
Liz Kammer9abd62d2021-05-21 08:37:59 -0400275 archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
Liz Kammer9abd62d2021-05-21 08:37:59 -0400276 for axis, configToProps := range archVariantCompilerProps {
277 for config, props := range configToProps {
278 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
279 // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
280 // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
281 if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
282 srcsList := parseSrcs(baseCompilerProps)
283 srcs.SetSelectValue(axis, config, srcsList)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400284 }
285
Chris Parsons69fa9f92021-07-13 11:47:44 -0400286 archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
287 archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
288 for _, dir := range parseLocalIncludeDirs(baseCompilerProps) {
289 archVariantCopts = append(archVariantCopts, includeFlags(dir)...)
290 archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...)
291 }
292
Liz Kammer135bf552021-08-11 10:46:06 -0400293 if axis == bazel.NoConfigAxis {
294 if includeBuildDirectory(baseCompilerProps.Include_build_directory) {
295 flags := includeFlags(".")
296 archVariantCopts = append(archVariantCopts, flags...)
297 archVariantAsflags = append(archVariantAsflags, flags...)
298 }
299 }
300
Chris Parsons69fa9f92021-07-13 11:47:44 -0400301 copts.SetSelectValue(axis, config, archVariantCopts)
302 asFlags.SetSelectValue(axis, config, archVariantAsflags)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400303 conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
304 cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
Chris Parsons2c788392021-08-10 11:58:07 -0400305 rtti.SetSelectValue(axis, config, baseCompilerProps.Rtti)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400306 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000307 }
308 }
309
Liz Kammer74deed42021-06-02 13:02:03 -0400310 srcs.ResolveExcludes()
Jingwen Chenc1c26502021-04-05 10:35:13 +0000311
Liz Kammerba7a9c52021-05-26 08:45:30 -0400312 productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
313 "Cflags": &copts,
314 "Asflags": &asFlags,
315 "CppFlags": &cppFlags,
316 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400317 productVariableProps := android.ProductVariableProperties(ctx)
Liz Kammerba7a9c52021-05-26 08:45:30 -0400318 for propName, attr := range productVarPropNameToAttribute {
319 if props, exists := productVariableProps[propName]; exists {
320 for _, prop := range props {
321 flags, ok := prop.Property.([]string)
322 if !ok {
323 ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
324 }
325 newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
Liz Kammer47535c52021-06-02 16:02:22 -0400326 attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400327 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400328 }
329 }
330
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000331 srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
332
Jingwen Chen107c0de2021-04-09 10:43:12 +0000333 return compilerAttributes{
Chris Parsons990c4f42021-05-25 12:10:58 -0400334 copts: copts,
335 srcs: srcs,
336 asFlags: asFlags,
337 asSrcs: asSrcs,
338 cSrcs: cSrcs,
339 conlyFlags: conlyFlags,
340 cppFlags: cppFlags,
Chris Parsons2c788392021-08-10 11:58:07 -0400341 rtti: rtti,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000342 }
343}
344
345// Convenience struct to hold all attributes parsed from linker properties.
346type linkerAttributes struct {
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000347 deps bazel.LabelListAttribute
348 dynamicDeps bazel.LabelListAttribute
Chris Parsons51f8c392021-08-03 21:01:05 -0400349 systemDynamicDeps bazel.LabelListAttribute
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000350 wholeArchiveDeps bazel.LabelListAttribute
351 exportedDeps bazel.LabelListAttribute
352 useLibcrt bazel.BoolAttribute
353 linkopts bazel.StringListAttribute
354 versionScript bazel.LabelAttribute
355 stripKeepSymbols bazel.BoolAttribute
356 stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
357 stripKeepSymbolsList bazel.StringListAttribute
358 stripAll bazel.BoolAttribute
359 stripNone bazel.BoolAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000360}
361
Rupert Shuttleworth143be942021-05-09 23:55:51 -0400362// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
363func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
364 flags := linkerProperties.Ldflags
365 if !BoolDefault(linkerProperties.Pack_relocations, true) {
366 flags = append(flags, "-Wl,--pack-dyn-relocs=none")
367 }
368 return flags
369}
370
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200371// bp2BuildParseLinkerProps parses the linker properties of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400372// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000373func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Liz Kammer47535c52021-06-02 16:02:22 -0400374 var headerDeps bazel.LabelListAttribute
375 var staticDeps bazel.LabelListAttribute
Chris Parsonsd6358772021-05-18 18:35:24 -0400376 var exportedDeps bazel.LabelListAttribute
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400377 var dynamicDeps bazel.LabelListAttribute
Chris Parsons08648312021-05-06 16:23:19 -0400378 var wholeArchiveDeps bazel.LabelListAttribute
Liz Kammer135bf552021-08-11 10:46:06 -0400379 systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
Jingwen Chen63930982021-03-24 10:04:33 -0400380 var linkopts bazel.StringListAttribute
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200381 var versionScript bazel.LabelAttribute
Liz Kammerd366c902021-06-03 13:43:01 -0400382 var useLibcrt bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400383
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000384 var stripKeepSymbols bazel.BoolAttribute
385 var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
386 var stripKeepSymbolsList bazel.StringListAttribute
387 var stripAll bazel.BoolAttribute
388 var stripNone bazel.BoolAttribute
389
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000390 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
391 for config, props := range configToProps {
392 if stripProperties, ok := props.(*StripProperties); ok {
393 stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
394 stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
395 stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
396 stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
397 stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
398 }
399 }
400 }
401
Liz Kammer9abd62d2021-05-21 08:37:59 -0400402 for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
403 for config, props := range configToProps {
404 if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
Liz Kammer135bf552021-08-11 10:46:06 -0400405 // Excludes to parallel Soong:
406 // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
Liz Kammer47535c52021-06-02 16:02:22 -0400407 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
408 staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
409 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400410 wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400411
Liz Kammer135bf552021-08-11 10:46:06 -0400412 systemSharedLibs := baseLinkerProps.System_shared_libs
413 // systemSharedLibs distinguishes between nil/empty list behavior:
414 // nil -> use default values
415 // empty list -> no values specified
416 if len(systemSharedLibs) > 0 {
417 systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
Chris Parsons51f8c392021-08-03 21:01:05 -0400418 }
419 systemSharedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, systemSharedLibs))
420
421 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
Liz Kammer47535c52021-06-02 16:02:22 -0400422 dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400423
Liz Kammer47535c52021-06-02 16:02:22 -0400424 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
425 headerDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, headerLibs))
426 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
427 exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs))
428
429 linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400430 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400431 versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400432 }
Liz Kammerd366c902021-06-03 13:43:01 -0400433 useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400434 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400435 }
436 }
437
Liz Kammer47535c52021-06-02 16:02:22 -0400438 type productVarDep struct {
439 // the name of the corresponding excludes field, if one exists
440 excludesField string
441 // reference to the bazel attribute that should be set for the given product variable config
442 attribute *bazel.LabelListAttribute
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400443
444 depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
Liz Kammer47535c52021-06-02 16:02:22 -0400445 }
446
447 productVarToDepFields := map[string]productVarDep{
448 // product variables do not support exclude_shared_libs
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400449 "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: android.BazelLabelForModuleDepsExcludes},
450 "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, android.BazelLabelForModuleDepsExcludes},
451 "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, android.BazelLabelForModuleWholeDepsExcludes},
Liz Kammer47535c52021-06-02 16:02:22 -0400452 }
453
454 productVariableProps := android.ProductVariableProperties(ctx)
455 for name, dep := range productVarToDepFields {
456 props, exists := productVariableProps[name]
457 excludeProps, excludesExists := productVariableProps[dep.excludesField]
458 // if neither an include or excludes property exists, then skip it
459 if !exists && !excludesExists {
460 continue
461 }
462 // collect all the configurations that an include or exclude property exists for.
463 // we want to iterate all configurations rather than either the include or exclude because for a
464 // particular configuration we may have only and include or only an exclude to handle
465 configs := make(map[string]bool, len(props)+len(excludeProps))
466 for config := range props {
467 configs[config] = true
468 }
469 for config := range excludeProps {
470 configs[config] = true
471 }
472
473 for config := range configs {
474 prop, includesExists := props[config]
475 excludesProp, excludesExists := excludeProps[config]
476 var includes, excludes []string
477 var ok bool
478 // if there was no includes/excludes property, casting fails and that's expected
479 if includes, ok = prop.Property.([]string); includesExists && !ok {
480 ctx.ModuleErrorf("Could not convert product variable %s property", name)
481 }
482 if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
483 ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
484 }
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400485
486 dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
Liz Kammer47535c52021-06-02 16:02:22 -0400487 }
488 }
489
490 staticDeps.ResolveExcludes()
491 dynamicDeps.ResolveExcludes()
492 wholeArchiveDeps.ResolveExcludes()
493
494 headerDeps.Append(staticDeps)
495
Jingwen Chen107c0de2021-04-09 10:43:12 +0000496 return linkerAttributes{
Chris Parsons51f8c392021-08-03 21:01:05 -0400497 deps: headerDeps,
498 exportedDeps: exportedDeps,
499 dynamicDeps: dynamicDeps,
500 systemDynamicDeps: systemSharedDeps,
501 wholeArchiveDeps: wholeArchiveDeps,
502 linkopts: linkopts,
503 useLibcrt: useLibcrt,
504 versionScript: versionScript,
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000505
506 // Strip properties
507 stripKeepSymbols: stripKeepSymbols,
508 stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
509 stripKeepSymbolsList: stripKeepSymbolsList,
510 stripAll: stripAll,
511 stripNone: stripNone,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000512 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400513}
514
Jingwen Chened9c17d2021-04-13 07:14:55 +0000515// Relativize a list of root-relative paths with respect to the module's
516// directory.
517//
518// include_dirs Soong prop are root-relative (b/183742505), but
519// local_include_dirs, export_include_dirs and export_system_include_dirs are
520// module dir relative. This function makes a list of paths entirely module dir
521// relative.
522//
523// For the `include` attribute, Bazel wants the paths to be relative to the
524// module.
525func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000526 var relativePaths []string
527 for _, path := range paths {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000528 // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
529 relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
530 if err != nil {
531 panic(err)
532 }
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000533 relativePaths = append(relativePaths, relativePath)
534 }
535 return relativePaths
536}
537
Liz Kammer5fad5012021-09-09 14:08:21 -0400538// BazelIncludes contains information about -I and -isystem paths from a module converted to Bazel
539// attributes.
540type BazelIncludes struct {
541 Includes bazel.StringListAttribute
542 SystemIncludes bazel.StringListAttribute
543}
544
545func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) BazelIncludes {
Jingwen Chen91220d72021-03-24 02:18:33 -0400546 libraryDecorator := module.linker.(*libraryDecorator)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400547 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
548}
Jingwen Chen91220d72021-03-24 02:18:33 -0400549
Liz Kammer5fad5012021-09-09 14:08:21 -0400550// Bp2buildParseExportedIncludesForPrebuiltLibrary returns a BazelIncludes with Bazel-ified values
551// to export includes from the underlying module's properties.
552func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) BazelIncludes {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400553 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
554 libraryDecorator := prebuiltLibraryLinker.libraryDecorator
555 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
556}
557
558// bp2BuildParseExportedIncludes creates a string list attribute contains the
559// exported included directories of a module.
Liz Kammer5fad5012021-09-09 14:08:21 -0400560func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) BazelIncludes {
561 exported := BazelIncludes{}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400562 for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
563 for config, props := range configToProps {
564 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
Liz Kammer5fad5012021-09-09 14:08:21 -0400565 if len(flagExporterProperties.Export_include_dirs) > 0 {
566 exported.Includes.SetSelectValue(axis, config, flagExporterProperties.Export_include_dirs)
567 }
568 if len(flagExporterProperties.Export_system_include_dirs) > 0 {
569 exported.SystemIncludes.SetSelectValue(axis, config, flagExporterProperties.Export_system_include_dirs)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400570 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400571 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400572 }
573 }
Liz Kammer5fad5012021-09-09 14:08:21 -0400574 exported.Includes.DeduplicateAxesFromBase()
575 exported.SystemIncludes.DeduplicateAxesFromBase()
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400576
Liz Kammer5fad5012021-09-09 14:08:21 -0400577 return exported
Jingwen Chen91220d72021-03-24 02:18:33 -0400578}