blob: e48f757dc8df58934a7bf4448d791bf62f70cf3d [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"
Chris Parsons953b3562021-09-20 15:14:39 -040023 "github.com/google/blueprint"
Liz Kammerba7a9c52021-05-26 08:45:30 -040024
25 "github.com/google/blueprint/proptools"
Jingwen Chen91220d72021-03-24 02:18:33 -040026)
27
Liz Kammer2222c6b2021-05-24 15:41:47 -040028// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
Jingwen Chenbcf53042021-05-26 04:42:42 +000029// properties which apply to either the shared or static version of a cc_library module.
Liz Kammer2222c6b2021-05-24 15:41:47 -040030type staticOrSharedAttributes struct {
Jingwen Chenc4dc9b42021-06-11 12:51:48 +000031 Srcs bazel.LabelListAttribute
32 Srcs_c bazel.LabelListAttribute
33 Srcs_as bazel.LabelListAttribute
34 Copts bazel.StringListAttribute
Jingwen Chen14a8bda2021-06-02 11:10:02 +000035
Jingwen Chenc4dc9b42021-06-11 12:51:48 +000036 Static_deps bazel.LabelListAttribute
37 Dynamic_deps bazel.LabelListAttribute
38 Whole_archive_deps bazel.LabelListAttribute
Chris Parsons51f8c392021-08-03 21:01:05 -040039
40 System_dynamic_deps bazel.LabelListAttribute
Jingwen Chen53681ef2021-04-29 08:15:13 +000041}
42
Jingwen Chen14a8bda2021-06-02 11:10:02 +000043func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) {
44 // Branch srcs into three language-specific groups.
45 // C++ is the "catch-all" group, and comprises generated sources because we don't
46 // know the language of these sources until the genrule is executed.
47 // TODO(b/190006308): Handle language detection of sources in a Bazel rule.
48 isCSrcOrFilegroup := func(s string) bool {
49 return strings.HasSuffix(s, ".c") || strings.HasSuffix(s, "_c_srcs")
50 }
51
52 isAsmSrcOrFilegroup := func(s string) bool {
53 return strings.HasSuffix(s, ".S") || strings.HasSuffix(s, ".s") || strings.HasSuffix(s, "_as_srcs")
54 }
55
56 // Check that a module is a filegroup type named <label>.
57 isFilegroupNamed := func(m android.Module, fullLabel string) bool {
58 if ctx.OtherModuleType(m) != "filegroup" {
59 return false
60 }
61 labelParts := strings.Split(fullLabel, ":")
62 if len(labelParts) > 2 {
63 // There should not be more than one colon in a label.
64 panic(fmt.Errorf("%s is not a valid Bazel label for a filegroup", fullLabel))
65 } else {
66 return m.Name() == labelParts[len(labelParts)-1]
67 }
68 }
69
70 // Convert the filegroup dependencies into the extension-specific filegroups
71 // filtered in the filegroup.bzl macro.
72 cppFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040073 m, exists := ctx.ModuleFromName(label)
74 if exists {
75 aModule, _ := m.(android.Module)
76 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000077 label = label + "_cpp_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000078 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040079 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000080 return label
81 }
82 cFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040083 m, exists := ctx.ModuleFromName(label)
84 if exists {
85 aModule, _ := m.(android.Module)
86 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000087 label = label + "_c_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000088 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040089 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000090 return label
91 }
92 asFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040093 m, exists := ctx.ModuleFromName(label)
94 if exists {
95 aModule, _ := m.(android.Module)
96 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000097 label = label + "_as_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000098 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040099 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000100 return label
101 }
102
103 cSrcs = bazel.MapLabelListAttribute(srcs, cFilegroup)
104 cSrcs = bazel.FilterLabelListAttribute(cSrcs, isCSrcOrFilegroup)
105
106 asSrcs = bazel.MapLabelListAttribute(srcs, asFilegroup)
107 asSrcs = bazel.FilterLabelListAttribute(asSrcs, isAsmSrcOrFilegroup)
108
109 cppSrcs = bazel.MapLabelListAttribute(srcs, cppFilegroup)
110 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, cSrcs)
111 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, asSrcs)
112 return
113}
114
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000115// bp2BuildParseLibProps returns the attributes for a variant of a cc_library.
116func bp2BuildParseLibProps(ctx android.TopDownMutatorContext, module *Module, isStatic bool) staticOrSharedAttributes {
Jingwen Chen53681ef2021-04-29 08:15:13 +0000117 lib, ok := module.compiler.(*libraryDecorator)
118 if !ok {
Liz Kammer2222c6b2021-05-24 15:41:47 -0400119 return staticOrSharedAttributes{}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000120 }
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000121 return bp2buildParseStaticOrSharedProps(ctx, module, lib, isStatic)
122}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000123
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000124// bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
125func bp2BuildParseSharedProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
126 return bp2BuildParseLibProps(ctx, module, false)
Jingwen Chen53681ef2021-04-29 08:15:13 +0000127}
128
129// bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400130func bp2BuildParseStaticProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000131 return bp2BuildParseLibProps(ctx, module, 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))
Chris Parsons953b3562021-09-20 15:14:39 -0400140 attrs.Static_deps.SetSelectValue(axis, config, bazelLabelForStaticDeps(ctx, props.Static_libs))
141 attrs.Dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.Shared_libs))
142 attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs))
143 attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(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
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000181// NOTE: Used outside of Soong repo project, in the clangprebuilts.go bootstrap_go_package
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400182func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400183 var srcLabelAttribute bazel.LabelAttribute
184
Liz Kammer9abd62d2021-05-21 08:37:59 -0400185 for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
186 for config, props := range configToProps {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400187 if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
188 if len(prebuiltLinkerProperties.Srcs) > 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400189 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
190 continue
191 } else if len(prebuiltLinkerProperties.Srcs) == 0 {
192 continue
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400193 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400194 src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])
195 srcLabelAttribute.SetSelectValue(axis, config, src)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400196 }
197 }
198 }
199
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400200 return prebuiltAttributes{
201 Src: srcLabelAttribute,
202 }
203}
204
Jingwen Chen107c0de2021-04-09 10:43:12 +0000205// Convenience struct to hold all attributes parsed from compiler properties.
206type compilerAttributes struct {
Chris Parsons990c4f42021-05-25 12:10:58 -0400207 // Options for all languages
208 copts bazel.StringListAttribute
209 // Assembly options and sources
210 asFlags bazel.StringListAttribute
211 asSrcs bazel.LabelListAttribute
212 // C options and sources
213 conlyFlags bazel.StringListAttribute
214 cSrcs bazel.LabelListAttribute
215 // C++ options and sources
216 cppFlags bazel.StringListAttribute
Jingwen Chened9c17d2021-04-13 07:14:55 +0000217 srcs bazel.LabelListAttribute
Chris Parsons2c788392021-08-10 11:58:07 -0400218
219 rtti bazel.BoolAttribute
Liz Kammer35687bc2021-09-10 10:07:07 -0400220
221 localIncludes bazel.StringListAttribute
222 absoluteIncludes bazel.StringListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000223}
224
Jingwen Chen63930982021-03-24 10:04:33 -0400225// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000226func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
Jingwen Chen882bcc12021-04-27 05:54:20 +0000227 var srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000228 var copts bazel.StringListAttribute
Chris Parsons990c4f42021-05-25 12:10:58 -0400229 var asFlags bazel.StringListAttribute
230 var conlyFlags bazel.StringListAttribute
231 var cppFlags bazel.StringListAttribute
Chris Parsons2c788392021-08-10 11:58:07 -0400232 var rtti bazel.BoolAttribute
Liz Kammer35687bc2021-09-10 10:07:07 -0400233 var localIncludes bazel.StringListAttribute
234 var absoluteIncludes bazel.StringListAttribute
Jingwen Chened9c17d2021-04-13 07:14:55 +0000235
Chris Parsons990c4f42021-05-25 12:10:58 -0400236 parseCommandLineFlags := func(soongFlags []string) []string {
237 var result []string
238 for _, flag := range soongFlags {
Colin Cross52aa4e12021-05-25 15:20:39 +0000239 // Soong's cflags can contain spaces, like `-include header.h`. For
240 // Bazel's copts, split them up to be compatible with the
241 // no_copts_tokenization feature.
Chris Parsons990c4f42021-05-25 12:10:58 -0400242 result = append(result, strings.Split(flag, " ")...)
Colin Cross52aa4e12021-05-25 15:20:39 +0000243 }
Chris Parsons990c4f42021-05-25 12:10:58 -0400244 return result
245 }
246
Liz Kammer74deed42021-06-02 13:02:03 -0400247 // Parse srcs from an arch or OS's props value.
Jingwen Chene32e9e02021-04-23 09:17:24 +0000248 parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
Chris Parsons484e50a2021-05-13 15:13:04 -0400249 // Add srcs-like dependencies such as generated files.
250 // First create a LabelList containing these dependencies, then merge the values with srcs.
251 generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
252 generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
Chris Parsons484e50a2021-05-13 15:13:04 -0400253 generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
254
Liz Kammer74deed42021-06-02 13:02:03 -0400255 allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
Chris Parsons484e50a2021-05-13 15:13:04 -0400256 return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000257 }
258
Liz Kammer9abd62d2021-05-21 08:37:59 -0400259 archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
Liz Kammer9abd62d2021-05-21 08:37:59 -0400260 for axis, configToProps := range archVariantCompilerProps {
261 for config, props := range configToProps {
262 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
263 // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
264 // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
265 if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
266 srcsList := parseSrcs(baseCompilerProps)
267 srcs.SetSelectValue(axis, config, srcsList)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400268 }
269
Chris Parsons69fa9f92021-07-13 11:47:44 -0400270 archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
271 archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
Liz Kammer35687bc2021-09-10 10:07:07 -0400272
273 localIncludeDirs := baseCompilerProps.Local_include_dirs
274 if axis == bazel.NoConfigAxis && includeBuildDirectory(baseCompilerProps.Include_build_directory) {
275 localIncludeDirs = append(localIncludeDirs, ".")
Chris Parsons69fa9f92021-07-13 11:47:44 -0400276 }
277
Liz Kammer35687bc2021-09-10 10:07:07 -0400278 absoluteIncludes.SetSelectValue(axis, config, baseCompilerProps.Include_dirs)
279 localIncludes.SetSelectValue(axis, config, localIncludeDirs)
Liz Kammer135bf552021-08-11 10:46:06 -0400280
Chris Parsons69fa9f92021-07-13 11:47:44 -0400281 copts.SetSelectValue(axis, config, archVariantCopts)
282 asFlags.SetSelectValue(axis, config, archVariantAsflags)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400283 conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
284 cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
Chris Parsons2c788392021-08-10 11:58:07 -0400285 rtti.SetSelectValue(axis, config, baseCompilerProps.Rtti)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400286 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000287 }
288 }
289
Liz Kammer74deed42021-06-02 13:02:03 -0400290 srcs.ResolveExcludes()
Liz Kammer35687bc2021-09-10 10:07:07 -0400291 absoluteIncludes.DeduplicateAxesFromBase()
292 localIncludes.DeduplicateAxesFromBase()
Jingwen Chenc1c26502021-04-05 10:35:13 +0000293
Liz Kammerba7a9c52021-05-26 08:45:30 -0400294 productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
295 "Cflags": &copts,
296 "Asflags": &asFlags,
297 "CppFlags": &cppFlags,
298 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400299 productVariableProps := android.ProductVariableProperties(ctx)
Liz Kammerba7a9c52021-05-26 08:45:30 -0400300 for propName, attr := range productVarPropNameToAttribute {
301 if props, exists := productVariableProps[propName]; exists {
302 for _, prop := range props {
303 flags, ok := prop.Property.([]string)
304 if !ok {
305 ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
306 }
307 newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
Liz Kammer47535c52021-06-02 16:02:22 -0400308 attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400309 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400310 }
311 }
312
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000313 srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
314
Jingwen Chen107c0de2021-04-09 10:43:12 +0000315 return compilerAttributes{
Liz Kammer35687bc2021-09-10 10:07:07 -0400316 copts: copts,
317 srcs: srcs,
318 asFlags: asFlags,
319 asSrcs: asSrcs,
320 cSrcs: cSrcs,
321 conlyFlags: conlyFlags,
322 cppFlags: cppFlags,
323 rtti: rtti,
324 localIncludes: localIncludes,
325 absoluteIncludes: absoluteIncludes,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000326 }
327}
328
329// Convenience struct to hold all attributes parsed from linker properties.
330type linkerAttributes struct {
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000331 deps bazel.LabelListAttribute
332 dynamicDeps bazel.LabelListAttribute
Chris Parsons51f8c392021-08-03 21:01:05 -0400333 systemDynamicDeps bazel.LabelListAttribute
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000334 wholeArchiveDeps bazel.LabelListAttribute
335 exportedDeps bazel.LabelListAttribute
336 useLibcrt bazel.BoolAttribute
337 linkopts bazel.StringListAttribute
338 versionScript bazel.LabelAttribute
339 stripKeepSymbols bazel.BoolAttribute
340 stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
341 stripKeepSymbolsList bazel.StringListAttribute
342 stripAll bazel.BoolAttribute
343 stripNone bazel.BoolAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000344}
345
Rupert Shuttleworth143be942021-05-09 23:55:51 -0400346// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
347func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
348 flags := linkerProperties.Ldflags
349 if !BoolDefault(linkerProperties.Pack_relocations, true) {
350 flags = append(flags, "-Wl,--pack-dyn-relocs=none")
351 }
352 return flags
353}
354
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200355// bp2BuildParseLinkerProps parses the linker properties of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400356// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000357func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Liz Kammer47535c52021-06-02 16:02:22 -0400358 var headerDeps bazel.LabelListAttribute
359 var staticDeps bazel.LabelListAttribute
Chris Parsonsd6358772021-05-18 18:35:24 -0400360 var exportedDeps bazel.LabelListAttribute
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400361 var dynamicDeps bazel.LabelListAttribute
Chris Parsons08648312021-05-06 16:23:19 -0400362 var wholeArchiveDeps bazel.LabelListAttribute
Liz Kammer135bf552021-08-11 10:46:06 -0400363 systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
Jingwen Chen63930982021-03-24 10:04:33 -0400364 var linkopts bazel.StringListAttribute
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200365 var versionScript bazel.LabelAttribute
Liz Kammerd366c902021-06-03 13:43:01 -0400366 var useLibcrt bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400367
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000368 var stripKeepSymbols bazel.BoolAttribute
369 var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
370 var stripKeepSymbolsList bazel.StringListAttribute
371 var stripAll bazel.BoolAttribute
372 var stripNone bazel.BoolAttribute
373
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000374 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
375 for config, props := range configToProps {
376 if stripProperties, ok := props.(*StripProperties); ok {
377 stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
378 stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
379 stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
380 stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
381 stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
382 }
383 }
384 }
385
Liz Kammer9abd62d2021-05-21 08:37:59 -0400386 for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
387 for config, props := range configToProps {
388 if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
Liz Kammer135bf552021-08-11 10:46:06 -0400389 // Excludes to parallel Soong:
390 // 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 -0400391 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
Chris Parsons953b3562021-09-20 15:14:39 -0400392 staticDeps.SetSelectValue(axis, config, bazelLabelForStaticDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
Liz Kammer47535c52021-06-02 16:02:22 -0400393 wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
Chris Parsons953b3562021-09-20 15:14:39 -0400394 wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400395
Liz Kammer135bf552021-08-11 10:46:06 -0400396 systemSharedLibs := baseLinkerProps.System_shared_libs
397 // systemSharedLibs distinguishes between nil/empty list behavior:
398 // nil -> use default values
399 // empty list -> no values specified
400 if len(systemSharedLibs) > 0 {
401 systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
Chris Parsons51f8c392021-08-03 21:01:05 -0400402 }
Chris Parsons953b3562021-09-20 15:14:39 -0400403 systemSharedDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400404
405 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
Chris Parsons953b3562021-09-20 15:14:39 -0400406 dynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400407
Liz Kammer47535c52021-06-02 16:02:22 -0400408 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
Chris Parsons953b3562021-09-20 15:14:39 -0400409 headerDeps.SetSelectValue(axis, config, bazelLabelForHeaderDeps(ctx, headerLibs))
Liz Kammer47535c52021-06-02 16:02:22 -0400410 exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
Chris Parsons953b3562021-09-20 15:14:39 -0400411 exportedDeps.SetSelectValue(axis, config, bazelLabelForHeaderDeps(ctx, exportedLibs))
Liz Kammer47535c52021-06-02 16:02:22 -0400412
413 linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400414 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400415 versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400416 }
Liz Kammerd366c902021-06-03 13:43:01 -0400417 useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400418 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400419 }
420 }
421
Liz Kammer47535c52021-06-02 16:02:22 -0400422 type productVarDep struct {
423 // the name of the corresponding excludes field, if one exists
424 excludesField string
425 // reference to the bazel attribute that should be set for the given product variable config
426 attribute *bazel.LabelListAttribute
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400427
Chris Parsons953b3562021-09-20 15:14:39 -0400428 depResolutionFunc func(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList
Liz Kammer47535c52021-06-02 16:02:22 -0400429 }
430
431 productVarToDepFields := map[string]productVarDep{
432 // product variables do not support exclude_shared_libs
Chris Parsons953b3562021-09-20 15:14:39 -0400433 "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
434 "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, bazelLabelForStaticDepsExcludes},
435 "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
Liz Kammer47535c52021-06-02 16:02:22 -0400436 }
437
438 productVariableProps := android.ProductVariableProperties(ctx)
439 for name, dep := range productVarToDepFields {
440 props, exists := productVariableProps[name]
441 excludeProps, excludesExists := productVariableProps[dep.excludesField]
442 // if neither an include or excludes property exists, then skip it
443 if !exists && !excludesExists {
444 continue
445 }
446 // collect all the configurations that an include or exclude property exists for.
447 // we want to iterate all configurations rather than either the include or exclude because for a
448 // particular configuration we may have only and include or only an exclude to handle
449 configs := make(map[string]bool, len(props)+len(excludeProps))
450 for config := range props {
451 configs[config] = true
452 }
453 for config := range excludeProps {
454 configs[config] = true
455 }
456
457 for config := range configs {
458 prop, includesExists := props[config]
459 excludesProp, excludesExists := excludeProps[config]
460 var includes, excludes []string
461 var ok bool
462 // if there was no includes/excludes property, casting fails and that's expected
463 if includes, ok = prop.Property.([]string); includesExists && !ok {
464 ctx.ModuleErrorf("Could not convert product variable %s property", name)
465 }
466 if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
467 ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
468 }
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400469
470 dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
Liz Kammer47535c52021-06-02 16:02:22 -0400471 }
472 }
473
474 staticDeps.ResolveExcludes()
475 dynamicDeps.ResolveExcludes()
476 wholeArchiveDeps.ResolveExcludes()
477
478 headerDeps.Append(staticDeps)
479
Jingwen Chen107c0de2021-04-09 10:43:12 +0000480 return linkerAttributes{
Chris Parsons51f8c392021-08-03 21:01:05 -0400481 deps: headerDeps,
482 exportedDeps: exportedDeps,
483 dynamicDeps: dynamicDeps,
484 systemDynamicDeps: systemSharedDeps,
485 wholeArchiveDeps: wholeArchiveDeps,
486 linkopts: linkopts,
487 useLibcrt: useLibcrt,
488 versionScript: versionScript,
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000489
490 // Strip properties
491 stripKeepSymbols: stripKeepSymbols,
492 stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
493 stripKeepSymbolsList: stripKeepSymbolsList,
494 stripAll: stripAll,
495 stripNone: stripNone,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000496 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400497}
498
Jingwen Chened9c17d2021-04-13 07:14:55 +0000499// Relativize a list of root-relative paths with respect to the module's
500// directory.
501//
502// include_dirs Soong prop are root-relative (b/183742505), but
503// local_include_dirs, export_include_dirs and export_system_include_dirs are
504// module dir relative. This function makes a list of paths entirely module dir
505// relative.
506//
507// For the `include` attribute, Bazel wants the paths to be relative to the
508// module.
509func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000510 var relativePaths []string
511 for _, path := range paths {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000512 // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
513 relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
514 if err != nil {
515 panic(err)
516 }
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000517 relativePaths = append(relativePaths, relativePath)
518 }
519 return relativePaths
520}
521
Liz Kammer5fad5012021-09-09 14:08:21 -0400522// BazelIncludes contains information about -I and -isystem paths from a module converted to Bazel
523// attributes.
524type BazelIncludes struct {
525 Includes bazel.StringListAttribute
526 SystemIncludes bazel.StringListAttribute
527}
528
529func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) BazelIncludes {
Jingwen Chen91220d72021-03-24 02:18:33 -0400530 libraryDecorator := module.linker.(*libraryDecorator)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400531 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
532}
Jingwen Chen91220d72021-03-24 02:18:33 -0400533
Liz Kammer5fad5012021-09-09 14:08:21 -0400534// Bp2buildParseExportedIncludesForPrebuiltLibrary returns a BazelIncludes with Bazel-ified values
535// to export includes from the underlying module's properties.
536func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) BazelIncludes {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400537 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
538 libraryDecorator := prebuiltLibraryLinker.libraryDecorator
539 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
540}
541
542// bp2BuildParseExportedIncludes creates a string list attribute contains the
543// exported included directories of a module.
Liz Kammer5fad5012021-09-09 14:08:21 -0400544func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) BazelIncludes {
545 exported := BazelIncludes{}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400546 for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
547 for config, props := range configToProps {
548 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
Liz Kammer5fad5012021-09-09 14:08:21 -0400549 if len(flagExporterProperties.Export_include_dirs) > 0 {
550 exported.Includes.SetSelectValue(axis, config, flagExporterProperties.Export_include_dirs)
551 }
552 if len(flagExporterProperties.Export_system_include_dirs) > 0 {
553 exported.SystemIncludes.SetSelectValue(axis, config, flagExporterProperties.Export_system_include_dirs)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400554 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400555 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400556 }
557 }
Liz Kammer5fad5012021-09-09 14:08:21 -0400558 exported.Includes.DeduplicateAxesFromBase()
559 exported.SystemIncludes.DeduplicateAxesFromBase()
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400560
Liz Kammer5fad5012021-09-09 14:08:21 -0400561 return exported
Jingwen Chen91220d72021-03-24 02:18:33 -0400562}
Chris Parsons953b3562021-09-20 15:14:39 -0400563
564func bazelLabelForStaticModule(ctx android.TopDownMutatorContext, m blueprint.Module) string {
565 label := android.BazelModuleLabel(ctx, m)
566 if aModule, ok := m.(android.Module); ok {
567 if ctx.OtherModuleType(aModule) == "cc_library" && !android.GenerateCcLibraryStaticOnly(m.Name()) {
568 label += "_bp2build_cc_library_static"
569 }
570 }
571 return label
572}
573
574func bazelLabelForSharedModule(ctx android.TopDownMutatorContext, m blueprint.Module) string {
575 // cc_library, at it's root name, propagates the shared library, which depends on the static
576 // library.
577 return android.BazelModuleLabel(ctx, m)
578}
579
580func bazelLabelForStaticWholeModuleDeps(ctx android.TopDownMutatorContext, m blueprint.Module) string {
581 label := bazelLabelForStaticModule(ctx, m)
582 if aModule, ok := m.(android.Module); ok {
583 if android.IsModulePrebuilt(aModule) {
584 label += "_alwayslink"
585 }
586 }
587 return label
588}
589
590func bazelLabelForWholeDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList {
591 return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps)
592}
593
594func bazelLabelForWholeDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList {
595 return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticWholeModuleDeps)
596}
597
598func bazelLabelForStaticDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList {
599 return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticModule)
600}
601
602func bazelLabelForStaticDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList {
603 return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule)
604}
605
606func bazelLabelForSharedDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList {
607 return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule)
608}
609
610func bazelLabelForHeaderDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList {
611 // This is not elegant, but bp2build's shared library targets only propagate
612 // their header information as part of the normal C++ provider.
613 return bazelLabelForSharedDeps(ctx, modules)
614}
615
616func bazelLabelForSharedDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList {
617 return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
618}