1// 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 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) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 68 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "cc_prebuilt_binary") 69} 70 71func (mt *binarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 72 return &nativeBinaryInfoProperties{} 73} 74 75const ( 76 nativeBinaryDir = "bin" 77) 78 79// path to the native binary. Relative to <sdk_root>/<api_dir> 80func nativeBinaryPathFor(lib nativeBinaryInfoProperties) string { 81 return filepath.Join(lib.OsPrefix(), lib.archType, 82 nativeBinaryDir, lib.outputFile.Base()) 83} 84 85// nativeBinaryInfoProperties represents properties of a native binary 86// 87// The exported (capitalized) fields will be examined and may be changed during common value extraction. 88// The unexported fields will be left untouched. 89type nativeBinaryInfoProperties struct { 90 android.SdkMemberPropertiesBase 91 92 // archType is not exported as if set (to a non default value) it is always arch specific. 93 // This is "" for common properties. 94 archType string 95 96 // outputFile is not exported as it is always arch specific. 97 outputFile android.Path 98 99 // The set of shared libraries 100 // 101 // This field is exported as its contents may not be arch specific. 102 SharedLibs []string 103 104 // The set of system shared libraries 105 // 106 // This field is exported as its contents may not be arch specific. 107 SystemSharedLibs []string 108} 109 110func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 111 ccModule := variant.(*Module) 112 113 p.archType = ccModule.Target().Arch.ArchType.String() 114 p.outputFile = getRequiredMemberOutputFile(ctx, ccModule) 115 116 if ccModule.linker != nil { 117 specifiedDeps := specifiedDeps{} 118 specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps) 119 120 p.SharedLibs = specifiedDeps.sharedLibs 121 p.SystemSharedLibs = specifiedDeps.systemSharedLibs 122 } 123} 124 125func (p *nativeBinaryInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 126 if p.Compile_multilib != "" { 127 propertySet.AddProperty("compile_multilib", p.Compile_multilib) 128 } 129 130 builder := ctx.SnapshotBuilder() 131 if p.outputFile != nil { 132 propertySet.AddProperty("srcs", []string{nativeBinaryPathFor(*p)}) 133 134 builder.CopyToSnapshot(p.outputFile, nativeBinaryPathFor(*p)) 135 } 136 137 if len(p.SharedLibs) > 0 { 138 propertySet.AddPropertyWithTag("shared_libs", p.SharedLibs, builder.SdkMemberReferencePropertyTag(false)) 139 } 140 141 // SystemSharedLibs needs to be propagated if it's a list, even if it's empty, 142 // so check for non-nil instead of nonzero length. 143 if p.SystemSharedLibs != nil { 144 propertySet.AddPropertyWithTag("system_shared_libs", p.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false)) 145 } 146} 147