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 ( 18 "fmt" 19 "os" 20 "strings" 21 22 "github.com/google/blueprint" 23) 24 25// The Bazel QueryView singleton is responsible for generating the Ninja actions 26// for calling the soong_build primary builder in the main build.ninja file. 27func init() { 28 RegisterSingletonType("bazel_queryview", BazelQueryViewSingleton) 29} 30 31// BazelQueryViewSingleton is the singleton responsible for registering the 32// soong_build build statement that will convert the Soong module graph after 33// applying *all* mutators, enabing the feature to query the final state of the 34// Soong graph. This mode is meant for querying the build graph state, and not meant 35// for generating BUILD files to be checked in. 36func BazelQueryViewSingleton() Singleton { 37 return &bazelQueryViewSingleton{} 38} 39 40// BazelConverterSingleton is the singleton responsible for registering the soong_build 41// build statement that will convert the Soong module graph by applying an alternate 42// pipeline of mutators, with the goal of reaching semantic equivalence between the original 43// Blueprint and final BUILD files. Using this mode, the goal is to be able to 44// build with these BUILD files directly in the source tree. 45func BazelConverterSingleton() Singleton { 46 return &bazelConverterSingleton{} 47} 48 49type bazelQueryViewSingleton struct{} 50type bazelConverterSingleton struct{} 51 52func generateBuildActionsForBazelConversion(ctx SingletonContext, converterMode bool) { 53 name := "queryview" 54 descriptionTemplate := "[EXPERIMENTAL, PRE-PRODUCTION] Creating the Bazel QueryView workspace with %s at $outDir" 55 56 // Create a build and rule statement, using the Bazel QueryView's WORKSPACE 57 // file as the output file marker. 58 var deps Paths 59 moduleListFilePath := pathForBuildToolDep(ctx, ctx.Config().moduleListFile) 60 deps = append(deps, moduleListFilePath) 61 deps = append(deps, pathForBuildToolDep(ctx, ctx.Config().ProductVariablesFileName)) 62 63 bazelQueryViewDirectory := PathForOutput(ctx, name) 64 bazelQueryViewWorkspaceFile := bazelQueryViewDirectory.Join(ctx, "WORKSPACE") 65 primaryBuilder := primaryBuilderPath(ctx) 66 bazelQueryView := ctx.Rule(pctx, "bazelQueryView", 67 blueprint.RuleParams{ 68 Command: fmt.Sprintf( 69 `rm -rf "${outDir}/"* && `+ 70 `mkdir -p "${outDir}" && `+ 71 `echo WORKSPACE: $$(cat "%s") > "${outDir}/.queryview-depfile.d" && `+ 72 `BUILDER="%s" && `+ 73 `echo BUILDER=$$BUILDER && `+ 74 `cd "$$(dirname "$$BUILDER")" && `+ 75 `echo PWD=$$PWD && `+ 76 `ABSBUILDER="$$PWD/$$(basename "$$BUILDER")" && `+ 77 `echo ABSBUILDER=$$ABSBUILDER && `+ 78 `cd / && `+ 79 `env -i "$$ABSBUILDER" --bazel_queryview_dir "${outDir}" "%s"`, 80 moduleListFilePath.String(), // Use the contents of Android.bp.list as the depfile. 81 primaryBuilder.String(), 82 strings.Join(os.Args[1:], "\" \""), 83 ), 84 CommandDeps: []string{primaryBuilder.String()}, 85 Description: fmt.Sprintf( 86 descriptionTemplate, 87 primaryBuilder.Base()), 88 Deps: blueprint.DepsGCC, 89 Depfile: "${outDir}/.queryview-depfile.d", 90 }, 91 "outDir") 92 93 ctx.Build(pctx, BuildParams{ 94 Rule: bazelQueryView, 95 Output: bazelQueryViewWorkspaceFile, 96 Inputs: deps, 97 Args: map[string]string{ 98 "outDir": bazelQueryViewDirectory.String(), 99 }, 100 }) 101 102 // Add a phony target for generating the workspace 103 ctx.Phony(name, bazelQueryViewWorkspaceFile) 104} 105 106func (c *bazelQueryViewSingleton) GenerateBuildActions(ctx SingletonContext) { 107 generateBuildActionsForBazelConversion(ctx, false) 108} 109 110func (c *bazelConverterSingleton) GenerateBuildActions(ctx SingletonContext) { 111 generateBuildActionsForBazelConversion(ctx, true) 112} 113