Merge "Reorganize soong_build/main.go ."
This commit is contained in:
commit
c5b3a1722c
|
@ -24,7 +24,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"android/soong/shared"
|
"android/soong/shared"
|
||||||
|
|
||||||
"github.com/google/blueprint/bootstrap"
|
"github.com/google/blueprint/bootstrap"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
@ -65,16 +64,10 @@ func newNameResolver(config android.Config) *android.NameResolver {
|
||||||
return android.NewNameResolver(exportFilter)
|
return android.NewNameResolver(exportFilter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bazelConversionRequested checks that the user is intending to convert
|
func newContext(configuration android.Config, prepareBuildActions bool) *android.Context {
|
||||||
// Blueprint to Bazel BUILD files.
|
|
||||||
func bazelConversionRequested(configuration android.Config) bool {
|
|
||||||
return configuration.IsEnvTrue("GENERATE_BAZEL_FILES")
|
|
||||||
}
|
|
||||||
|
|
||||||
func newContext(configuration android.Config) *android.Context {
|
|
||||||
ctx := android.NewContext(configuration)
|
ctx := android.NewContext(configuration)
|
||||||
ctx.Register()
|
ctx.Register()
|
||||||
if !shouldPrepareBuildActions(configuration) {
|
if !prepareBuildActions {
|
||||||
configuration.SetStopBefore(bootstrap.StopBeforePrepareBuildActions)
|
configuration.SetStopBefore(bootstrap.StopBeforePrepareBuildActions)
|
||||||
}
|
}
|
||||||
ctx.SetNameInterface(newNameResolver(configuration))
|
ctx.SetNameInterface(newNameResolver(configuration))
|
||||||
|
@ -91,6 +84,84 @@ func newConfig(srcDir string) android.Config {
|
||||||
return configuration
|
return configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bazel-enabled mode. Soong runs in two passes.
|
||||||
|
// First pass: Analyze the build tree, but only store all bazel commands
|
||||||
|
// needed to correctly evaluate the tree in the second pass.
|
||||||
|
// TODO(cparsons): Don't output any ninja file, as the second pass will overwrite
|
||||||
|
// the incorrect results from the first pass, and file I/O is expensive.
|
||||||
|
func runMixedModeBuild(configuration android.Config, firstCtx *android.Context, extraNinjaDeps []string) {
|
||||||
|
configuration.SetStopBefore(bootstrap.StopBeforeWriteNinja)
|
||||||
|
bootstrap.Main(firstCtx.Context, configuration, false, extraNinjaDeps...)
|
||||||
|
// Invoke bazel commands and save results for second pass.
|
||||||
|
if err := configuration.BazelContext.InvokeBazel(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// Second pass: Full analysis, using the bazel command results. Output ninja file.
|
||||||
|
secondPassConfig, err := android.ConfigForAdditionalRun(configuration)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
secondCtx := newContext(secondPassConfig, true)
|
||||||
|
bootstrap.Main(secondCtx.Context, secondPassConfig, false, extraNinjaDeps...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the code-generation phase to convert BazelTargetModules to BUILD files.
|
||||||
|
func runQueryView(configuration android.Config, ctx *android.Context) {
|
||||||
|
codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.QueryView)
|
||||||
|
absoluteQueryViewDir := shared.JoinPath(topDir, bazelQueryViewDir)
|
||||||
|
if err := createBazelQueryView(codegenContext, absoluteQueryViewDir); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runSoongDocs(configuration android.Config, extraNinjaDeps []string) {
|
||||||
|
ctx := newContext(configuration, false)
|
||||||
|
bootstrap.Main(ctx.Context, configuration, false, extraNinjaDeps...)
|
||||||
|
if err := writeDocs(ctx, configuration, docFile); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeMetrics(configuration android.Config) {
|
||||||
|
metricsFile := filepath.Join(bootstrap.CmdlineBuildDir(), "soong_build_metrics.pb")
|
||||||
|
err := android.WriteMetrics(configuration, metricsFile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "error writing soong_build metrics %s: %s", metricsFile, err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doChosenActivity(configuration android.Config, extraNinjaDeps []string) {
|
||||||
|
bazelConversionRequested := configuration.IsEnvTrue("GENERATE_BAZEL_FILES")
|
||||||
|
mixedModeBuild := configuration.BazelContext.BazelEnabled()
|
||||||
|
generateQueryView := bazelQueryViewDir != ""
|
||||||
|
|
||||||
|
if bazelConversionRequested {
|
||||||
|
// Run the alternate pipeline of bp2build mutators and singleton to convert
|
||||||
|
// Blueprint to BUILD files before everything else.
|
||||||
|
runBp2Build(configuration, extraNinjaDeps)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := newContext(configuration, !generateQueryView)
|
||||||
|
if mixedModeBuild {
|
||||||
|
runMixedModeBuild(configuration, ctx, extraNinjaDeps)
|
||||||
|
} else {
|
||||||
|
bootstrap.Main(ctx.Context, configuration, false, extraNinjaDeps...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the Soong module graph into Bazel BUILD files.
|
||||||
|
if generateQueryView {
|
||||||
|
runQueryView(configuration, ctx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
writeMetrics(configuration)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
@ -101,7 +172,6 @@ func main() {
|
||||||
usedVariablesFile := shared.JoinPath(outDir, "soong.environment.used")
|
usedVariablesFile := shared.JoinPath(outDir, "soong.environment.used")
|
||||||
// The top-level Blueprints file is passed as the first argument.
|
// The top-level Blueprints file is passed as the first argument.
|
||||||
srcDir := filepath.Dir(flag.Arg(0))
|
srcDir := filepath.Dir(flag.Arg(0))
|
||||||
var ctx *android.Context
|
|
||||||
configuration := newConfig(srcDir)
|
configuration := newConfig(srcDir)
|
||||||
extraNinjaDeps := []string{
|
extraNinjaDeps := []string{
|
||||||
configuration.ProductVariablesFileName,
|
configuration.ProductVariablesFileName,
|
||||||
|
@ -122,72 +192,17 @@ func main() {
|
||||||
extraNinjaDeps = append(extraNinjaDeps, filepath.Join(configuration.BuildDir(), "always_rerun_for_delve"))
|
extraNinjaDeps = append(extraNinjaDeps, filepath.Join(configuration.BuildDir(), "always_rerun_for_delve"))
|
||||||
}
|
}
|
||||||
|
|
||||||
bazelConversionRequested := bazelConversionRequested(configuration)
|
if docFile != "" {
|
||||||
if bazelConversionRequested {
|
// We don't write an used variables file when generating documentation
|
||||||
// Run the alternate pipeline of bp2build mutators and singleton to convert Blueprint to BUILD files
|
// because that is done from within the actual builds as a Ninja action and
|
||||||
// before everything else.
|
// thus it would overwrite the actual used variables file so this is
|
||||||
runBp2Build(srcDir, configuration, extraNinjaDeps)
|
// special-cased.
|
||||||
} else if configuration.BazelContext.BazelEnabled() {
|
runSoongDocs(configuration, extraNinjaDeps)
|
||||||
// Bazel-enabled mode. Soong runs in two passes.
|
return
|
||||||
// First pass: Analyze the build tree, but only store all bazel commands
|
|
||||||
// needed to correctly evaluate the tree in the second pass.
|
|
||||||
// TODO(cparsons): Don't output any ninja file, as the second pass will overwrite
|
|
||||||
// the incorrect results from the first pass, and file I/O is expensive.
|
|
||||||
firstCtx := newContext(configuration)
|
|
||||||
configuration.SetStopBefore(bootstrap.StopBeforeWriteNinja)
|
|
||||||
bootstrap.Main(firstCtx.Context, configuration, false, extraNinjaDeps...)
|
|
||||||
// Invoke bazel commands and save results for second pass.
|
|
||||||
if err := configuration.BazelContext.InvokeBazel(); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
// Second pass: Full analysis, using the bazel command results. Output ninja file.
|
|
||||||
secondPassConfig, err := android.ConfigForAdditionalRun(configuration)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
ctx = newContext(secondPassConfig)
|
|
||||||
bootstrap.Main(ctx.Context, secondPassConfig, false, extraNinjaDeps...)
|
|
||||||
} else {
|
|
||||||
ctx = newContext(configuration)
|
|
||||||
bootstrap.Main(ctx.Context, configuration, false, extraNinjaDeps...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the Soong module graph into Bazel BUILD files.
|
doChosenActivity(configuration, extraNinjaDeps)
|
||||||
if !bazelConversionRequested && bazelQueryViewDir != "" {
|
writeUsedVariablesFile(shared.JoinPath(topDir, usedVariablesFile), configuration)
|
||||||
// Run the code-generation phase to convert BazelTargetModules to BUILD files.
|
|
||||||
codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.QueryView)
|
|
||||||
absoluteQueryViewDir := shared.JoinPath(topDir, bazelQueryViewDir)
|
|
||||||
if err := createBazelQueryView(codegenContext, absoluteQueryViewDir); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bazelConversionRequested && docFile != "" {
|
|
||||||
if err := writeDocs(ctx, configuration, docFile); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "%s", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(ccross): make this a command line argument. Requires plumbing through blueprint
|
|
||||||
// to affect the command line of the primary builder.
|
|
||||||
if !bazelConversionRequested && shouldPrepareBuildActions(configuration) {
|
|
||||||
metricsFile := filepath.Join(bootstrap.CmdlineBuildDir(), "soong_build_metrics.pb")
|
|
||||||
err := android.WriteMetrics(configuration, metricsFile)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "error writing soong_build metrics %s: %s", metricsFile, err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if docFile == "" {
|
|
||||||
// Let's not overwrite the used variables file when generating
|
|
||||||
// documentation
|
|
||||||
writeUsedVariablesFile(shared.JoinPath(topDir, usedVariablesFile), configuration)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeUsedVariablesFile(path string, configuration android.Config) {
|
func writeUsedVariablesFile(path string, configuration android.Config) {
|
||||||
|
@ -218,7 +233,7 @@ func writeUsedVariablesFile(path string, configuration android.Config) {
|
||||||
// Run Soong in the bp2build mode. This creates a standalone context that registers
|
// Run Soong in the bp2build mode. This creates a standalone context that registers
|
||||||
// an alternate pipeline of mutators and singletons specifically for generating
|
// an alternate pipeline of mutators and singletons specifically for generating
|
||||||
// Bazel BUILD files instead of Ninja files.
|
// Bazel BUILD files instead of Ninja files.
|
||||||
func runBp2Build(srcDir string, configuration android.Config, extraNinjaDeps []string) {
|
func runBp2Build(configuration android.Config, extraNinjaDeps []string) {
|
||||||
// Register an alternate set of singletons and mutators for bazel
|
// Register an alternate set of singletons and mutators for bazel
|
||||||
// conversion for Bazel conversion.
|
// conversion for Bazel conversion.
|
||||||
bp2buildCtx := android.NewContext(configuration)
|
bp2buildCtx := android.NewContext(configuration)
|
||||||
|
@ -233,7 +248,7 @@ func runBp2Build(srcDir string, configuration android.Config, extraNinjaDeps []s
|
||||||
// configurations or variables, since those will generate different BUILD
|
// configurations or variables, since those will generate different BUILD
|
||||||
// files based on how the user has configured their tree.
|
// files based on how the user has configured their tree.
|
||||||
bp2buildCtx.SetModuleListFile(bootstrap.CmdlineModuleListFile())
|
bp2buildCtx.SetModuleListFile(bootstrap.CmdlineModuleListFile())
|
||||||
modulePaths, err := bp2buildCtx.ListModulePaths(srcDir)
|
modulePaths, err := bp2buildCtx.ListModulePaths(configuration.SrcDir())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -283,20 +298,3 @@ func runBp2Build(srcDir string, configuration android.Config, extraNinjaDeps []s
|
||||||
[]byte(fmt.Sprintf("%s: \\\n %s\n", ninjaFileName, extraNinjaDepsString)),
|
[]byte(fmt.Sprintf("%s: \\\n %s\n", ninjaFileName, extraNinjaDepsString)),
|
||||||
0666)
|
0666)
|
||||||
}
|
}
|
||||||
|
|
||||||
// shouldPrepareBuildActions reads configuration and flags if build actions
|
|
||||||
// should be generated.
|
|
||||||
func shouldPrepareBuildActions(configuration android.Config) bool {
|
|
||||||
// Generating Soong docs
|
|
||||||
if docFile != "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generating a directory for Soong query (queryview)
|
|
||||||
if bazelQueryViewDir != "" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generating a directory for converted Bazel BUILD files
|
|
||||||
return !bazelConversionRequested(configuration)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue