1// Copyright 2017 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 "fmt" 19 20 "android/soong/android" 21 "android/soong/genrule" 22 "android/soong/snapshot" 23) 24 25func init() { 26 android.RegisterModuleType("cc_genrule", GenRuleFactory) 27} 28 29type GenruleExtraProperties struct { 30 Vendor_available *bool 31 Odm_available *bool 32 Product_available *bool 33 Ramdisk_available *bool 34 Vendor_ramdisk_available *bool 35 Recovery_available *bool 36 Sdk_version *string 37} 38 39// cc_genrule is a genrule that can depend on other cc_* objects. 40// The cmd may be run multiple times, once for each of the different arch/etc 41// variations. The following environment variables will be set when the command 42// execute: 43// 44// CC_ARCH the name of the architecture the command is being executed for 45// 46// CC_MULTILIB "lib32" if the architecture the command is being executed for is 32-bit, 47// "lib64" if it is 64-bit. 48// 49// CC_NATIVE_BRIDGE the name of the subdirectory that native bridge libraries are stored in if 50// the architecture has native bridge enabled, empty if it is disabled. 51func GenRuleFactory() android.Module { 52 module := genrule.NewGenRule() 53 54 extra := &GenruleExtraProperties{} 55 module.Extra = extra 56 module.ImageInterface = extra 57 module.CmdModifier = genruleCmdModifier 58 module.AddProperties(module.Extra) 59 60 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibBoth) 61 62 android.InitApexModule(module) 63 android.InitBazelModule(module) 64 65 return module 66} 67 68func genruleCmdModifier(ctx android.ModuleContext, cmd string) string { 69 target := ctx.Target() 70 arch := target.Arch.ArchType 71 return fmt.Sprintf("CC_ARCH=%s CC_NATIVE_BRIDGE=%s CC_MULTILIB=%s && %s", 72 arch.Name, target.NativeBridgeRelativePath, arch.Multilib, cmd) 73} 74 75var _ android.ImageInterface = (*GenruleExtraProperties)(nil) 76 77func (g *GenruleExtraProperties) ImageMutatorBegin(ctx android.BaseModuleContext) {} 78 79func (g *GenruleExtraProperties) CoreVariantNeeded(ctx android.BaseModuleContext) bool { 80 if ctx.DeviceConfig().VndkVersion() == "" { 81 return true 82 } 83 84 if ctx.DeviceConfig().ProductVndkVersion() != "" && ctx.ProductSpecific() { 85 return false 86 } 87 88 return !(ctx.SocSpecific() || ctx.DeviceSpecific()) 89} 90 91func (g *GenruleExtraProperties) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 92 return Bool(g.Ramdisk_available) 93} 94 95func (g *GenruleExtraProperties) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 96 return Bool(g.Vendor_ramdisk_available) 97} 98 99func (g *GenruleExtraProperties) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 100 return false 101} 102 103func (g *GenruleExtraProperties) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { 104 // If the build is using a snapshot, the recovery variant under AOSP directories 105 // is not needed. 106 recoverySnapshotVersion := ctx.DeviceConfig().RecoverySnapshotVersion() 107 if recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && 108 !snapshot.IsRecoveryProprietaryModule(ctx) { 109 return false 110 } else { 111 return Bool(g.Recovery_available) 112 } 113} 114 115func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.BaseModuleContext) []string { 116 if ctx.DeviceConfig().VndkVersion() == "" { 117 return nil 118 } 119 120 var variants []string 121 if Bool(g.Vendor_available) || Bool(g.Odm_available) || ctx.SocSpecific() || ctx.DeviceSpecific() { 122 vndkVersion := ctx.DeviceConfig().VndkVersion() 123 // If vndkVersion is current, we can always use PlatformVndkVersion. 124 // If not, we assume modules under proprietary paths are compatible for 125 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, that is 126 // PLATFORM_VNDK_VERSION. 127 if vndkVersion == "current" || !snapshot.IsVendorProprietaryModule(ctx) { 128 variants = append(variants, VendorVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion()) 129 } else { 130 variants = append(variants, VendorVariationPrefix+vndkVersion) 131 } 132 } 133 134 if ctx.DeviceConfig().ProductVndkVersion() == "" { 135 return variants 136 } 137 138 if Bool(g.Product_available) || ctx.ProductSpecific() { 139 variants = append(variants, ProductVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion()) 140 if vndkVersion := ctx.DeviceConfig().ProductVndkVersion(); vndkVersion != "current" { 141 variants = append(variants, ProductVariationPrefix+vndkVersion) 142 } 143 } 144 145 return variants 146} 147 148func (g *GenruleExtraProperties) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { 149} 150