Use `Path` instead of string for file paths
This centralizes verification and common operations, like converting the
path to a source file to the path for a built object.
It also embeds the configuration knowledge into the path, so that we can
remove "${SrcDir}/path" from the ninja file. When SrcDir is '.', that
leads to paths like './path' instead of just 'path' like make is doing,
causing differences in compiled binaries.
Change-Id: Ib4e8910a6e867ce1b7b420d927c04f1142a7589e
diff --git a/common/package_ctx.go b/common/package_ctx.go
new file mode 100644
index 0000000..cd18b65
--- /dev/null
+++ b/common/package_ctx.go
@@ -0,0 +1,127 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package common
+
+import (
+ "fmt"
+
+ "github.com/google/blueprint"
+)
+
+// AndroidPackageContext is a wrapper for blueprint.PackageContext that adds
+// some android-specific helper functions.
+type AndroidPackageContext struct {
+ blueprint.PackageContext
+}
+
+func NewPackageContext(pkgPath string) AndroidPackageContext {
+ return AndroidPackageContext{blueprint.NewPackageContext(pkgPath)}
+}
+
+// configErrorWrapper can be used with Path functions when a Context is not
+// available. A Config can be provided, and errors are stored as a list for
+// later retrieval.
+//
+// The most common use here will be with VariableFunc, where only a config is
+// provided, and an error should be returned.
+type configErrorWrapper struct {
+ config Config
+ errors []error
+}
+
+var _ PathContext = &configErrorWrapper{}
+var _ errorfContext = &configErrorWrapper{}
+
+func (e *configErrorWrapper) Config() interface{} {
+ return e.config
+}
+func (e *configErrorWrapper) Errorf(format string, args ...interface{}) {
+ e.errors = append(e.errors, fmt.Errorf(format, args...))
+}
+
+// SourcePathVariable returns a Variable whose value is the source directory
+// appended with the supplied path. It may only be called during a Go package's
+// initialization - either from the init() function or as part of a
+// package-scoped variable's initialization.
+func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.Variable {
+ return p.VariableFunc(name, func(config interface{}) (string, error) {
+ ctx := &configErrorWrapper{config.(Config), []error{}}
+ p := safePathForSource(ctx, path)
+ if len(ctx.errors) > 0 {
+ return "", ctx.errors[0]
+ }
+ return p.String(), nil
+ })
+}
+
+// HostBinVariable returns a Variable whose value is the path to a host tool
+// in the bin directory for host targets. It may only be called during a Go
+// package's initialization - either from the init() function or as part of a
+// package-scoped variable's initialization.
+func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.Variable {
+ return p.VariableFunc(name, func(config interface{}) (string, error) {
+ ctx := &configErrorWrapper{config.(Config), []error{}}
+ p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "bin", path)
+ if len(ctx.errors) > 0 {
+ return "", ctx.errors[0]
+ }
+ return p.String(), nil
+ })
+}
+
+// HostJavaToolVariable returns a Variable whose value is the path to a host
+// tool in the frameworks directory for host targets. It may only be called
+// during a Go package's initialization - either from the init() function or as
+// part of a package-scoped variable's initialization.
+func (p AndroidPackageContext) HostJavaToolVariable(name, path string) blueprint.Variable {
+ return p.VariableFunc(name, func(config interface{}) (string, error) {
+ ctx := &configErrorWrapper{config.(Config), []error{}}
+ p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path)
+ if len(ctx.errors) > 0 {
+ return "", ctx.errors[0]
+ }
+ return p.String(), nil
+ })
+}
+
+// IntermediatesPathVariable returns a Variable whose value is the intermediate
+// directory appended with the supplied path. It may only be called during a Go
+// package's initialization - either from the init() function or as part of a
+// package-scoped variable's initialization.
+func (p AndroidPackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable {
+ return p.VariableFunc(name, func(config interface{}) (string, error) {
+ ctx := &configErrorWrapper{config.(Config), []error{}}
+ p := PathForIntermediates(ctx, path)
+ if len(ctx.errors) > 0 {
+ return "", ctx.errors[0]
+ }
+ return p.String(), nil
+ })
+}
+
+// PrefixedPathsForSourceVariable returns a Variable whose value is the
+// list of source paths prefixed with the supplied prefix. It may only be
+// called during a Go package's initialization - either from the init()
+// function or as part of a package-scoped variable's initialization.
+func (p AndroidPackageContext) PrefixedPathsForSourceVariable(name, prefix string, paths []string) blueprint.Variable {
+ return p.VariableFunc(name, func(config interface{}) (string, error) {
+ ctx := &configErrorWrapper{config.(Config), []error{}}
+ paths := PathsForSource(ctx, paths)
+ if len(ctx.errors) > 0 {
+ return "", ctx.errors[0]
+ }
+ return JoinWithPrefix(paths.Strings(), prefix), nil
+ })
+}