diff options
Diffstat (limited to 'android/bazel_handler.go')
-rw-r--r-- | android/bazel_handler.go | 94 |
1 files changed, 89 insertions, 5 deletions
diff --git a/android/bazel_handler.go b/android/bazel_handler.go index 94bc88b42..fd4b5ef1b 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -186,6 +186,8 @@ type BazelContext interface { // Returns the depsets defined in Bazel's aquery response. AqueryDepsets() []bazel.AqueryDepset + + QueueBazelSandwichCqueryRequests(config Config) error } type bazelRunner interface { @@ -264,6 +266,10 @@ func (m MockBazelContext) QueueBazelRequest(label string, requestType cqueryRequ m.BazelRequests[key] = true } +func (m MockBazelContext) QueueBazelSandwichCqueryRequests(config Config) error { + panic("unimplemented") +} + func (m MockBazelContext) GetOutputFiles(label string, _ configKey) ([]string, error) { result, ok := m.LabelToOutputFiles[label] if !ok { @@ -424,6 +430,10 @@ func (n noopBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configK panic("unimplemented") } +func (n noopBazelContext) QueueBazelSandwichCqueryRequests(config Config) error { + panic("unimplemented") +} + func (n noopBazelContext) GetOutputFiles(_ string, _ configKey) ([]string, error) { panic("unimplemented") } @@ -1042,6 +1052,50 @@ var ( allBazelCommands = []bazelCommand{aqueryCmd, cqueryCmd, buildCmd} ) +func GetBazelSandwichCqueryRequests(config Config) ([]cqueryKey, error) { + result := make([]cqueryKey, 0, len(allowlists.BazelSandwichTargets)) + // Note that bazel "targets" are different from soong "targets", the bazel targets are + // synonymous with soong modules, and soong targets are a configuration a module is built in. + for _, target := range allowlists.BazelSandwichTargets { + var soongTarget Target + if target.Host { + soongTarget = config.BuildOSTarget + } else { + soongTarget = config.AndroidCommonTarget + if soongTarget.Os.Class != Device { + // kernel-build-tools seems to set the AndroidCommonTarget to a linux host + // target for some reason, disable device builds in that case. + continue + } + } + + result = append(result, cqueryKey{ + label: target.Label, + requestType: cquery.GetOutputFiles, + configKey: configKey{ + arch: soongTarget.Arch.String(), + osType: soongTarget.Os, + }, + }) + } + return result, nil +} + +// QueueBazelSandwichCqueryRequests queues cquery requests for all the bazel labels in +// bazel_sandwich_targets. These will later be given phony targets so that they can be built on the +// command line. +func (context *mixedBuildBazelContext) QueueBazelSandwichCqueryRequests(config Config) error { + requests, err := GetBazelSandwichCqueryRequests(config) + if err != nil { + return err + } + for _, request := range requests { + context.QueueBazelRequest(request.label, request.requestType, request.configKey) + } + + return nil +} + // Issues commands to Bazel to receive results for all cquery requests // queued in the BazelContext. func (context *mixedBuildBazelContext) InvokeBazel(config Config, ctx invokeBazelContext) error { @@ -1255,6 +1309,11 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) { executionRoot := path.Join(ctx.Config().BazelContext.OutputBase(), "execroot", "__main__") bazelOutDir := path.Join(executionRoot, "bazel-out") + rel, err := filepath.Rel(ctx.Config().OutDir(), executionRoot) + if err != nil { + ctx.Errorf("%s", err.Error()) + } + dotdotsToOutRoot := strings.Repeat("../", strings.Count(rel, "/")+1) for index, buildStatement := range ctx.Config().BazelContext.BuildStatementsToRegister() { // nil build statements are a valid case where we do not create an action because it is // unnecessary or handled by other processing @@ -1286,7 +1345,8 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) { }) } } - createCommand(rule.Command(), buildStatement, executionRoot, bazelOutDir, ctx, depsetHashToDepset) + createCommand(rule.Command(), buildStatement, executionRoot, bazelOutDir, ctx, depsetHashToDepset, dotdotsToOutRoot) + desc := fmt.Sprintf("%s: %s", buildStatement.Mnemonic, buildStatement.OutputPaths) rule.Build(fmt.Sprintf("bazel %d", index), desc) continue @@ -1331,6 +1391,24 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) { panic(fmt.Sprintf("unhandled build statement: %v", buildStatement)) } } + + // Create phony targets for all the bazel sandwich output files + requests, err := GetBazelSandwichCqueryRequests(ctx.Config()) + if err != nil { + ctx.Errorf(err.Error()) + } + for _, request := range requests { + files, err := ctx.Config().BazelContext.GetOutputFiles(request.label, request.configKey) + if err != nil { + ctx.Errorf(err.Error()) + } + filesAsPaths := make([]Path, 0, len(files)) + for _, file := range files { + filesAsPaths = append(filesAsPaths, PathForBazelOut(ctx, file)) + } + ctx.Phony("bazel_sandwich", filesAsPaths...) + } + ctx.Phony("checkbuild", PathForPhony(ctx, "bazel_sandwich")) } // Returns a out dir path for a sandboxed mixed build action @@ -1344,7 +1422,7 @@ func intermediatePathForSboxMixedBuildAction(ctx PathContext, statement *bazel.B } // Register bazel-owned build statements (obtained from the aquery invocation). -func createCommand(cmd *RuleBuilderCommand, buildStatement *bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx BuilderContext, depsetHashToDepset map[string]bazel.AqueryDepset) { +func createCommand(cmd *RuleBuilderCommand, buildStatement *bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx BuilderContext, depsetHashToDepset map[string]bazel.AqueryDepset, dotdotsToOutRoot string) { // executionRoot is the action cwd. if buildStatement.ShouldRunInSbox { // mkdir -p ensures that the directory exists when run via sbox @@ -1367,14 +1445,17 @@ func createCommand(cmd *RuleBuilderCommand, buildStatement *bazel.BuildStatement cmd.Flag(pair.Key + "=" + pair.Value) } + command := buildStatement.Command + command = strings.ReplaceAll(command, "{DOTDOTS_TO_OUTPUT_ROOT}", dotdotsToOutRoot) + // The actual Bazel action. - if len(buildStatement.Command) > 16*1024 { + if len(command) > 16*1024 { commandFile := PathForBazelOut(ctx, buildStatement.OutputPaths[0]+".sh") - WriteFileRule(ctx, commandFile, buildStatement.Command) + WriteFileRule(ctx, commandFile, command) cmd.Text("bash").Text(buildStatement.OutputPaths[0] + ".sh").Implicit(commandFile) } else { - cmd.Text(buildStatement.Command) + cmd.Text(command) } for _, outputPath := range buildStatement.OutputPaths { @@ -1403,6 +1484,9 @@ func createCommand(cmd *RuleBuilderCommand, buildStatement *bazel.BuildStatement cmd.Implicit(PathForPhony(ctx, otherDepsetName)) } } + for _, implicitPath := range buildStatement.ImplicitDeps { + cmd.Implicit(PathForArbitraryOutput(ctx, implicitPath)) + } if depfile := buildStatement.Depfile; depfile != nil { // The paths in depfile are relative to `executionRoot`. |