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 bp2build 16 17import ( 18 "android/soong/android" 19 "fmt" 20 "os" 21) 22 23// Codegen is the backend of bp2build. The code generator is responsible for 24// writing .bzl files that are equivalent to Android.bp files that are capable 25// of being built with Bazel. 26func Codegen(ctx *CodegenContext) CodegenMetrics { 27 // This directory stores BUILD files that could be eventually checked-in. 28 bp2buildDir := android.PathForOutput(ctx, "bp2build") 29 android.RemoveAllOutputDir(bp2buildDir) 30 31 buildToTargets, metrics := GenerateBazelTargets(ctx, true) 32 bp2buildFiles := CreateBazelFiles(nil, buildToTargets, ctx.mode) 33 writeFiles(ctx, bp2buildDir, bp2buildFiles) 34 35 soongInjectionDir := android.PathForOutput(ctx, "soong_injection") 36 writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles()) 37 38 return metrics 39} 40 41// Get the output directory and create it if it doesn't exist. 42func getOrCreateOutputDir(outputDir android.OutputPath, ctx android.PathContext, dir string) android.OutputPath { 43 dirPath := outputDir.Join(ctx, dir) 44 android.CreateOutputDirIfNonexistent(dirPath, os.ModePerm) 45 return dirPath 46} 47 48// writeFiles materializes a list of BazelFile rooted at outputDir. 49func writeFiles(ctx android.PathContext, outputDir android.OutputPath, files []BazelFile) { 50 for _, f := range files { 51 p := getOrCreateOutputDir(outputDir, ctx, f.Dir).Join(ctx, f.Basename) 52 if err := writeFile(ctx, p, f.Contents); err != nil { 53 panic(fmt.Errorf("Failed to write %q (dir %q) due to %q", f.Basename, f.Dir, err)) 54 } 55 } 56} 57 58func writeFile(ctx android.PathContext, pathToFile android.OutputPath, content string) error { 59 // These files are made editable to allow users to modify and iterate on them 60 // in the source tree. 61 return android.WriteFileToOutputDir(pathToFile, []byte(content), 0644) 62} 63