1 // Copyright 2016 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 15 package android 16 17 import ( 18 "fmt" 19 20 "github.com/google/blueprint" 21 "github.com/google/blueprint/proptools" 22 ) 23 24 // This file implements common functionality for handling modules that may exist as prebuilts, 25 // source, or both. 26 27 type prebuiltDependencyTag struct { 28 blueprint.BaseDependencyTag 29 } 30 31 var prebuiltDepTag prebuiltDependencyTag 32 33 type PrebuiltProperties struct { 34 // When prefer is set to true the prebuilt will be used instead of any source module with 35 // a matching name. 36 Prefer *bool `android:"arch_variant"` 37 38 SourceExists bool `blueprint:"mutated"` 39 UsePrebuilt bool `blueprint:"mutated"` 40 } 41 42 type Prebuilt struct { 43 properties PrebuiltProperties 44 module Module 45 srcs *[]string 46 src *string 47 } 48 49 func (p *Prebuilt) Name(name string) string { 50 return "prebuilt_" + name 51 } 52 53 func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path { 54 if p.srcs != nil { 55 if len(*p.srcs) == 0 { 56 ctx.PropertyErrorf("srcs", "missing prebuilt source file") 57 return nil 58 } 59 60 if len(*p.srcs) > 1 { 61 ctx.PropertyErrorf("srcs", "multiple prebuilt source files") 62 return nil 63 } 64 65 // Return the singleton source after expanding any filegroup in the 66 // sources. 67 return PathForModuleSrc(ctx, (*p.srcs)[0]) 68 } else { 69 if proptools.String(p.src) == "" { 70 ctx.PropertyErrorf("src", "missing prebuilt source file") 71 return nil 72 } 73 return PathForModuleSrc(ctx, *p.src) 74 } 75 } 76 77 func (p *Prebuilt) UsePrebuilt() bool { 78 return p.properties.UsePrebuilt 79 } 80 81 func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) { 82 p := module.Prebuilt() 83 module.AddProperties(&p.properties) 84 p.srcs = srcs 85 } 86 87 func InitSingleSourcePrebuiltModule(module PrebuiltInterface, src *string) { 88 p := module.Prebuilt() 89 module.AddProperties(&p.properties) 90 p.src = src 91 } 92 93 type PrebuiltInterface interface { 94 Module 95 Prebuilt() *Prebuilt 96 } 97 98 func RegisterPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) { 99 ctx.BottomUp("prebuilts", PrebuiltMutator).Parallel() 100 } 101 102 func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) { 103 ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel() 104 ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel() 105 } 106 107 // PrebuiltMutator ensures that there is always a module with an undecorated name, and marks 108 // prebuilt modules that have both a prebuilt and a source module. 109 func PrebuiltMutator(ctx BottomUpMutatorContext) { 110 if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { 111 p := m.Prebuilt() 112 name := m.base().BaseModuleName() 113 if ctx.OtherModuleExists(name) { 114 ctx.AddReverseDependency(ctx.Module(), prebuiltDepTag, name) 115 p.properties.SourceExists = true 116 } else { 117 ctx.Rename(name) 118 } 119 } 120 } 121 122 // PrebuiltSelectModuleMutator marks prebuilts that are used, either overriding source modules or 123 // because the source module doesn't exist. It also disables installing overridden source modules. 124 func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) { 125 if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { 126 p := m.Prebuilt() 127 if p.srcs == nil && p.src == nil { 128 panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it")) 129 } 130 if !p.properties.SourceExists { 131 p.properties.UsePrebuilt = p.usePrebuilt(ctx, nil) 132 } 133 } else if s, ok := ctx.Module().(Module); ok { 134 ctx.VisitDirectDepsWithTag(prebuiltDepTag, func(m Module) { 135 p := m.(PrebuiltInterface).Prebuilt() 136 if p.usePrebuilt(ctx, s) { 137 p.properties.UsePrebuilt = true 138 s.SkipInstall() 139 } 140 }) 141 } 142 } 143 144 // PrebuiltPostDepsMutator does two operations. It replace dependencies on the 145 // source module with dependencies on the prebuilt when both modules exist and 146 // the prebuilt should be used. When the prebuilt should not be used, disable 147 // installing it. Secondly, it also adds a sourcegroup to any filegroups found 148 // in the prebuilt's 'Srcs' property. 149 func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) { 150 if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { 151 p := m.Prebuilt() 152 name := m.base().BaseModuleName() 153 if p.properties.UsePrebuilt { 154 if p.properties.SourceExists { 155 ctx.ReplaceDependencies(name) 156 } 157 } else { 158 m.SkipInstall() 159 } 160 } 161 } 162 163 // usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt 164 // will be used if it is marked "prefer" or if the source module is disabled. 165 func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool { 166 if p.srcs != nil && len(*p.srcs) == 0 { 167 return false 168 } 169 170 if p.src != nil && *p.src == "" { 171 return false 172 } 173 174 // TODO: use p.Properties.Name and ctx.ModuleDir to override preference 175 if Bool(p.properties.Prefer) { 176 return true 177 } 178 179 return source == nil || !source.Enabled() 180 } 181 182 func (p *Prebuilt) SourceExists() bool { 183 return p.properties.SourceExists 184 } 185