github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/android/prebuilt.go (about)

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