From 13af8140bcf40c71deb3b0fee11bb8e9ad792621 Mon Sep 17 00:00:00 2001 From: Dan Willemsen Date: Thu, 16 Jul 2020 17:49:05 -0700 Subject: [PATCH] Add prebuilt_build_tool to allow genrules to use prebuilt tools cc_prebuilt_binary doesn't work well for host tools because they'll often be using their own versions of shared libraries that may not be compatible with what we build. So add a module type that allows genrules to use one of these prebuilts as a tool. Like other prebuilts, we'll use the source module if we have it, or the prebuilt otherwise. It supports adding extra dependencies for shared libraries or other data files that are necessary to run the tool. Any genrules using the tool will be rerun if any of the dependencies change. Bug: 128690776 Test: treehugger (builds one-true-awk with bison) Change-Id: I82c26be1c3c9fe6cab42892ddea339c301c0b316 --- android/Android.bp | 1 + android/defs.go | 2 +- android/prebuilt_build_tool.go | 94 ++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 android/prebuilt_build_tool.go diff --git a/android/Android.bp b/android/Android.bp index 977345b6b..1627e9c42 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -39,6 +39,7 @@ bootstrap_go_package { "paths.go", "phony.go", "prebuilt.go", + "prebuilt_build_tool.go", "proto.go", "register.go", "rule_builder.go", diff --git a/android/defs.go b/android/defs.go index 45522246f..83daa0368 100644 --- a/android/defs.go +++ b/android/defs.go @@ -69,7 +69,7 @@ var ( // A symlink rule. Symlink = pctx.AndroidStaticRule("Symlink", blueprint.RuleParams{ - Command: "ln -f -s $fromPath $out", + Command: "rm -f $out && ln -f -s $fromPath $out", Description: "symlink $out", }, "fromPath") diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go new file mode 100644 index 000000000..a9f29ef69 --- /dev/null +++ b/android/prebuilt_build_tool.go @@ -0,0 +1,94 @@ +// Copyright 2020 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 android + +import ( + "path" + "path/filepath" +) + +func init() { + RegisterModuleType("prebuilt_build_tool", prebuiltBuildToolFactory) +} + +type prebuiltBuildToolProperties struct { + // Source file to be executed for this build tool + Src *string `android:"path,arch_variant"` + + // Extra files that should trigger rules using this tool to rebuild + Deps []string `android:"path,arch_variant"` +} + +type prebuiltBuildTool struct { + ModuleBase + prebuilt Prebuilt + + properties prebuiltBuildToolProperties + + toolPath OptionalPath +} + +func (t *prebuiltBuildTool) Name() string { + return t.prebuilt.Name(t.ModuleBase.Name()) +} + +func (t *prebuiltBuildTool) Prebuilt() *Prebuilt { + return &t.prebuilt +} + +func (t *prebuiltBuildTool) DepsMutator(ctx BottomUpMutatorContext) { + if t.properties.Src == nil { + ctx.PropertyErrorf("src", "missing prebuilt source file") + } +} + +func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) { + sourcePath := t.prebuilt.SingleSourcePath(ctx) + installedPath := PathForModuleOut(ctx, t.ModuleBase.Name()) + deps := PathsForModuleSrc(ctx, t.properties.Deps) + + relPath, err := filepath.Rel(path.Dir(installedPath.String()), sourcePath.String()) + if err != nil { + ctx.ModuleErrorf("Unabled to generate symlink between %q and %q: %s", installedPath.String(), sourcePath.String()) + } + + ctx.Build(pctx, BuildParams{ + Rule: Symlink, + Output: installedPath, + Input: sourcePath, + Implicits: deps, + Args: map[string]string{ + "fromPath": relPath, + }, + }) + + t.toolPath = OptionalPathForPath(installedPath) +} + +func (t *prebuiltBuildTool) HostToolPath() OptionalPath { + return t.toolPath +} + +var _ HostToolProvider = &prebuiltBuildTool{} + +// prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use +// in genrules with the "tools" property. +func prebuiltBuildToolFactory() Module { + module := &prebuiltBuildTool{} + module.AddProperties(&module.properties) + InitSingleSourcePrebuiltModule(module, &module.properties, "Src") + InitAndroidArchModule(module, HostSupportedNoCross, MultilibFirst) + return module +}