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 15package android 16 17import "github.com/google/blueprint" 18 19// This file implements common functionality for handling modules that may exist as prebuilts, 20// source, or both. 21 22type prebuiltDependencyTag struct { 23 blueprint.BaseDependencyTag 24} 25 26var prebuiltDepTag prebuiltDependencyTag 27 28type Prebuilt struct { 29 Properties struct { 30 Srcs []string `android:"arch_variant"` 31 // When prefer is set to true the prebuilt will be used instead of any source module with 32 // a matching name. 33 Prefer bool `android:"arch_variant"` 34 35 SourceExists bool `blueprint:"mutated"` 36 UsePrebuilt bool `blueprint:"mutated"` 37 } 38 module Module 39} 40 41func (p *Prebuilt) Name(name string) string { 42 return "prebuilt_" + name 43} 44 45func (p *Prebuilt) Path(ctx ModuleContext) Path { 46 if len(p.Properties.Srcs) == 0 { 47 ctx.PropertyErrorf("srcs", "missing prebuilt source file") 48 return nil 49 } 50 51 if len(p.Properties.Srcs) > 1 { 52 ctx.PropertyErrorf("srcs", "multiple prebuilt source files") 53 return nil 54 } 55 56 return PathForModuleSrc(ctx, p.Properties.Srcs[0]) 57} 58 59type PrebuiltInterface interface { 60 Module 61 Prebuilt() *Prebuilt 62} 63 64// prebuiltMutator ensures that there is always a module with an undecorated name, and marks 65// prebuilt modules that have both a prebuilt and a source module. 66func prebuiltMutator(ctx BottomUpMutatorContext) { 67 if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { 68 p := m.Prebuilt() 69 name := m.base().BaseModuleName() 70 if ctx.OtherModuleExists(name) { 71 ctx.AddReverseDependency(ctx.Module(), prebuiltDepTag, name) 72 p.Properties.SourceExists = true 73 } else { 74 ctx.Rename(name) 75 } 76 } 77} 78 79// PrebuiltSelectModuleMutator marks prebuilts that are used, either overriding source modules or 80// because the source module doesn't exist. It also disables installing overridden source modules. 81func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) { 82 if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { 83 p := m.Prebuilt() 84 if !p.Properties.SourceExists { 85 p.Properties.UsePrebuilt = p.usePrebuilt(ctx, nil) 86 } 87 } else if s, ok := ctx.Module().(Module); ok { 88 ctx.VisitDirectDeps(func(m blueprint.Module) { 89 if ctx.OtherModuleDependencyTag(m) == prebuiltDepTag { 90 p := m.(PrebuiltInterface).Prebuilt() 91 if p.usePrebuilt(ctx, s) { 92 p.Properties.UsePrebuilt = true 93 s.SkipInstall() 94 } 95 } 96 }) 97 } 98} 99 100// PrebuiltReplaceMutator replaces dependencies on the source module with dependencies on the 101// prebuilt when both modules exist and the prebuilt should be used. When the prebuilt should not 102// be used, disable installing it. 103func PrebuiltReplaceMutator(ctx BottomUpMutatorContext) { 104 if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { 105 p := m.Prebuilt() 106 name := m.base().BaseModuleName() 107 if p.Properties.UsePrebuilt { 108 if p.Properties.SourceExists { 109 ctx.ReplaceDependencies(name) 110 } 111 } else { 112 m.SkipInstall() 113 } 114 } 115} 116 117// usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt 118// will be used if it is marked "prefer" or if the source module is disabled. 119func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool { 120 if len(p.Properties.Srcs) == 0 { 121 return false 122 } 123 124 // TODO: use p.Properties.Name and ctx.ModuleDir to override preference 125 if p.Properties.Prefer { 126 return true 127 } 128 129 return source == nil || !source.Enabled() 130} 131