Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 946e0b69 authored by Jingwen Chen's avatar Jingwen Chen Committed by Gerrit Code Review
Browse files

Merge "Add bp2build mode to soong_build."

parents 0ec64e5d 4133ce69
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -44,6 +44,11 @@ func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
	}
}

func registerMutatorsForBazelConversion(ctx *blueprint.Context) {
	// FIXME(b/171263886): Start bringing in mutators to make the Bionic
	// module subgraph suitable for automated conversion.
}

func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
	mctx := &registerMutatorsContext{}

+40 −6
Original line number Diff line number Diff line
@@ -26,15 +26,40 @@ import (
// for calling the soong_build primary builder in the main build.ninja file.
func init() {
	RegisterSingletonType("bazel_queryview", BazelQueryViewSingleton)
	RegisterSingletonType("bazel_converter", BazelConverterSingleton)
}

// BazelQueryViewSingleton is the singleton responsible for registering the
// soong_build build statement that will convert the Soong module graph after
// applying *all* mutators, enabing the feature to query the final state of the
// Soong graph. This mode is meant for querying the build graph state, and not meant
// for generating BUILD files to be checked in.
func BazelQueryViewSingleton() Singleton {
	return &bazelQueryViewSingleton{}
}

// BazelConverterSingleton is the singleton responsible for registering the soong_build
// build statement that will convert the Soong module graph by applying an alternate
// pipeline of mutators, with the goal of reaching semantic equivalence between the original
// Blueprint and final BUILD files. Using this mode, the goal is to be able to
// build with these BUILD files directly in the source tree.
func BazelConverterSingleton() Singleton {
	return &bazelConverterSingleton{}
}

type bazelQueryViewSingleton struct{}
type bazelConverterSingleton struct{}

func generateBuildActionsForBazelConversion(ctx SingletonContext, converterMode bool) {
	name := "queryview"
	additionalEnvVars := ""
	descriptionTemplate := "[EXPERIMENTAL, PRE-PRODUCTION] Creating the Bazel QueryView workspace with %s at $outDir"
	if converterMode {
		name = "bp2build"
		additionalEnvVars = "CONVERT_TO_BAZEL=true"
		descriptionTemplate = "[EXPERIMENTAL, PRE-PRODUCTION] Converting all Android.bp to Bazel BUILD files with %s at $outDir"
	}

func (c *bazelQueryViewSingleton) GenerateBuildActions(ctx SingletonContext) {
	// Create a build and rule statement, using the Bazel QueryView's WORKSPACE
	// file as the output file marker.
	var deps Paths
@@ -42,22 +67,23 @@ func (c *bazelQueryViewSingleton) GenerateBuildActions(ctx SingletonContext) {
	deps = append(deps, moduleListFilePath)
	deps = append(deps, pathForBuildToolDep(ctx, ctx.Config().ProductVariablesFileName))

	bazelQueryViewDirectory := PathForOutput(ctx, "queryview")
	bazelQueryViewDirectory := PathForOutput(ctx, name)
	bazelQueryViewWorkspaceFile := bazelQueryViewDirectory.Join(ctx, "WORKSPACE")
	primaryBuilder := primaryBuilderPath(ctx)
	bazelQueryView := ctx.Rule(pctx, "bazelQueryView",
		blueprint.RuleParams{
			Command: fmt.Sprintf(
				"rm -rf ${outDir}/* && "+
					"%s --bazel_queryview_dir ${outDir} %s && "+
					"%s %s --bazel_queryview_dir ${outDir} %s && "+
					"echo WORKSPACE: `cat %s` > ${outDir}/.queryview-depfile.d",
				additionalEnvVars,
				primaryBuilder.String(),
				strings.Join(os.Args[1:], " "),
				moduleListFilePath.String(), // Use the contents of Android.bp.list as the depfile.
			),
			CommandDeps: []string{primaryBuilder.String()},
			Description: fmt.Sprintf(
				"[EXPERIMENTAL, PRE-PRODUCTION] Creating the Bazel QueryView workspace with %s at $outDir",
				descriptionTemplate,
				primaryBuilder.Base()),
			Deps:    blueprint.DepsGCC,
			Depfile: "${outDir}/.queryview-depfile.d",
@@ -73,6 +99,14 @@ func (c *bazelQueryViewSingleton) GenerateBuildActions(ctx SingletonContext) {
		},
	})

	// Add a phony target for building the Bazel QueryView
	ctx.Phony("queryview", bazelQueryViewWorkspaceFile)
	// Add a phony target for generating the workspace
	ctx.Phony(name, bazelQueryViewWorkspaceFile)
}

func (c *bazelQueryViewSingleton) GenerateBuildActions(ctx SingletonContext) {
	generateBuildActionsForBazelConversion(ctx, false)
}

func (c *bazelConverterSingleton) GenerateBuildActions(ctx SingletonContext) {
	generateBuildActionsForBazelConversion(ctx, true)
}
+15 −0
Original line number Diff line number Diff line
@@ -90,6 +90,21 @@ func NewContext(config Config) *Context {
	return ctx
}

// RegisterForBazelConversion registers an alternate shadow pipeline of
// singletons, module types and mutators to register for converting Blueprint
// files to semantically equivalent BUILD files.
func (ctx *Context) RegisterForBazelConversion() {
	for _, t := range moduleTypes {
		ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
	}

	bazelConverterSingleton := singleton{"bp2build", BazelConverterSingleton}
	ctx.RegisterSingletonType(bazelConverterSingleton.name,
		SingletonFactoryAdaptor(ctx, bazelConverterSingleton.factory))

	registerMutatorsForBazelConversion(ctx.Context)
}

func (ctx *Context) Register() {
	for _, t := range preSingletons {
		ctx.RegisterPreSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
+32 −7
Original line number Diff line number Diff line
@@ -51,10 +51,22 @@ func newNameResolver(config android.Config) *android.NameResolver {
	return android.NewNameResolver(exportFilter)
}

// bazelConversionRequested checks that the user is intending to convert
// Blueprint to Bazel BUILD files.
func bazelConversionRequested(configuration android.Config) bool {
	return configuration.IsEnvTrue("CONVERT_TO_BAZEL")
}

func newContext(srcDir string, configuration android.Config) *android.Context {
	ctx := android.NewContext(configuration)
	if bazelConversionRequested(configuration) {
		// Register an alternate set of singletons and mutators for bazel
		// conversion for Bazel conversion.
		ctx.RegisterForBazelConversion()
	} else {
		ctx.Register()
	if !shouldPrepareBuildActions() {
	}
	if !shouldPrepareBuildActions(configuration) {
		configuration.SetStopBefore(bootstrap.StopBeforePrepareBuildActions)
	}
	ctx.SetNameInterface(newNameResolver(configuration))
@@ -114,6 +126,8 @@ func main() {
		ctx = newContext(srcDir, configuration)
		bootstrap.Main(ctx.Context, configuration, extraNinjaDeps...)
	}

	// Convert the Soong module graph into Bazel BUILD files.
	if bazelQueryViewDir != "" {
		if err := createBazelQueryView(ctx, bazelQueryViewDir); err != nil {
			fmt.Fprintf(os.Stderr, "%s", err)
@@ -130,7 +144,7 @@ func main() {

	// TODO(ccross): make this a command line argument.  Requires plumbing through blueprint
	//  to affect the command line of the primary builder.
	if shouldPrepareBuildActions() {
	if shouldPrepareBuildActions(configuration) {
		metricsFile := filepath.Join(bootstrap.BuildDir, "soong_build_metrics.pb")
		err := android.WriteMetrics(configuration, metricsFile)
		if err != nil {
@@ -140,8 +154,19 @@ func main() {
	}
}

func shouldPrepareBuildActions() bool {
	// If we're writing soong_docs or queryview, don't write build.ninja or
	// collect metrics.
	return docFile == "" && bazelQueryViewDir == ""
// 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)
}