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