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
15package common
16
17import (
18	"fmt"
19
20	"github.com/google/blueprint"
21)
22
23// AndroidPackageContext is a wrapper for blueprint.PackageContext that adds
24// some android-specific helper functions.
25type AndroidPackageContext struct {
26	blueprint.PackageContext
27}
28
29func NewPackageContext(pkgPath string) AndroidPackageContext {
30	return AndroidPackageContext{blueprint.NewPackageContext(pkgPath)}
31}
32
33// configErrorWrapper can be used with Path functions when a Context is not
34// available. A Config can be provided, and errors are stored as a list for
35// later retrieval.
36//
37// The most common use here will be with VariableFunc, where only a config is
38// provided, and an error should be returned.
39type configErrorWrapper struct {
40	pctx   AndroidPackageContext
41	config Config
42	errors []error
43}
44
45var _ PathContext = &configErrorWrapper{}
46var _ errorfContext = &configErrorWrapper{}
47
48func (e *configErrorWrapper) Config() interface{} {
49	return e.config
50}
51func (e *configErrorWrapper) Errorf(format string, args ...interface{}) {
52	e.errors = append(e.errors, fmt.Errorf(format, args...))
53}
54func (e *configErrorWrapper) AddNinjaFileDeps(deps ...string) {
55	e.pctx.AddNinjaFileDeps(deps...)
56}
57
58// SourcePathVariable returns a Variable whose value is the source directory
59// appended with the supplied path. It may only be called during a Go package's
60// initialization - either from the init() function or as part of a
61// package-scoped variable's initialization.
62func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.Variable {
63	return p.VariableFunc(name, func(config interface{}) (string, error) {
64		ctx := &configErrorWrapper{p, config.(Config), []error{}}
65		p := safePathForSource(ctx, path)
66		if len(ctx.errors) > 0 {
67			return "", ctx.errors[0]
68		}
69		return p.String(), nil
70	})
71}
72
73// HostBinVariable returns a Variable whose value is the path to a host tool
74// in the bin directory for host targets. It may only be called during a Go
75// package's initialization - either from the init() function or as part of a
76// package-scoped variable's initialization.
77func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.Variable {
78	return p.VariableFunc(name, func(config interface{}) (string, error) {
79		ctx := &configErrorWrapper{p, config.(Config), []error{}}
80		p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "bin", path)
81		if len(ctx.errors) > 0 {
82			return "", ctx.errors[0]
83		}
84		return p.String(), nil
85	})
86}
87
88// HostJavaToolVariable returns a Variable whose value is the path to a host
89// tool in the frameworks directory for host targets. It may only be called
90// during a Go package's initialization - either from the init() function or as
91// part of a package-scoped variable's initialization.
92func (p AndroidPackageContext) HostJavaToolVariable(name, path string) blueprint.Variable {
93	return p.VariableFunc(name, func(config interface{}) (string, error) {
94		ctx := &configErrorWrapper{p, config.(Config), []error{}}
95		p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path)
96		if len(ctx.errors) > 0 {
97			return "", ctx.errors[0]
98		}
99		return p.String(), nil
100	})
101}
102
103// IntermediatesPathVariable returns a Variable whose value is the intermediate
104// directory appended with the supplied path. It may only be called during a Go
105// package's initialization - either from the init() function or as part of a
106// package-scoped variable's initialization.
107func (p AndroidPackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable {
108	return p.VariableFunc(name, func(config interface{}) (string, error) {
109		ctx := &configErrorWrapper{p, config.(Config), []error{}}
110		p := PathForIntermediates(ctx, path)
111		if len(ctx.errors) > 0 {
112			return "", ctx.errors[0]
113		}
114		return p.String(), nil
115	})
116}
117
118// PrefixedPathsForOptionalSourceVariable returns a Variable whose value is the
119// list of present source paths prefixed with the supplied prefix. It may only
120// be called during a Go package's initialization - either from the init()
121// function or as part of a package-scoped variable's initialization.
122func (p AndroidPackageContext) PrefixedPathsForOptionalSourceVariable(
123	name, prefix string, paths []string) blueprint.Variable {
124
125	return p.VariableFunc(name, func(config interface{}) (string, error) {
126		ctx := &configErrorWrapper{p, config.(Config), []error{}}
127		paths := PathsForOptionalSource(ctx, "", paths)
128		if len(ctx.errors) > 0 {
129			return "", ctx.errors[0]
130		}
131		return JoinWithPrefix(paths.Strings(), prefix), nil
132	})
133}
134