1 // Copyright 2015 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/pathtools" 22 ) 23 24 // AndroidPackageContext is a wrapper for blueprint.PackageContext that adds 25 // some android-specific helper functions. 26 type AndroidPackageContext struct { 27 blueprint.PackageContext 28 } 29 30 func NewPackageContext(pkgPath string) AndroidPackageContext { 31 return AndroidPackageContext{blueprint.NewPackageContext(pkgPath)} 32 } 33 34 // configErrorWrapper can be used with Path functions when a Context is not 35 // available. A Config can be provided, and errors are stored as a list for 36 // later retrieval. 37 // 38 // The most common use here will be with VariableFunc, where only a config is 39 // provided, and an error should be returned. 40 type configErrorWrapper struct { 41 pctx AndroidPackageContext 42 config Config 43 errors []error 44 } 45 46 var _ PathContext = &configErrorWrapper{} 47 var _ errorfContext = &configErrorWrapper{} 48 49 func (e *configErrorWrapper) Config() interface{} { 50 return e.config 51 } 52 func (e *configErrorWrapper) Errorf(format string, args ...interface{}) { 53 e.errors = append(e.errors, fmt.Errorf(format, args...)) 54 } 55 func (e *configErrorWrapper) AddNinjaFileDeps(deps ...string) { 56 e.pctx.AddNinjaFileDeps(deps...) 57 } 58 59 func (e *configErrorWrapper) Fs() pathtools.FileSystem { 60 return nil 61 } 62 63 // SourcePathVariable returns a Variable whose value is the source directory 64 // appended with the supplied path. It may only be called during a Go package's 65 // initialization - either from the init() function or as part of a 66 // package-scoped variable's initialization. 67 func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.Variable { 68 return p.VariableFunc(name, func(config interface{}) (string, error) { 69 ctx := &configErrorWrapper{p, config.(Config), []error{}} 70 p := safePathForSource(ctx, path) 71 if len(ctx.errors) > 0 { 72 return "", ctx.errors[0] 73 } 74 return p.String(), nil 75 }) 76 } 77 78 // HostBinVariable returns a Variable whose value is the path to a host tool 79 // in the bin directory for host targets. It may only be called during a Go 80 // package's initialization - either from the init() function or as part of a 81 // package-scoped variable's initialization. 82 func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.Variable { 83 return p.VariableFunc(name, func(config interface{}) (string, error) { 84 ctx := &configErrorWrapper{p, config.(Config), []error{}} 85 p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "bin", path) 86 if len(ctx.errors) > 0 { 87 return "", ctx.errors[0] 88 } 89 return p.String(), nil 90 }) 91 } 92 93 // HostJavaToolVariable returns a Variable whose value is the path to a host 94 // tool in the frameworks directory for host targets. It may only be called 95 // during a Go package's initialization - either from the init() function or as 96 // part of a package-scoped variable's initialization. 97 func (p AndroidPackageContext) HostJavaToolVariable(name, path string) blueprint.Variable { 98 return p.VariableFunc(name, func(config interface{}) (string, error) { 99 ctx := &configErrorWrapper{p, config.(Config), []error{}} 100 p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path) 101 if len(ctx.errors) > 0 { 102 return "", ctx.errors[0] 103 } 104 return p.String(), nil 105 }) 106 } 107 108 // IntermediatesPathVariable returns a Variable whose value is the intermediate 109 // directory appended with the supplied path. It may only be called during a Go 110 // package's initialization - either from the init() function or as part of a 111 // package-scoped variable's initialization. 112 func (p AndroidPackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable { 113 return p.VariableFunc(name, func(config interface{}) (string, error) { 114 ctx := &configErrorWrapper{p, config.(Config), []error{}} 115 p := PathForIntermediates(ctx, path) 116 if len(ctx.errors) > 0 { 117 return "", ctx.errors[0] 118 } 119 return p.String(), nil 120 }) 121 } 122 123 // PrefixedPathsForOptionalSourceVariable returns a Variable whose value is the 124 // list of present source paths prefixed with the supplied prefix. It may only 125 // be called during a Go package's initialization - either from the init() 126 // function or as part of a package-scoped variable's initialization. 127 func (p AndroidPackageContext) PrefixedPathsForOptionalSourceVariable( 128 name, prefix string, paths []string) blueprint.Variable { 129 130 return p.VariableFunc(name, func(config interface{}) (string, error) { 131 ctx := &configErrorWrapper{p, config.(Config), []error{}} 132 paths := PathsForOptionalSource(ctx, "", paths) 133 if len(ctx.errors) > 0 { 134 return "", ctx.errors[0] 135 } 136 return JoinWithPrefix(paths.Strings(), prefix), nil 137 }) 138 } 139 140 type RuleParams struct { 141 blueprint.RuleParams 142 GomaSupported bool 143 } 144 145 // AndroidStaticRule wraps blueprint.StaticRule and provides a default Pool if none is specified 146 func (p AndroidPackageContext) AndroidStaticRule(name string, params blueprint.RuleParams, 147 argNames ...string) blueprint.Rule { 148 return p.AndroidRuleFunc(name, func(interface{}) (blueprint.RuleParams, error) { 149 return params, nil 150 }, argNames...) 151 } 152 153 // AndroidGomaStaticRule wraps blueprint.StaticRule but uses goma's parallelism if goma is enabled 154 func (p AndroidPackageContext) AndroidGomaStaticRule(name string, params blueprint.RuleParams, 155 argNames ...string) blueprint.Rule { 156 return p.StaticRule(name, params, argNames...) 157 } 158 159 func (p AndroidPackageContext) AndroidRuleFunc(name string, 160 f func(interface{}) (blueprint.RuleParams, error), argNames ...string) blueprint.Rule { 161 return p.PackageContext.RuleFunc(name, func(config interface{}) (blueprint.RuleParams, error) { 162 params, err := f(config) 163 if config.(Config).UseGoma() && params.Pool == nil { 164 // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the 165 // local parallelism value 166 params.Pool = localPool 167 } 168 return params, err 169 }, argNames...) 170 } 171