blob: 1b38a754bdfcc8ba3e6667c59a245a805d7784fb [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 Kammer7a210ac2021-09-22 15:52:58 -040023
Chris Parsons953b3562021-09-20 15:14:39 -040024 "github.com/google/blueprint"
Liz Kammerba7a9c52021-05-26 08:45:30 -040025
26 "github.com/google/blueprint/proptools"
Jingwen Chen91220d72021-03-24 02:18:33 -040027)
28
Liz Kammer2222c6b2021-05-24 15:41:47 -040029// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
Jingwen Chenbcf53042021-05-26 04:42:42 +000030// properties which apply to either the shared or static version of a cc_library module.
Liz Kammer2222c6b2021-05-24 15:41:47 -040031type staticOrSharedAttributes struct {
Jingwen Chenc4dc9b42021-06-11 12:51:48 +000032 Srcs bazel.LabelListAttribute
33 Srcs_c bazel.LabelListAttribute
34 Srcs_as bazel.LabelListAttribute
35 Copts bazel.StringListAttribute
Jingwen Chen14a8bda2021-06-02 11:10:02 +000036
Liz Kammer7a210ac2021-09-22 15:52:58 -040037 Deps bazel.LabelListAttribute
38 Implementation_deps bazel.LabelListAttribute
39 Dynamic_deps bazel.LabelListAttribute
40 Implementation_dynamic_deps bazel.LabelListAttribute
41 Whole_archive_deps bazel.LabelListAttribute
Chris Parsons51f8c392021-08-03 21:01:05 -040042
43 System_dynamic_deps bazel.LabelListAttribute
Jingwen Chen53681ef2021-04-29 08:15:13 +000044}
45
Jingwen Chen14a8bda2021-06-02 11:10:02 +000046func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) {
47 // Branch srcs into three language-specific groups.
48 // C++ is the "catch-all" group, and comprises generated sources because we don't
49 // know the language of these sources until the genrule is executed.
50 // TODO(b/190006308): Handle language detection of sources in a Bazel rule.
51 isCSrcOrFilegroup := func(s string) bool {
52 return strings.HasSuffix(s, ".c") || strings.HasSuffix(s, "_c_srcs")
53 }
54
55 isAsmSrcOrFilegroup := func(s string) bool {
56 return strings.HasSuffix(s, ".S") || strings.HasSuffix(s, ".s") || strings.HasSuffix(s, "_as_srcs")
57 }
58
59 // Check that a module is a filegroup type named <label>.
60 isFilegroupNamed := func(m android.Module, fullLabel string) bool {
61 if ctx.OtherModuleType(m) != "filegroup" {
62 return false
63 }
64 labelParts := strings.Split(fullLabel, ":")
65 if len(labelParts) > 2 {
66 // There should not be more than one colon in a label.
67 panic(fmt.Errorf("%s is not a valid Bazel label for a filegroup", fullLabel))
68 } else {
69 return m.Name() == labelParts[len(labelParts)-1]
70 }
71 }
72
73 // Convert the filegroup dependencies into the extension-specific filegroups
74 // filtered in the filegroup.bzl macro.
75 cppFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040076 m, exists := ctx.ModuleFromName(label)
77 if exists {
78 aModule, _ := m.(android.Module)
79 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000080 label = label + "_cpp_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000081 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040082 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000083 return label
84 }
85 cFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040086 m, exists := ctx.ModuleFromName(label)
87 if exists {
88 aModule, _ := m.(android.Module)
89 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +000090 label = label + "_c_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +000091 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -040092 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +000093 return label
94 }
95 asFilegroup := func(label string) string {
Chris Parsons5a34ffb2021-07-21 14:34:58 -040096 m, exists := ctx.ModuleFromName(label)
97 if exists {
98 aModule, _ := m.(android.Module)
99 if isFilegroupNamed(aModule, label) {
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000100 label = label + "_as_srcs"
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000101 }
Chris Parsons5a34ffb2021-07-21 14:34:58 -0400102 }
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000103 return label
104 }
105
106 cSrcs = bazel.MapLabelListAttribute(srcs, cFilegroup)
107 cSrcs = bazel.FilterLabelListAttribute(cSrcs, isCSrcOrFilegroup)
108
109 asSrcs = bazel.MapLabelListAttribute(srcs, asFilegroup)
110 asSrcs = bazel.FilterLabelListAttribute(asSrcs, isAsmSrcOrFilegroup)
111
112 cppSrcs = bazel.MapLabelListAttribute(srcs, cppFilegroup)
113 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, cSrcs)
114 cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, asSrcs)
115 return
116}
117
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000118// bp2BuildParseLibProps returns the attributes for a variant of a cc_library.
119func bp2BuildParseLibProps(ctx android.TopDownMutatorContext, module *Module, isStatic bool) staticOrSharedAttributes {
Jingwen Chen53681ef2021-04-29 08:15:13 +0000120 lib, ok := module.compiler.(*libraryDecorator)
121 if !ok {
Liz Kammer2222c6b2021-05-24 15:41:47 -0400122 return staticOrSharedAttributes{}
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 return bp2buildParseStaticOrSharedProps(ctx, module, lib, isStatic)
125}
Jingwen Chen53681ef2021-04-29 08:15:13 +0000126
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000127// bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
128func bp2BuildParseSharedProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
129 return bp2BuildParseLibProps(ctx, module, false)
Jingwen Chen53681ef2021-04-29 08:15:13 +0000130}
131
132// bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
Liz Kammer2222c6b2021-05-24 15:41:47 -0400133func bp2BuildParseStaticProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes {
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000134 return bp2BuildParseLibProps(ctx, module, true)
Liz Kammer2222c6b2021-05-24 15:41:47 -0400135}
136
Liz Kammer7a210ac2021-09-22 15:52:58 -0400137type depsPartition struct {
138 export bazel.LabelList
139 implementation bazel.LabelList
140}
141
142type bazelLabelForDepsFn func(android.TopDownMutatorContext, []string) bazel.LabelList
143
144func partitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
145 implementation, export := android.FilterList(allDeps, exportedDeps)
146
147 return depsPartition{
148 export: fn(ctx, export),
149 implementation: fn(ctx, implementation),
150 }
151}
152
153type bazelLabelForDepsExcludesFn func(android.TopDownMutatorContext, []string, []string) bazel.LabelList
154
155func partitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
156 implementation, export := android.FilterList(allDeps, exportedDeps)
157
158 return depsPartition{
159 export: fn(ctx, export, excludes),
160 implementation: fn(ctx, implementation, excludes),
161 }
162}
163
Jingwen Chenbcf53042021-05-26 04:42:42 +0000164func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
Liz Kammer135bf552021-08-11 10:46:06 -0400165 attrs := staticOrSharedAttributes{}
Jingwen Chenbcf53042021-05-26 04:42:42 +0000166
Liz Kammer9abd62d2021-05-21 08:37:59 -0400167 setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000168 attrs.Copts.SetSelectValue(axis, config, props.Cflags)
169 attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
Chris Parsons953b3562021-09-20 15:14:39 -0400170 attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs))
Liz Kammer7a210ac2021-09-22 15:52:58 -0400171
172 staticDeps := partitionExportedAndImplementationsDeps(ctx, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps)
173 attrs.Deps.SetSelectValue(axis, config, staticDeps.export)
174 attrs.Implementation_deps.SetSelectValue(axis, config, staticDeps.implementation)
175
176 sharedDeps := partitionExportedAndImplementationsDeps(ctx, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps)
177 attrs.Dynamic_deps.SetSelectValue(axis, config, sharedDeps.export)
178 attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation)
179
180 attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs))
Jingwen Chenbcf53042021-05-26 04:42:42 +0000181 }
Liz Kammer135bf552021-08-11 10:46:06 -0400182 // system_dynamic_deps distinguishes between nil/empty list behavior:
183 // nil -> use default values
184 // empty list -> no values specified
185 attrs.System_dynamic_deps.ForceSpecifyEmptyList = true
Jingwen Chenbcf53042021-05-26 04:42:42 +0000186
187 if isStatic {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400188 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StaticProperties{}) {
189 for config, props := range configToProps {
190 if staticOrSharedProps, ok := props.(*StaticProperties); ok {
191 setAttrs(axis, config, staticOrSharedProps.Static)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000192 }
193 }
194 }
195 } else {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400196 for axis, configToProps := range module.GetArchVariantProperties(ctx, &SharedProperties{}) {
197 for config, props := range configToProps {
198 if staticOrSharedProps, ok := props.(*SharedProperties); ok {
199 setAttrs(axis, config, staticOrSharedProps.Shared)
Jingwen Chenbcf53042021-05-26 04:42:42 +0000200 }
201 }
202 }
203 }
204
Jingwen Chenc4dc9b42021-06-11 12:51:48 +0000205 cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.Srcs)
206 attrs.Srcs = cppSrcs
207 attrs.Srcs_c = cSrcs
208 attrs.Srcs_as = asSrcs
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000209
Jingwen Chenbcf53042021-05-26 04:42:42 +0000210 return attrs
Jingwen Chen53681ef2021-04-29 08:15:13 +0000211}
212
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400213// Convenience struct to hold all attributes parsed from prebuilt properties.
214type prebuiltAttributes struct {
215 Src bazel.LabelAttribute
216}
217
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxac5097f2021-09-01 21:22:09 +0000218// NOTE: Used outside of Soong repo project, in the clangprebuilts.go bootstrap_go_package
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400219func Bp2BuildParsePrebuiltLibraryProps(ctx android.TopDownMutatorContext, module *Module) prebuiltAttributes {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400220 var srcLabelAttribute bazel.LabelAttribute
221
Liz Kammer9abd62d2021-05-21 08:37:59 -0400222 for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
223 for config, props := range configToProps {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400224 if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
225 if len(prebuiltLinkerProperties.Srcs) > 1 {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400226 ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
227 continue
228 } else if len(prebuiltLinkerProperties.Srcs) == 0 {
229 continue
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400230 }
Liz Kammer9abd62d2021-05-21 08:37:59 -0400231 src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])
232 srcLabelAttribute.SetSelectValue(axis, config, src)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400233 }
234 }
235 }
236
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400237 return prebuiltAttributes{
238 Src: srcLabelAttribute,
239 }
240}
241
Jingwen Chen107c0de2021-04-09 10:43:12 +0000242// Convenience struct to hold all attributes parsed from compiler properties.
243type compilerAttributes struct {
Chris Parsons990c4f42021-05-25 12:10:58 -0400244 // Options for all languages
245 copts bazel.StringListAttribute
246 // Assembly options and sources
247 asFlags bazel.StringListAttribute
248 asSrcs bazel.LabelListAttribute
249 // C options and sources
250 conlyFlags bazel.StringListAttribute
251 cSrcs bazel.LabelListAttribute
252 // C++ options and sources
253 cppFlags bazel.StringListAttribute
Jingwen Chened9c17d2021-04-13 07:14:55 +0000254 srcs bazel.LabelListAttribute
Chris Parsons2c788392021-08-10 11:58:07 -0400255
256 rtti bazel.BoolAttribute
Liz Kammer35687bc2021-09-10 10:07:07 -0400257
258 localIncludes bazel.StringListAttribute
259 absoluteIncludes bazel.StringListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000260}
261
Jingwen Chen63930982021-03-24 10:04:33 -0400262// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000263func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Module) compilerAttributes {
Jingwen Chen882bcc12021-04-27 05:54:20 +0000264 var srcs bazel.LabelListAttribute
Jingwen Chen107c0de2021-04-09 10:43:12 +0000265 var copts bazel.StringListAttribute
Chris Parsons990c4f42021-05-25 12:10:58 -0400266 var asFlags bazel.StringListAttribute
267 var conlyFlags bazel.StringListAttribute
268 var cppFlags bazel.StringListAttribute
Chris Parsons2c788392021-08-10 11:58:07 -0400269 var rtti bazel.BoolAttribute
Liz Kammer35687bc2021-09-10 10:07:07 -0400270 var localIncludes bazel.StringListAttribute
271 var absoluteIncludes bazel.StringListAttribute
Jingwen Chened9c17d2021-04-13 07:14:55 +0000272
Chris Parsons990c4f42021-05-25 12:10:58 -0400273 parseCommandLineFlags := func(soongFlags []string) []string {
274 var result []string
275 for _, flag := range soongFlags {
Colin Cross52aa4e12021-05-25 15:20:39 +0000276 // Soong's cflags can contain spaces, like `-include header.h`. For
277 // Bazel's copts, split them up to be compatible with the
278 // no_copts_tokenization feature.
Chris Parsons990c4f42021-05-25 12:10:58 -0400279 result = append(result, strings.Split(flag, " ")...)
Colin Cross52aa4e12021-05-25 15:20:39 +0000280 }
Chris Parsons990c4f42021-05-25 12:10:58 -0400281 return result
282 }
283
Liz Kammer74deed42021-06-02 13:02:03 -0400284 // Parse srcs from an arch or OS's props value.
Jingwen Chene32e9e02021-04-23 09:17:24 +0000285 parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList {
Chris Parsons484e50a2021-05-13 15:13:04 -0400286 // Add srcs-like dependencies such as generated files.
287 // First create a LabelList containing these dependencies, then merge the values with srcs.
288 generatedHdrsAndSrcs := baseCompilerProps.Generated_headers
289 generatedHdrsAndSrcs = append(generatedHdrsAndSrcs, baseCompilerProps.Generated_sources...)
Chris Parsons484e50a2021-05-13 15:13:04 -0400290 generatedHdrsAndSrcsLabelList := android.BazelLabelForModuleDeps(ctx, generatedHdrsAndSrcs)
291
Liz Kammer74deed42021-06-02 13:02:03 -0400292 allSrcsLabelList := android.BazelLabelForModuleSrcExcludes(ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
Chris Parsons484e50a2021-05-13 15:13:04 -0400293 return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedHdrsAndSrcsLabelList)
Jingwen Chene32e9e02021-04-23 09:17:24 +0000294 }
295
Liz Kammer9abd62d2021-05-21 08:37:59 -0400296 archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
Liz Kammer9abd62d2021-05-21 08:37:59 -0400297 for axis, configToProps := range archVariantCompilerProps {
298 for config, props := range configToProps {
299 if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
300 // If there's arch specific srcs or exclude_srcs, generate a select entry for it.
301 // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
302 if len(baseCompilerProps.Srcs) > 0 || len(baseCompilerProps.Exclude_srcs) > 0 {
303 srcsList := parseSrcs(baseCompilerProps)
304 srcs.SetSelectValue(axis, config, srcsList)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400305 }
306
Chris Parsons69fa9f92021-07-13 11:47:44 -0400307 archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags)
308 archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags)
Liz Kammer35687bc2021-09-10 10:07:07 -0400309
310 localIncludeDirs := baseCompilerProps.Local_include_dirs
311 if axis == bazel.NoConfigAxis && includeBuildDirectory(baseCompilerProps.Include_build_directory) {
312 localIncludeDirs = append(localIncludeDirs, ".")
Chris Parsons69fa9f92021-07-13 11:47:44 -0400313 }
314
Liz Kammer35687bc2021-09-10 10:07:07 -0400315 absoluteIncludes.SetSelectValue(axis, config, baseCompilerProps.Include_dirs)
316 localIncludes.SetSelectValue(axis, config, localIncludeDirs)
Liz Kammer135bf552021-08-11 10:46:06 -0400317
Chris Parsons69fa9f92021-07-13 11:47:44 -0400318 copts.SetSelectValue(axis, config, archVariantCopts)
319 asFlags.SetSelectValue(axis, config, archVariantAsflags)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400320 conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags))
321 cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags))
Chris Parsons2c788392021-08-10 11:58:07 -0400322 rtti.SetSelectValue(axis, config, baseCompilerProps.Rtti)
Liz Kammer9abd62d2021-05-21 08:37:59 -0400323 }
Jingwen Chenc1c26502021-04-05 10:35:13 +0000324 }
325 }
326
Liz Kammer74deed42021-06-02 13:02:03 -0400327 srcs.ResolveExcludes()
Liz Kammer35687bc2021-09-10 10:07:07 -0400328 absoluteIncludes.DeduplicateAxesFromBase()
329 localIncludes.DeduplicateAxesFromBase()
Jingwen Chenc1c26502021-04-05 10:35:13 +0000330
Liz Kammerba7a9c52021-05-26 08:45:30 -0400331 productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
332 "Cflags": &copts,
333 "Asflags": &asFlags,
334 "CppFlags": &cppFlags,
335 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400336 productVariableProps := android.ProductVariableProperties(ctx)
Liz Kammerba7a9c52021-05-26 08:45:30 -0400337 for propName, attr := range productVarPropNameToAttribute {
338 if props, exists := productVariableProps[propName]; exists {
339 for _, prop := range props {
340 flags, ok := prop.Property.([]string)
341 if !ok {
342 ctx.ModuleErrorf("Could not convert product variable %s property", proptools.PropertyNameForField(propName))
343 }
344 newFlags, _ := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable)
Liz Kammer47535c52021-06-02 16:02:22 -0400345 attr.SetSelectValue(bazel.ProductVariableConfigurationAxis(prop.FullConfig), prop.FullConfig, newFlags)
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400346 }
Liz Kammer6fd7b3f2021-05-06 13:54:29 -0400347 }
348 }
349
Jingwen Chen14a8bda2021-06-02 11:10:02 +0000350 srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs)
351
Jingwen Chen107c0de2021-04-09 10:43:12 +0000352 return compilerAttributes{
Liz Kammer35687bc2021-09-10 10:07:07 -0400353 copts: copts,
354 srcs: srcs,
355 asFlags: asFlags,
356 asSrcs: asSrcs,
357 cSrcs: cSrcs,
358 conlyFlags: conlyFlags,
359 cppFlags: cppFlags,
360 rtti: rtti,
361 localIncludes: localIncludes,
362 absoluteIncludes: absoluteIncludes,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000363 }
364}
365
366// Convenience struct to hold all attributes parsed from linker properties.
367type linkerAttributes struct {
Liz Kammer7a210ac2021-09-22 15:52:58 -0400368 deps bazel.LabelListAttribute
369 implementationDeps bazel.LabelListAttribute
370 dynamicDeps bazel.LabelListAttribute
371 implementationDynamicDeps bazel.LabelListAttribute
372 wholeArchiveDeps bazel.LabelListAttribute
373 systemDynamicDeps bazel.LabelListAttribute
374
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000375 useLibcrt bazel.BoolAttribute
376 linkopts bazel.StringListAttribute
377 versionScript bazel.LabelAttribute
378 stripKeepSymbols bazel.BoolAttribute
379 stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
380 stripKeepSymbolsList bazel.StringListAttribute
381 stripAll bazel.BoolAttribute
382 stripNone bazel.BoolAttribute
Jingwen Chenc1c26502021-04-05 10:35:13 +0000383}
384
Rupert Shuttleworth143be942021-05-09 23:55:51 -0400385// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
386func getBp2BuildLinkerFlags(linkerProperties *BaseLinkerProperties) []string {
387 flags := linkerProperties.Ldflags
388 if !BoolDefault(linkerProperties.Pack_relocations, true) {
389 flags = append(flags, "-Wl,--pack-dyn-relocs=none")
390 }
391 return flags
392}
393
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200394// bp2BuildParseLinkerProps parses the linker properties of a module, including
Jingwen Chen91220d72021-03-24 02:18:33 -0400395// configurable attribute values.
Jingwen Chen107c0de2021-04-09 10:43:12 +0000396func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
Liz Kammer7a210ac2021-09-22 15:52:58 -0400397
Liz Kammer47535c52021-06-02 16:02:22 -0400398 var headerDeps bazel.LabelListAttribute
Liz Kammer7a210ac2021-09-22 15:52:58 -0400399 var implementationHeaderDeps bazel.LabelListAttribute
400 var deps bazel.LabelListAttribute
401 var implementationDeps bazel.LabelListAttribute
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400402 var dynamicDeps bazel.LabelListAttribute
Liz Kammer7a210ac2021-09-22 15:52:58 -0400403 var implementationDynamicDeps bazel.LabelListAttribute
Chris Parsons08648312021-05-06 16:23:19 -0400404 var wholeArchiveDeps bazel.LabelListAttribute
Liz Kammer135bf552021-08-11 10:46:06 -0400405 systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
Liz Kammer7a210ac2021-09-22 15:52:58 -0400406
Jingwen Chen63930982021-03-24 10:04:33 -0400407 var linkopts bazel.StringListAttribute
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200408 var versionScript bazel.LabelAttribute
Liz Kammerd366c902021-06-03 13:43:01 -0400409 var useLibcrt bazel.BoolAttribute
Jingwen Chen63930982021-03-24 10:04:33 -0400410
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000411 var stripKeepSymbols bazel.BoolAttribute
412 var stripKeepSymbolsAndDebugFrame bazel.BoolAttribute
413 var stripKeepSymbolsList bazel.StringListAttribute
414 var stripAll bazel.BoolAttribute
415 var stripNone bazel.BoolAttribute
416
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000417 for axis, configToProps := range module.GetArchVariantProperties(ctx, &StripProperties{}) {
418 for config, props := range configToProps {
419 if stripProperties, ok := props.(*StripProperties); ok {
420 stripKeepSymbols.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols)
421 stripKeepSymbolsList.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_list)
422 stripKeepSymbolsAndDebugFrame.SetSelectValue(axis, config, stripProperties.Strip.Keep_symbols_and_debug_frame)
423 stripAll.SetSelectValue(axis, config, stripProperties.Strip.All)
424 stripNone.SetSelectValue(axis, config, stripProperties.Strip.None)
425 }
426 }
427 }
428
Liz Kammer9abd62d2021-05-21 08:37:59 -0400429 for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
430 for config, props := range configToProps {
431 if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
Liz Kammer7a210ac2021-09-22 15:52:58 -0400432
Liz Kammer135bf552021-08-11 10:46:06 -0400433 // Excludes to parallel Soong:
434 // 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 -0400435 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
Liz Kammer7a210ac2021-09-22 15:52:58 -0400436 staticDeps := partitionExportedAndImplementationsDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs, baseLinkerProps.Export_static_lib_headers, bazelLabelForStaticDepsExcludes)
437 deps.SetSelectValue(axis, config, staticDeps.export)
438 implementationDeps.SetSelectValue(axis, config, staticDeps.implementation)
439
440 wholeStaticLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
441 wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, baseLinkerProps.Exclude_static_libs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400442
Liz Kammer135bf552021-08-11 10:46:06 -0400443 systemSharedLibs := baseLinkerProps.System_shared_libs
444 // systemSharedLibs distinguishes between nil/empty list behavior:
445 // nil -> use default values
446 // empty list -> no values specified
447 if len(systemSharedLibs) > 0 {
448 systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
Chris Parsons51f8c392021-08-03 21:01:05 -0400449 }
Chris Parsons953b3562021-09-20 15:14:39 -0400450 systemSharedDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
Chris Parsons51f8c392021-08-03 21:01:05 -0400451
452 sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
Liz Kammer7a210ac2021-09-22 15:52:58 -0400453 sharedDeps := partitionExportedAndImplementationsDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs, baseLinkerProps.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes)
454 dynamicDeps.SetSelectValue(axis, config, sharedDeps.export)
455 implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400456
Liz Kammer47535c52021-06-02 16:02:22 -0400457 headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
Liz Kammer7a210ac2021-09-22 15:52:58 -0400458 hDeps := partitionExportedAndImplementationsDeps(ctx, headerLibs, baseLinkerProps.Export_header_lib_headers, bazelLabelForHeaderDeps)
459
460 headerDeps.SetSelectValue(axis, config, hDeps.export)
461 implementationHeaderDeps.SetSelectValue(axis, config, hDeps.implementation)
Liz Kammer47535c52021-06-02 16:02:22 -0400462
463 linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400464 if baseLinkerProps.Version_script != nil {
Liz Kammer9abd62d2021-05-21 08:37:59 -0400465 versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
Rupert Shuttleworth22cd2eb2021-05-27 02:15:54 -0400466 }
Liz Kammerd366c902021-06-03 13:43:01 -0400467 useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400468 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400469 }
470 }
471
Liz Kammer47535c52021-06-02 16:02:22 -0400472 type productVarDep struct {
473 // the name of the corresponding excludes field, if one exists
474 excludesField string
475 // reference to the bazel attribute that should be set for the given product variable config
476 attribute *bazel.LabelListAttribute
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400477
Chris Parsons953b3562021-09-20 15:14:39 -0400478 depResolutionFunc func(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList
Liz Kammer47535c52021-06-02 16:02:22 -0400479 }
480
481 productVarToDepFields := map[string]productVarDep{
482 // product variables do not support exclude_shared_libs
Liz Kammer7a210ac2021-09-22 15:52:58 -0400483 "Shared_libs": productVarDep{attribute: &implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
484 "Static_libs": productVarDep{"Exclude_static_libs", &implementationDeps, bazelLabelForStaticDepsExcludes},
Chris Parsons953b3562021-09-20 15:14:39 -0400485 "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
Liz Kammer47535c52021-06-02 16:02:22 -0400486 }
487
488 productVariableProps := android.ProductVariableProperties(ctx)
489 for name, dep := range productVarToDepFields {
490 props, exists := productVariableProps[name]
491 excludeProps, excludesExists := productVariableProps[dep.excludesField]
492 // if neither an include or excludes property exists, then skip it
493 if !exists && !excludesExists {
494 continue
495 }
496 // collect all the configurations that an include or exclude property exists for.
497 // we want to iterate all configurations rather than either the include or exclude because for a
498 // particular configuration we may have only and include or only an exclude to handle
499 configs := make(map[string]bool, len(props)+len(excludeProps))
500 for config := range props {
501 configs[config] = true
502 }
503 for config := range excludeProps {
504 configs[config] = true
505 }
506
507 for config := range configs {
508 prop, includesExists := props[config]
509 excludesProp, excludesExists := excludeProps[config]
510 var includes, excludes []string
511 var ok bool
512 // if there was no includes/excludes property, casting fails and that's expected
513 if includes, ok = prop.Property.([]string); includesExists && !ok {
514 ctx.ModuleErrorf("Could not convert product variable %s property", name)
515 }
516 if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok {
517 ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField)
518 }
Liz Kammer2d7bbe32021-06-10 18:20:06 -0400519
520 dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes))
Liz Kammer47535c52021-06-02 16:02:22 -0400521 }
522 }
523
Liz Kammer7a210ac2021-09-22 15:52:58 -0400524 headerDeps.Append(deps)
525 implementationHeaderDeps.Append(implementationDeps)
526
527 headerDeps.ResolveExcludes()
528 implementationHeaderDeps.ResolveExcludes()
Liz Kammer47535c52021-06-02 16:02:22 -0400529 dynamicDeps.ResolveExcludes()
Liz Kammer7a210ac2021-09-22 15:52:58 -0400530 implementationDynamicDeps.ResolveExcludes()
Liz Kammer47535c52021-06-02 16:02:22 -0400531 wholeArchiveDeps.ResolveExcludes()
532
Jingwen Chen107c0de2021-04-09 10:43:12 +0000533 return linkerAttributes{
Liz Kammer7a210ac2021-09-22 15:52:58 -0400534 deps: headerDeps,
535 implementationDeps: implementationHeaderDeps,
536 dynamicDeps: dynamicDeps,
537 implementationDynamicDeps: implementationDynamicDeps,
538 wholeArchiveDeps: wholeArchiveDeps,
539 systemDynamicDeps: systemSharedDeps,
540
541 linkopts: linkopts,
542 useLibcrt: useLibcrt,
543 versionScript: versionScript,
Jingwen Chen3d383bb2021-06-09 07:18:37 +0000544
545 // Strip properties
546 stripKeepSymbols: stripKeepSymbols,
547 stripKeepSymbolsAndDebugFrame: stripKeepSymbolsAndDebugFrame,
548 stripKeepSymbolsList: stripKeepSymbolsList,
549 stripAll: stripAll,
550 stripNone: stripNone,
Jingwen Chen107c0de2021-04-09 10:43:12 +0000551 }
Jingwen Chen91220d72021-03-24 02:18:33 -0400552}
553
Jingwen Chened9c17d2021-04-13 07:14:55 +0000554// Relativize a list of root-relative paths with respect to the module's
555// directory.
556//
557// include_dirs Soong prop are root-relative (b/183742505), but
558// local_include_dirs, export_include_dirs and export_system_include_dirs are
559// module dir relative. This function makes a list of paths entirely module dir
560// relative.
561//
562// For the `include` attribute, Bazel wants the paths to be relative to the
563// module.
564func bp2BuildMakePathsRelativeToModule(ctx android.BazelConversionPathContext, paths []string) []string {
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000565 var relativePaths []string
566 for _, path := range paths {
Jingwen Chened9c17d2021-04-13 07:14:55 +0000567 // Semantics of filepath.Rel: join(ModuleDir, rel(ModuleDir, path)) == path
568 relativePath, err := filepath.Rel(ctx.ModuleDir(), path)
569 if err != nil {
570 panic(err)
571 }
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000572 relativePaths = append(relativePaths, relativePath)
573 }
574 return relativePaths
575}
576
Liz Kammer5fad5012021-09-09 14:08:21 -0400577// BazelIncludes contains information about -I and -isystem paths from a module converted to Bazel
578// attributes.
579type BazelIncludes struct {
580 Includes bazel.StringListAttribute
581 SystemIncludes bazel.StringListAttribute
582}
583
584func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Module) BazelIncludes {
Jingwen Chen91220d72021-03-24 02:18:33 -0400585 libraryDecorator := module.linker.(*libraryDecorator)
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400586 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
587}
Jingwen Chen91220d72021-03-24 02:18:33 -0400588
Liz Kammer5fad5012021-09-09 14:08:21 -0400589// Bp2buildParseExportedIncludesForPrebuiltLibrary returns a BazelIncludes with Bazel-ified values
590// to export includes from the underlying module's properties.
591func Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx android.TopDownMutatorContext, module *Module) BazelIncludes {
Rupert Shuttleworthffd45822021-05-14 03:02:34 -0400592 prebuiltLibraryLinker := module.linker.(*prebuiltLibraryLinker)
593 libraryDecorator := prebuiltLibraryLinker.libraryDecorator
594 return bp2BuildParseExportedIncludesHelper(ctx, module, libraryDecorator)
595}
596
597// bp2BuildParseExportedIncludes creates a string list attribute contains the
598// exported included directories of a module.
Liz Kammer5fad5012021-09-09 14:08:21 -0400599func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, module *Module, libraryDecorator *libraryDecorator) BazelIncludes {
600 exported := BazelIncludes{}
Liz Kammer9abd62d2021-05-21 08:37:59 -0400601 for axis, configToProps := range module.GetArchVariantProperties(ctx, &FlagExporterProperties{}) {
602 for config, props := range configToProps {
603 if flagExporterProperties, ok := props.(*FlagExporterProperties); ok {
Liz Kammer5fad5012021-09-09 14:08:21 -0400604 if len(flagExporterProperties.Export_include_dirs) > 0 {
605 exported.Includes.SetSelectValue(axis, config, flagExporterProperties.Export_include_dirs)
606 }
607 if len(flagExporterProperties.Export_system_include_dirs) > 0 {
608 exported.SystemIncludes.SetSelectValue(axis, config, flagExporterProperties.Export_system_include_dirs)
Rupert Shuttleworthc194ffb2021-05-19 06:49:02 -0400609 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400610 }
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400611 }
612 }
Liz Kammer5fad5012021-09-09 14:08:21 -0400613 exported.Includes.DeduplicateAxesFromBase()
614 exported.SystemIncludes.DeduplicateAxesFromBase()
Rupert Shuttleworth375451e2021-04-26 07:49:08 -0400615
Liz Kammer5fad5012021-09-09 14:08:21 -0400616 return exported
Jingwen Chen91220d72021-03-24 02:18:33 -0400617}
Chris Parsons953b3562021-09-20 15:14:39 -0400618
619func bazelLabelForStaticModule(ctx android.TopDownMutatorContext, m blueprint.Module) string {
620 label := android.BazelModuleLabel(ctx, m)
621 if aModule, ok := m.(android.Module); ok {
622 if ctx.OtherModuleType(aModule) == "cc_library" && !android.GenerateCcLibraryStaticOnly(m.Name()) {
623 label += "_bp2build_cc_library_static"
624 }
625 }
626 return label
627}
628
629func bazelLabelForSharedModule(ctx android.TopDownMutatorContext, m blueprint.Module) string {
630 // cc_library, at it's root name, propagates the shared library, which depends on the static
631 // library.
632 return android.BazelModuleLabel(ctx, m)
633}
634
635func bazelLabelForStaticWholeModuleDeps(ctx android.TopDownMutatorContext, m blueprint.Module) string {
636 label := bazelLabelForStaticModule(ctx, m)
637 if aModule, ok := m.(android.Module); ok {
638 if android.IsModulePrebuilt(aModule) {
639 label += "_alwayslink"
640 }
641 }
642 return label
643}
644
645func bazelLabelForWholeDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList {
646 return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps)
647}
648
649func bazelLabelForWholeDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList {
650 return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticWholeModuleDeps)
651}
652
653func bazelLabelForStaticDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList {
654 return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticModule)
655}
656
657func bazelLabelForStaticDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList {
658 return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule)
659}
660
661func bazelLabelForSharedDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList {
662 return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule)
663}
664
665func bazelLabelForHeaderDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList {
666 // This is not elegant, but bp2build's shared library targets only propagate
667 // their header information as part of the normal C++ provider.
668 return bazelLabelForSharedDeps(ctx, modules)
669}
670
671func bazelLabelForSharedDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList {
672 return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
673}