blob: 58d6ad0adb45bfed95347c9b939ffa6a086e7163 [file] [log] [blame]
Paul Duffin25ce04b2020-01-16 11:47:25 +00001// Copyright 2020 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.
14
15package cc
16
17import (
18 "path/filepath"
Paul Duffin13ad94f2020-02-19 16:19:27 +000019 "strings"
Paul Duffin25ce04b2020-01-16 11:47:25 +000020
21 "android/soong/android"
22 "github.com/google/blueprint"
23)
24
25func init() {
26 android.RegisterSdkMemberType(ccBinarySdkMemberType)
27}
28
29var ccBinarySdkMemberType = &binarySdkMemberType{
30 SdkMemberTypeBase: android.SdkMemberTypeBase{
31 PropertyName: "native_binaries",
32 },
33}
34
35type binarySdkMemberType struct {
36 android.SdkMemberTypeBase
37}
38
39func (mt *binarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
40 targets := mctx.MultiTargets()
41 for _, lib := range names {
42 for _, target := range targets {
43 name, version := StubsLibNameAndVersion(lib)
44 if version == "" {
45 version = LatestStubsVersionFor(mctx.Config(), name)
46 }
47 mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
48 {Mutator: "version", Variation: version},
49 }...), dependencyTag, name)
50 }
51 }
52}
53
54func (mt *binarySdkMemberType) IsInstance(module android.Module) bool {
55 // Check the module to see if it can be used with this module type.
56 if m, ok := module.(*Module); ok {
57 for _, allowableMemberType := range m.sdkMemberTypes {
58 if allowableMemberType == mt {
59 return true
60 }
61 }
62 }
63
64 return false
65}
66
67func (mt *binarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
68 info := mt.organizeVariants(member)
69 buildSharedNativeBinarySnapshot(info, builder, member)
70}
71
72// Organize the variants by architecture.
73func (mt *binarySdkMemberType) organizeVariants(member android.SdkMember) *nativeBinaryInfo {
74 memberName := member.Name()
75 info := &nativeBinaryInfo{
76 name: memberName,
77 memberType: mt,
78 }
79
80 for _, variant := range member.Variants() {
81 ccModule := variant.(*Module)
82
83 info.archVariantProperties = append(info.archVariantProperties, nativeBinaryInfoProperties{
84 name: memberName,
85 archType: ccModule.Target().Arch.ArchType.String(),
86 outputFile: ccModule.OutputFile().Path(),
87 })
88 }
89
90 // Initialize the unexported properties that will not be set during the
91 // extraction process.
92 info.commonProperties.name = memberName
93
94 // Extract common properties from the arch specific properties.
95 extractCommonProperties(&info.commonProperties, info.archVariantProperties)
96
97 return info
98}
99
100func buildSharedNativeBinarySnapshot(info *nativeBinaryInfo, builder android.SnapshotBuilder, member android.SdkMember) {
101 pbm := builder.AddPrebuiltModule(member, "cc_prebuilt_binary")
Paul Duffin13ad94f2020-02-19 16:19:27 +0000102 archVariantCount := len(info.archVariantProperties)
103
104 // Choose setting for compile_multilib that is appropriate for the arch variants supplied.
105 var multilib string
106 if archVariantCount == 2 {
107 multilib = "both"
108 } else if archVariantCount == 1 {
109 if strings.HasSuffix(info.archVariantProperties[0].archType, "64") {
110 multilib = "64"
111 } else {
112 multilib = "32"
113 }
114 }
115 if multilib != "" {
116 pbm.AddProperty("compile_multilib", multilib)
117 }
118
Paul Duffin25ce04b2020-01-16 11:47:25 +0000119 archProperties := pbm.AddPropertySet("arch")
120 for _, av := range info.archVariantProperties {
121 archTypeProperties := archProperties.AddPropertySet(av.archType)
122 archTypeProperties.AddProperty("srcs", []string{nativeBinaryPathFor(av)})
123
124 builder.CopyToSnapshot(av.outputFile, nativeBinaryPathFor(av))
125 }
126}
127
128const (
129 nativeBinaryDir = "bin"
130)
131
132// path to the native binary. Relative to <sdk_root>/<api_dir>
133func nativeBinaryPathFor(lib nativeBinaryInfoProperties) string {
134 return filepath.Join(lib.archType,
135 nativeBinaryDir, lib.outputFile.Base())
136}
137
138// nativeBinaryInfoProperties represents properties of a native binary
139//
140// The exported (capitalized) fields will be examined and may be changed during common value extraction.
141// The unexported fields will be left untouched.
142type nativeBinaryInfoProperties struct {
143 // The name of the library, is not exported as this must not be changed during optimization.
144 name string
145
146 // archType is not exported as if set (to a non default value) it is always arch specific.
147 // This is "" for common properties.
148 archType string
149
150 // outputFile is not exported as it is always arch specific.
151 outputFile android.Path
152}
153
154// nativeBinaryInfo represents a collection of arch-specific modules having the same name
155type nativeBinaryInfo struct {
156 name string
157 memberType *binarySdkMemberType
158 archVariantProperties []nativeBinaryInfoProperties
159 commonProperties nativeBinaryInfoProperties
160}