1// Copyright 2020 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 android
16
17import "path/filepath"
18
19func init() {
20	RegisterModuleType("prebuilt_build_tool", NewPrebuiltBuildTool)
21}
22
23type prebuiltBuildToolProperties struct {
24	// Source file to be executed for this build tool
25	Src *string `android:"path,arch_variant"`
26
27	// Extra files that should trigger rules using this tool to rebuild
28	Deps []string `android:"path,arch_variant"`
29
30	// Create a make variable with the specified name that contains the path to
31	// this prebuilt built tool, relative to the root of the source tree.
32	Export_to_make_var *string
33}
34
35type prebuiltBuildTool struct {
36	ModuleBase
37	prebuilt Prebuilt
38
39	properties prebuiltBuildToolProperties
40
41	toolPath OptionalPath
42}
43
44func (t *prebuiltBuildTool) Name() string {
45	return t.prebuilt.Name(t.ModuleBase.Name())
46}
47
48func (t *prebuiltBuildTool) Prebuilt() *Prebuilt {
49	return &t.prebuilt
50}
51
52func (t *prebuiltBuildTool) DepsMutator(ctx BottomUpMutatorContext) {
53	if t.properties.Src == nil {
54		ctx.PropertyErrorf("src", "missing prebuilt source file")
55	}
56}
57
58func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) {
59	sourcePath := t.prebuilt.SingleSourcePath(ctx)
60	installedPath := PathForModuleOut(ctx, t.BaseModuleName())
61	deps := PathsForModuleSrc(ctx, t.properties.Deps)
62
63	var fromPath = sourcePath.String()
64	if !filepath.IsAbs(fromPath) {
65		fromPath = "$$PWD/" + fromPath
66	}
67
68	ctx.Build(pctx, BuildParams{
69		Rule:      Symlink,
70		Output:    installedPath,
71		Input:     sourcePath,
72		Implicits: deps,
73		Args: map[string]string{
74			"fromPath": fromPath,
75		},
76	})
77
78	packagingDir := PathForModuleInstall(ctx, t.BaseModuleName())
79	ctx.PackageFile(packagingDir, sourcePath.String(), sourcePath)
80	for _, dep := range deps {
81		ctx.PackageFile(packagingDir, dep.String(), dep)
82	}
83
84	t.toolPath = OptionalPathForPath(installedPath)
85}
86
87func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) {
88	if makeVar := String(t.properties.Export_to_make_var); makeVar != "" {
89		if t.Target().Os != ctx.Config().BuildOS {
90			return
91		}
92		ctx.StrictRaw(makeVar, t.toolPath.String())
93	}
94}
95
96func (t *prebuiltBuildTool) HostToolPath() OptionalPath {
97	return t.toolPath
98}
99
100var _ HostToolProvider = &prebuiltBuildTool{}
101
102// prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use
103// in genrules with the "tools" property.
104func NewPrebuiltBuildTool() Module {
105	module := &prebuiltBuildTool{}
106	module.AddProperties(&module.properties)
107	InitSingleSourcePrebuiltModule(module, &module.properties, "Src")
108	InitAndroidArchModule(module, HostSupportedNoCross, MultilibFirst)
109	return module
110}
111