|  | // Copyright 2020 Google Inc. All rights reserved. | 
|  | // | 
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | // you may not use this file except in compliance with the License. | 
|  | // You may obtain a copy of the License at | 
|  | // | 
|  | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | // | 
|  | // Unless required by applicable law or agreed to in writing, software | 
|  | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | // See the License for the specific language governing permissions and | 
|  | // limitations under the License. | 
|  |  | 
|  | package cc | 
|  |  | 
|  | import ( | 
|  | "path/filepath" | 
|  |  | 
|  | "android/soong/android" | 
|  |  | 
|  | "github.com/google/blueprint" | 
|  | "github.com/google/blueprint/proptools" | 
|  | ) | 
|  |  | 
|  | func init() { | 
|  | android.RegisterSdkMemberType(ccBinarySdkMemberType) | 
|  | } | 
|  |  | 
|  | var ccBinarySdkMemberType = &binarySdkMemberType{ | 
|  | SdkMemberTypeBase: android.SdkMemberTypeBase{ | 
|  | PropertyName:    "native_binaries", | 
|  | HostOsDependent: true, | 
|  | }, | 
|  | } | 
|  |  | 
|  | type binarySdkMemberType struct { | 
|  | android.SdkMemberTypeBase | 
|  | } | 
|  |  | 
|  | func (mt *binarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { | 
|  | targets := mctx.MultiTargets() | 
|  | for _, bin := range names { | 
|  | for _, target := range targets { | 
|  | variations := target.Variations() | 
|  | if mctx.Device() { | 
|  | variations = append(variations, | 
|  | blueprint.Variation{Mutator: "image", Variation: android.CoreVariation}) | 
|  | } | 
|  | mctx.AddFarVariationDependencies(variations, dependencyTag, bin) | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | func (mt *binarySdkMemberType) IsInstance(module android.Module) bool { | 
|  | // Check the module to see if it can be used with this module type. | 
|  | if m, ok := module.(*Module); ok { | 
|  | for _, allowableMemberType := range m.sdkMemberTypes { | 
|  | if allowableMemberType == mt { | 
|  | return true | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return false | 
|  | } | 
|  |  | 
|  | func (mt *binarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { | 
|  | pbm := ctx.SnapshotBuilder().AddPrebuiltModule(member, "cc_prebuilt_binary") | 
|  |  | 
|  | ccModule := member.Variants()[0].(*Module) | 
|  |  | 
|  | if stl := ccModule.stl.Properties.Stl; stl != nil { | 
|  | pbm.AddProperty("stl", proptools.String(stl)) | 
|  | } | 
|  |  | 
|  | return pbm | 
|  | } | 
|  |  | 
|  | func (mt *binarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { | 
|  | return &nativeBinaryInfoProperties{} | 
|  | } | 
|  |  | 
|  | const ( | 
|  | nativeBinaryDir = "bin" | 
|  | ) | 
|  |  | 
|  | // path to the native binary. Relative to <sdk_root>/<api_dir> | 
|  | func nativeBinaryPathFor(lib nativeBinaryInfoProperties) string { | 
|  | return filepath.Join(lib.OsPrefix(), lib.archType, | 
|  | nativeBinaryDir, lib.outputFile.Base()) | 
|  | } | 
|  |  | 
|  | // nativeBinaryInfoProperties represents properties of a native binary | 
|  | // | 
|  | // The exported (capitalized) fields will be examined and may be changed during common value extraction. | 
|  | // The unexported fields will be left untouched. | 
|  | type nativeBinaryInfoProperties struct { | 
|  | android.SdkMemberPropertiesBase | 
|  |  | 
|  | // archType is not exported as if set (to a non default value) it is always arch specific. | 
|  | // This is "" for common properties. | 
|  | archType string | 
|  |  | 
|  | // outputFile is not exported as it is always arch specific. | 
|  | outputFile android.Path | 
|  |  | 
|  | // The set of shared libraries | 
|  | // | 
|  | // This field is exported as its contents may not be arch specific. | 
|  | SharedLibs []string | 
|  |  | 
|  | // The set of system shared libraries | 
|  | // | 
|  | // This field is exported as its contents may not be arch specific. | 
|  | SystemSharedLibs []string | 
|  |  | 
|  | // Arch specific flags. | 
|  | StaticExecutable bool | 
|  | Nocrt            bool | 
|  | } | 
|  |  | 
|  | func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { | 
|  | ccModule := variant.(*Module) | 
|  |  | 
|  | p.archType = ccModule.Target().Arch.ArchType.String() | 
|  | p.outputFile = getRequiredMemberOutputFile(ctx, ccModule) | 
|  |  | 
|  | binaryLinker := ccModule.linker.(*binaryDecorator) | 
|  | p.StaticExecutable = binaryLinker.static() | 
|  | p.Nocrt = Bool(binaryLinker.baseLinker.Properties.Nocrt) | 
|  |  | 
|  | if ccModule.linker != nil { | 
|  | specifiedDeps := specifiedDeps{} | 
|  | specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps) | 
|  |  | 
|  | p.SharedLibs = specifiedDeps.sharedLibs | 
|  | p.SystemSharedLibs = specifiedDeps.systemSharedLibs | 
|  | } | 
|  | } | 
|  |  | 
|  | func (p *nativeBinaryInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { | 
|  | builder := ctx.SnapshotBuilder() | 
|  | if p.outputFile != nil { | 
|  | propertySet.AddProperty("srcs", []string{nativeBinaryPathFor(*p)}) | 
|  |  | 
|  | builder.CopyToSnapshot(p.outputFile, nativeBinaryPathFor(*p)) | 
|  | } | 
|  |  | 
|  | if len(p.SharedLibs) > 0 { | 
|  | propertySet.AddPropertyWithTag("shared_libs", p.SharedLibs, builder.SdkMemberReferencePropertyTag(false)) | 
|  | } | 
|  |  | 
|  | // SystemSharedLibs needs to be propagated if it's a list, even if it's empty, | 
|  | // so check for non-nil instead of nonzero length. | 
|  | if p.SystemSharedLibs != nil { | 
|  | propertySet.AddPropertyWithTag("system_shared_libs", p.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false)) | 
|  | } | 
|  |  | 
|  | if p.StaticExecutable { | 
|  | propertySet.AddProperty("static_executable", p.StaticExecutable) | 
|  | } | 
|  | if p.Nocrt { | 
|  | propertySet.AddProperty("nocrt", p.Nocrt) | 
|  | } | 
|  | } |