Home | History | Annotate | Download | only in android
      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