Preserve depset structure from bazel aquery
Each depset now corresponds to a phony rule which depends on other depsets or on full paths; thus, bazel's depset structure is preserved in the form of phony rules of name bazel_depset_{id}. Previously, flattening and recopying large lists of file path strings was quite inefficient. This was particularly evident as we enumerated hundreds of clang headers for each cc compile action. This reduces soong_build analysis time by about 30% for mixed builds. It also reduces ninja file size by ~750MB. Fixes: 229405615 Test: Unit tests, manually verified metrics, mixed_droid CI Change-Id: I78df152ac1488ae0c6807afdde4b4ad5e6d26287
This commit is contained in:
@@ -28,6 +28,7 @@ import (
|
||||
|
||||
"android/soong/bazel/cquery"
|
||||
"android/soong/shared"
|
||||
"github.com/google/blueprint"
|
||||
|
||||
"android/soong/bazel"
|
||||
)
|
||||
@@ -101,6 +102,9 @@ type BazelContext interface {
|
||||
|
||||
// Returns build statements which should get registered to reflect Bazel's outputs.
|
||||
BuildStatementsToRegister() []bazel.BuildStatement
|
||||
|
||||
// Returns the depsets defined in Bazel's aquery response.
|
||||
AqueryDepsets() []bazel.AqueryDepset
|
||||
}
|
||||
|
||||
type bazelRunner interface {
|
||||
@@ -128,6 +132,9 @@ type bazelContext struct {
|
||||
|
||||
// Build statements which should get registered to reflect Bazel's outputs.
|
||||
buildStatements []bazel.BuildStatement
|
||||
|
||||
// Depsets which should be used for Bazel's build statements.
|
||||
depsets []bazel.AqueryDepset
|
||||
}
|
||||
|
||||
var _ BazelContext = &bazelContext{}
|
||||
@@ -175,6 +182,10 @@ func (m MockBazelContext) BuildStatementsToRegister() []bazel.BuildStatement {
|
||||
return []bazel.BuildStatement{}
|
||||
}
|
||||
|
||||
func (m MockBazelContext) AqueryDepsets() []bazel.AqueryDepset {
|
||||
return []bazel.AqueryDepset{}
|
||||
}
|
||||
|
||||
var _ BazelContext = MockBazelContext{}
|
||||
|
||||
func (bazelCtx *bazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, bool) {
|
||||
@@ -236,6 +247,10 @@ func (m noopBazelContext) BuildStatementsToRegister() []bazel.BuildStatement {
|
||||
return []bazel.BuildStatement{}
|
||||
}
|
||||
|
||||
func (m noopBazelContext) AqueryDepsets() []bazel.AqueryDepset {
|
||||
return []bazel.AqueryDepset{}
|
||||
}
|
||||
|
||||
func NewBazelContext(c *config) (BazelContext, error) {
|
||||
// TODO(cparsons): Assess USE_BAZEL=1 instead once "mixed Soong/Bazel builds"
|
||||
// are production ready.
|
||||
@@ -746,7 +761,7 @@ func (context *bazelContext) InvokeBazel() error {
|
||||
return err
|
||||
}
|
||||
|
||||
context.buildStatements, err = bazel.AqueryBuildStatements([]byte(aqueryOutput))
|
||||
context.buildStatements, context.depsets, err = bazel.AqueryBuildStatements([]byte(aqueryOutput))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -772,6 +787,10 @@ func (context *bazelContext) BuildStatementsToRegister() []bazel.BuildStatement
|
||||
return context.buildStatements
|
||||
}
|
||||
|
||||
func (context *bazelContext) AqueryDepsets() []bazel.AqueryDepset {
|
||||
return context.depsets
|
||||
}
|
||||
|
||||
func (context *bazelContext) OutputBase() string {
|
||||
return context.paths.outputBase
|
||||
}
|
||||
@@ -804,6 +823,23 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
|
||||
ctx.AddNinjaFileDeps(file)
|
||||
}
|
||||
|
||||
for _, depset := range ctx.Config().BazelContext.AqueryDepsets() {
|
||||
var outputs []Path
|
||||
for _, depsetDepId := range depset.TransitiveDepSetIds {
|
||||
otherDepsetName := bazelDepsetName(depsetDepId)
|
||||
outputs = append(outputs, PathForPhony(ctx, otherDepsetName))
|
||||
}
|
||||
for _, artifactPath := range depset.DirectArtifacts {
|
||||
outputs = append(outputs, PathForBazelOut(ctx, artifactPath))
|
||||
}
|
||||
thisDepsetName := bazelDepsetName(depset.Id)
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Outputs: []WritablePath{PathForPhony(ctx, thisDepsetName)},
|
||||
Implicits: outputs,
|
||||
})
|
||||
}
|
||||
|
||||
// Register bazel-owned build statements (obtained from the aquery invocation).
|
||||
for index, buildStatement := range ctx.Config().BazelContext.BuildStatementsToRegister() {
|
||||
if len(buildStatement.Command) < 1 {
|
||||
@@ -838,6 +874,10 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
|
||||
for _, inputPath := range buildStatement.InputPaths {
|
||||
cmd.Implicit(PathForBazelOut(ctx, inputPath))
|
||||
}
|
||||
for _, inputDepsetId := range buildStatement.InputDepsetIds {
|
||||
otherDepsetName := bazelDepsetName(inputDepsetId)
|
||||
cmd.Implicit(PathForPhony(ctx, otherDepsetName))
|
||||
}
|
||||
|
||||
if depfile := buildStatement.Depfile; depfile != nil {
|
||||
cmd.ImplicitDepFile(PathForBazelOut(ctx, *depfile))
|
||||
@@ -882,3 +922,7 @@ func GetConfigKey(ctx ModuleContext) configKey {
|
||||
osType: ctx.Os(),
|
||||
}
|
||||
}
|
||||
|
||||
func bazelDepsetName(depsetId int) string {
|
||||
return fmt.Sprintf("bazel_depset_%d", depsetId)
|
||||
}
|
||||
|
Reference in New Issue
Block a user