Create a new mode in soong_ui to generate API only BUILD files
The generated Bazel workspace will only contain api specific targets. This is feasible since these targets do not have any cross dependencies with the targets in the bp2build workspace The advantages of a new mode are 1. Does not pollute bp2build workspace with api targets 2. Does not block api targets with the current allowlist conversion mechansims in bp2build (In the future we might want to combine these two workspaces) A Soong module type will generate a Bazel target if it implements ApiProvider interface Test: m apigen Test: m nothing Change-Id: I69c57ca6539f932e0ad554ce84a87fb7936fdba0
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"time"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/bazel"
|
||||
"android/soong/bp2build"
|
||||
"android/soong/shared"
|
||||
"android/soong/ui/metrics/bp2build_metrics_proto"
|
||||
@@ -48,11 +49,12 @@ var (
|
||||
delveListen string
|
||||
delvePath string
|
||||
|
||||
moduleGraphFile string
|
||||
moduleActionsFile string
|
||||
docFile string
|
||||
bazelQueryViewDir string
|
||||
bp2buildMarker string
|
||||
moduleGraphFile string
|
||||
moduleActionsFile string
|
||||
docFile string
|
||||
bazelQueryViewDir string
|
||||
bazelApiBp2buildDir string
|
||||
bp2buildMarker string
|
||||
|
||||
cmdlineArgs bootstrap.Args
|
||||
)
|
||||
@@ -81,6 +83,7 @@ func init() {
|
||||
flag.StringVar(&moduleActionsFile, "module_actions_file", "", "JSON file to output inputs/outputs of actions of modules")
|
||||
flag.StringVar(&docFile, "soong_docs", "", "build documentation file to output")
|
||||
flag.StringVar(&bazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory relative to --top")
|
||||
flag.StringVar(&bazelApiBp2buildDir, "bazel_api_bp2build_dir", "", "path to the bazel api_bp2build directory relative to --top")
|
||||
flag.StringVar(&bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
|
||||
flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
|
||||
flag.BoolVar(&cmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
|
||||
@@ -129,6 +132,8 @@ func newConfig(availableEnv map[string]string) android.Config {
|
||||
buildMode = android.Bp2build
|
||||
} else if bazelQueryViewDir != "" {
|
||||
buildMode = android.GenerateQueryView
|
||||
} else if bazelApiBp2buildDir != "" {
|
||||
buildMode = android.ApiBp2build
|
||||
} else if moduleGraphFile != "" {
|
||||
buildMode = android.GenerateModuleGraph
|
||||
} else if docFile != "" {
|
||||
@@ -178,7 +183,7 @@ func runQueryView(queryviewDir, queryviewMarker string, configuration android.Co
|
||||
defer ctx.EventHandler.End("queryview")
|
||||
codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.QueryView)
|
||||
absoluteQueryViewDir := shared.JoinPath(topDir, queryviewDir)
|
||||
if err := createBazelQueryView(codegenContext, absoluteQueryViewDir); err != nil {
|
||||
if err := createBazelWorkspace(codegenContext, absoluteQueryViewDir); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -186,6 +191,96 @@ func runQueryView(queryviewDir, queryviewMarker string, configuration android.Co
|
||||
touch(shared.JoinPath(topDir, queryviewMarker))
|
||||
}
|
||||
|
||||
// Run the code-generation phase to convert API contributions to BUILD files.
|
||||
// Return marker file for the new synthetic workspace
|
||||
func runApiBp2build(configuration android.Config, extraNinjaDeps []string) string {
|
||||
// Create a new context and register mutators that are only meaningful to API export
|
||||
ctx := android.NewContext(configuration)
|
||||
ctx.EventHandler.Begin("api_bp2build")
|
||||
defer ctx.EventHandler.End("api_bp2build")
|
||||
ctx.SetNameInterface(newNameResolver(configuration))
|
||||
ctx.RegisterForApiBazelConversion()
|
||||
|
||||
// Register the Android.bp files in the tree
|
||||
// Add them to the workspace's .d file
|
||||
ctx.SetModuleListFile(cmdlineArgs.ModuleListFile)
|
||||
if paths, err := ctx.ListModulePaths("."); err == nil {
|
||||
extraNinjaDeps = append(extraNinjaDeps, paths...)
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Run the loading and analysis phase
|
||||
ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs,
|
||||
bootstrap.StopBeforePrepareBuildActions,
|
||||
ctx.Context,
|
||||
configuration)
|
||||
ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
|
||||
|
||||
// Add the globbed dependencies
|
||||
globs := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
|
||||
ninjaDeps = append(ninjaDeps, globs...)
|
||||
|
||||
// Run codegen to generate BUILD files
|
||||
codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.ApiBp2build)
|
||||
absoluteApiBp2buildDir := shared.JoinPath(topDir, bazelApiBp2buildDir)
|
||||
if err := createBazelWorkspace(codegenContext, absoluteApiBp2buildDir); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
|
||||
|
||||
// Create soong_injection repository
|
||||
soongInjectionFiles := bp2build.CreateSoongInjectionFiles(configuration, bp2build.CodegenMetrics{})
|
||||
absoluteSoongInjectionDir := shared.JoinPath(topDir, configuration.SoongOutDir(), bazel.SoongInjectionDirName)
|
||||
for _, file := range soongInjectionFiles {
|
||||
writeReadOnlyFile(absoluteSoongInjectionDir, file)
|
||||
}
|
||||
|
||||
workspace := shared.JoinPath(configuration.SoongOutDir(), "api_bp2build")
|
||||
|
||||
excludes := bazelArtifacts()
|
||||
// Exclude all src BUILD files
|
||||
excludes = append(excludes, apiBuildFileExcludes()...)
|
||||
|
||||
// Create the symlink forest
|
||||
symlinkDeps := bp2build.PlantSymlinkForest(
|
||||
configuration,
|
||||
topDir,
|
||||
workspace,
|
||||
bazelApiBp2buildDir,
|
||||
".",
|
||||
excludes)
|
||||
ninjaDeps = append(ninjaDeps, symlinkDeps...)
|
||||
|
||||
workspaceMarkerFile := workspace + ".marker"
|
||||
writeDepFile(workspaceMarkerFile, *ctx.EventHandler, ninjaDeps)
|
||||
touch(shared.JoinPath(topDir, workspaceMarkerFile))
|
||||
return workspaceMarkerFile
|
||||
}
|
||||
|
||||
// With some exceptions, api_bp2build does not have any dependencies on the checked-in BUILD files
|
||||
// Exclude them from the generated workspace to prevent unrelated errors during the loading phase
|
||||
func apiBuildFileExcludes() []string {
|
||||
ret := make([]string, 0)
|
||||
|
||||
srcs, err := getExistingBazelRelatedFiles(topDir)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error determining existing Bazel-related files: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, src := range srcs {
|
||||
if src != "WORKSPACE" &&
|
||||
src != "BUILD" &&
|
||||
src != "BUILD.bazel" &&
|
||||
!strings.HasPrefix(src, "build/bazel") &&
|
||||
!strings.HasPrefix(src, "prebuilts/clang") {
|
||||
ret = append(ret, src)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func writeMetrics(configuration android.Config, eventHandler metrics.EventHandler, metricsDir string) {
|
||||
if len(metricsDir) < 1 {
|
||||
fmt.Fprintf(os.Stderr, "\nMissing required env var for generating soong metrics: LOG_DIR\n")
|
||||
@@ -248,6 +343,8 @@ func doChosenActivity(ctx *android.Context, configuration android.Config, extraN
|
||||
return bp2buildMarker
|
||||
} else if configuration.IsMixedBuildsEnabled() {
|
||||
runMixedModeBuild(configuration, ctx, extraNinjaDeps)
|
||||
} else if configuration.BuildMode == android.ApiBp2build {
|
||||
return runApiBp2build(configuration, extraNinjaDeps)
|
||||
} else {
|
||||
var stopBefore bootstrap.StopBefore
|
||||
if configuration.BuildMode == android.GenerateModuleGraph {
|
||||
@@ -476,6 +573,16 @@ func getExistingBazelRelatedFiles(topDir string) ([]string, error) {
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func bazelArtifacts() []string {
|
||||
return []string{
|
||||
"bazel-bin",
|
||||
"bazel-genfiles",
|
||||
"bazel-out",
|
||||
"bazel-testlogs",
|
||||
"bazel-" + filepath.Base(topDir),
|
||||
}
|
||||
}
|
||||
|
||||
// Run Soong in the bp2build mode. This creates a standalone context that registers
|
||||
// an alternate pipeline of mutators and singletons specifically for generating
|
||||
// Bazel BUILD files instead of Ninja files.
|
||||
@@ -524,13 +631,7 @@ func runBp2Build(configuration android.Config, extraNinjaDeps []string) {
|
||||
generatedRoot := shared.JoinPath(configuration.SoongOutDir(), "bp2build")
|
||||
workspaceRoot := shared.JoinPath(configuration.SoongOutDir(), "workspace")
|
||||
|
||||
excludes := []string{
|
||||
"bazel-bin",
|
||||
"bazel-genfiles",
|
||||
"bazel-out",
|
||||
"bazel-testlogs",
|
||||
"bazel-" + filepath.Base(topDir),
|
||||
}
|
||||
excludes := bazelArtifacts()
|
||||
|
||||
if outDir[0] != '/' {
|
||||
excludes = append(excludes, outDir)
|
||||
|
Reference in New Issue
Block a user