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 "github.com/google/blueprint/proptools" 24) 25 26func init() { 27 android.RegisterSdkMemberType(ccBinarySdkMemberType) 28} 29 30var ccBinarySdkMemberType = &binarySdkMemberType{ 31 SdkMemberTypeBase: android.SdkMemberTypeBase{ 32 PropertyName: "native_binaries", 33 }, 34} 35 36type binarySdkMemberType struct { 37 android.SdkMemberTypeBase 38} 39 40func (mt *binarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { 41 targets := mctx.MultiTargets() 42 for _, lib := range names { 43 for _, target := range targets { 44 name, version := StubsLibNameAndVersion(lib) 45 if version == "" { 46 version = LatestStubsVersionFor(mctx.Config(), name) 47 } 48 mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{ 49 {Mutator: "version", Variation: version}, 50 }...), dependencyTag, name) 51 } 52 } 53} 54 55func (mt *binarySdkMemberType) IsInstance(module android.Module) bool { 56 // Check the module to see if it can be used with this module type. 57 if m, ok := module.(*Module); ok { 58 for _, allowableMemberType := range m.sdkMemberTypes { 59 if allowableMemberType == mt { 60 return true 61 } 62 } 63 } 64 65 return false 66} 67 68func (mt *binarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 69 pbm := ctx.SnapshotBuilder().AddPrebuiltModule(member, "cc_prebuilt_binary") 70 71 ccModule := member.Variants()[0].(*Module) 72 73 if stl := ccModule.stl.Properties.Stl; stl != nil { 74 pbm.AddProperty("stl", proptools.String(stl)) 75 } 76 77 return pbm 78} 79 80func (mt *binarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 81 return &nativeBinaryInfoProperties{} 82} 83 84const ( 85 nativeBinaryDir = "bin" 86) 87 88// path to the native binary. Relative to <sdk_root>/<api_dir> 89func nativeBinaryPathFor(lib nativeBinaryInfoProperties) string { 90 return filepath.Join(lib.OsPrefix(), lib.archType, 91 nativeBinaryDir, lib.outputFile.Base()) 92} 93 94// nativeBinaryInfoProperties represents properties of a native binary 95// 96// The exported (capitalized) fields will be examined and may be changed during common value extraction. 97// The unexported fields will be left untouched. 98type nativeBinaryInfoProperties struct { 99 android.SdkMemberPropertiesBase 100 101 // archType is not exported as if set (to a non default value) it is always arch specific. 102 // This is "" for common properties. 103 archType string 104 105 // outputFile is not exported as it is always arch specific. 106 outputFile android.Path 107 108 // The set of shared libraries 109 // 110 // This field is exported as its contents may not be arch specific. 111 SharedLibs []string 112 113 // The set of system shared libraries 114 // 115 // This field is exported as its contents may not be arch specific. 116 SystemSharedLibs []string 117 118 // Arch specific flags. 119 StaticExecutable bool 120 Nocrt bool 121} 122 123func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 124 ccModule := variant.(*Module) 125 126 p.archType = ccModule.Target().Arch.ArchType.String() 127 p.outputFile = getRequiredMemberOutputFile(ctx, ccModule) 128 129 binaryLinker := ccModule.linker.(*binaryDecorator) 130 p.StaticExecutable = binaryLinker.static() 131 p.Nocrt = Bool(binaryLinker.baseLinker.Properties.Nocrt) 132 133 if ccModule.linker != nil { 134 specifiedDeps := specifiedDeps{} 135 specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps) 136 137 p.SharedLibs = specifiedDeps.sharedLibs 138 p.SystemSharedLibs = specifiedDeps.systemSharedLibs 139 } 140} 141 142func (p *nativeBinaryInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 143 builder := ctx.SnapshotBuilder() 144 if p.outputFile != nil { 145 propertySet.AddProperty("srcs", []string{nativeBinaryPathFor(*p)}) 146 147 builder.CopyToSnapshot(p.outputFile, nativeBinaryPathFor(*p)) 148 } 149 150 if len(p.SharedLibs) > 0 { 151 propertySet.AddPropertyWithTag("shared_libs", p.SharedLibs, builder.SdkMemberReferencePropertyTag(false)) 152 } 153 154 // SystemSharedLibs needs to be propagated if it's a list, even if it's empty, 155 // so check for non-nil instead of nonzero length. 156 if p.SystemSharedLibs != nil { 157 propertySet.AddPropertyWithTag("system_shared_libs", p.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false)) 158 } 159 160 if p.StaticExecutable { 161 propertySet.AddProperty("static_executable", p.StaticExecutable) 162 } 163 if p.Nocrt { 164 propertySet.AddProperty("nocrt", p.Nocrt) 165 } 166} 167