mixed build targets need transitive tidy files

Previously in mixed builds, only the tidy files for the boundary module
were built, whereas all of its transitive dependencies' tidy files were
not being built. Instead we should export the list of transitive tidy
files for a module so that we can run clang-tidy for the boundary module
as well as its dependencies.

Bug: 195029134
Test: WITH_TIDY=1 DISABLE_ARTIFACT_PATH_REQUIREMENTS=true mss tidy-packages-modules-NeuralNetworks --bazel-mode-dev
Change-Id: I463646d2ae1fc4aa075a54c264e1c34571c3fd5c
This commit is contained in:
Sam Delmerico
2023-02-03 18:12:15 -05:00
parent cb3c52c766
commit 4ed95e263f
13 changed files with 318 additions and 24 deletions

View File

@@ -588,7 +588,11 @@ func (handler *ccBinaryBazelHandler) ProcessBazelQueryResponse(ctx android.Modul
return
}
outputFilePath := android.PathForBazelOut(ctx, info.OutputFile)
var outputFilePath android.Path = android.PathForBazelOut(ctx, info.OutputFile)
if len(info.TidyFiles) > 0 {
handler.module.tidyFiles = android.PathsForBazelOut(ctx, info.TidyFiles)
outputFilePath = android.AttachValidationActions(ctx, outputFilePath, handler.module.tidyFiles)
}
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
handler.module.linker.(*binaryDecorator).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput)

View File

@@ -55,6 +55,47 @@ cc_binary {
android.AssertStringEquals(t, "Unstripped output file", expectedUnStrippedFile, unStrippedFilePath.String())
}
func TestCcBinaryWithBazelValidations(t *testing.T) {
t.Parallel()
bp := `
cc_binary {
name: "foo",
srcs: ["foo.cc"],
bazel_module: { label: "//foo/bar:bar" },
tidy: true,
}`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.BazelContext = android.MockBazelContext{
OutputBaseDir: "outputbase",
LabelToCcBinary: map[string]cquery.CcUnstrippedInfo{
"//foo/bar:bar": cquery.CcUnstrippedInfo{
OutputFile: "foo",
UnstrippedOutput: "foo.unstripped",
TidyFiles: []string{"foo.c.tidy"},
},
},
}
ctx := android.GroupFixturePreparers(
prepareForCcTest,
android.FixtureMergeEnv(map[string]string{
"ALLOW_LOCAL_TIDY_TRUE": "1",
}),
).RunTestWithConfig(t, config).TestContext
binMod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module()
producer := binMod.(android.OutputFileProducer)
outputFiles, err := producer.OutputFiles("")
if err != nil {
t.Errorf("Unexpected error getting cc_binary outputfiles %s", err)
}
expectedOutputFiles := []string{"out/soong/.intermediates/foo/android_arm64_armv8-a/validated/foo"}
android.AssertPathsRelativeToTopEquals(t, "output files", expectedOutputFiles, outputFiles)
unStrippedFilePath := binMod.(*Module).UnstrippedOutputFile()
expectedUnStrippedFile := "outputbase/execroot/__main__/foo.unstripped"
android.AssertStringEquals(t, "Unstripped output file", expectedUnStrippedFile, unStrippedFilePath.String())
}
func TestBinaryLinkerScripts(t *testing.T) {
t.Parallel()
result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `

View File

@@ -1888,12 +1888,6 @@ func (c *Module) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
func (c *Module) ProcessBazelQueryResponse(ctx android.ModuleContext) {
bazelModuleLabel := c.getBazelModuleLabel(ctx)
bazelCtx := ctx.Config().BazelContext
if ccInfo, err := bazelCtx.GetCcInfo(bazelModuleLabel, android.GetConfigKey(ctx)); err == nil {
c.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
}
c.bazelHandler.ProcessBazelQueryResponse(ctx, bazelModuleLabel)
c.Properties.SubName = GetSubnameProperty(ctx, c)

View File

@@ -845,7 +845,11 @@ func (handler *ccLibraryBazelHandler) generateStaticBazelBuildActions(ctx androi
ctx.ModuleErrorf("expected exactly one root archive file for '%s', but got %s", label, rootStaticArchives)
return
}
outputFilePath := android.PathForBazelOut(ctx, rootStaticArchives[0])
var outputFilePath android.Path = android.PathForBazelOut(ctx, rootStaticArchives[0])
if len(ccInfo.TidyFiles) > 0 {
handler.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
outputFilePath = android.AttachValidationActions(ctx, outputFilePath, handler.module.tidyFiles)
}
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
objPaths := ccInfo.CcObjectFiles
@@ -881,9 +885,13 @@ func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx androi
ctx.ModuleErrorf("expected exactly one root dynamic library file for '%s', but got %s", label, rootDynamicLibraries)
return
}
outputFilePath := android.PathForBazelOut(ctx, rootDynamicLibraries[0])
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
var outputFilePath android.Path = android.PathForBazelOut(ctx, rootDynamicLibraries[0])
if len(ccInfo.TidyFiles) > 0 {
handler.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
outputFilePath = android.AttachValidationActions(ctx, outputFilePath, handler.module.tidyFiles)
}
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
handler.module.linker.(*libraryDecorator).unstrippedOutputFile = android.PathForBazelOut(ctx, ccInfo.UnstrippedOutput)
var tocFile android.OptionalPath

View File

@@ -76,7 +76,11 @@ func (h *libraryHeaderBazelHandler) ProcessBazelQueryResponse(ctx android.Module
return
}
outputPath := android.PathForBazelOut(ctx, outputPaths[0])
var outputPath android.Path = android.PathForBazelOut(ctx, outputPaths[0])
if len(ccInfo.TidyFiles) > 0 {
h.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
outputPath = android.AttachValidationActions(ctx, outputPath, h.module.tidyFiles)
}
h.module.outputFile = android.OptionalPathForPath(outputPath)
// HeaderLibraryInfo is an empty struct to indicate to dependencies that this is a header library

View File

@@ -308,6 +308,75 @@ cc_library {
android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps)
}
func TestCcLibraryWithBazelValidations(t *testing.T) {
t.Parallel()
bp := `
cc_library {
name: "foo",
srcs: ["foo.cc"],
bazel_module: { label: "//foo/bar:bar" },
tidy: true,
}`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.BazelContext = android.MockBazelContext{
OutputBaseDir: "outputbase",
LabelToCcInfo: map[string]cquery.CcInfo{
"//foo/bar:bar": cquery.CcInfo{
CcObjectFiles: []string{"foo.o"},
Includes: []string{"include"},
SystemIncludes: []string{"system_include"},
Headers: []string{"foo.h"},
RootDynamicLibraries: []string{"foo.so"},
UnstrippedOutput: "foo_unstripped.so",
},
"//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{
CcObjectFiles: []string{"foo.o"},
Includes: []string{"include"},
SystemIncludes: []string{"system_include"},
Headers: []string{"foo.h"},
RootStaticArchives: []string{"foo.a"},
TidyFiles: []string{"foo.c.tidy"},
},
},
}
ctx := android.GroupFixturePreparers(
prepareForCcTest,
android.FixtureMergeEnv(map[string]string{
"ALLOW_LOCAL_TIDY_TRUE": "1",
}),
).RunTestWithConfig(t, config).TestContext
staticFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
outputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
if err != nil {
t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
}
expectedOutputFiles := []string{"out/soong/.intermediates/foo/android_arm_armv7-a-neon_static/validated/foo.a"}
android.AssertPathsRelativeToTopEquals(t, "output files", expectedOutputFiles, outputFiles)
flagExporter := ctx.ModuleProvider(staticFoo, FlagExporterInfoProvider).(FlagExporterInfo)
android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs)
android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs)
android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders)
android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps)
sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
outputFiles, err = sharedFoo.(android.OutputFileProducer).OutputFiles("")
if err != nil {
t.Errorf("Unexpected error getting cc_library outputfiles %s", err)
}
expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"}
android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
android.AssertStringEquals(t, "unstripped shared library", "outputbase/execroot/__main__/foo_unstripped.so", sharedFoo.(*Module).linker.unstrippedOutputFilePath().String())
flagExporter = ctx.ModuleProvider(sharedFoo, FlagExporterInfoProvider).(FlagExporterInfo)
android.AssertPathsRelativeToTopEquals(t, "exported include dirs", []string{"outputbase/execroot/__main__/include"}, flagExporter.IncludeDirs)
android.AssertPathsRelativeToTopEquals(t, "exported system include dirs", []string{"outputbase/execroot/__main__/system_include"}, flagExporter.SystemIncludeDirs)
android.AssertPathsRelativeToTopEquals(t, "exported headers", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.GeneratedHeaders)
android.AssertPathsRelativeToTopEquals(t, "deps", []string{"outputbase/execroot/__main__/foo.h"}, flagExporter.Deps)
}
func TestLibraryVersionScript(t *testing.T) {
t.Parallel()
result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
@@ -344,6 +413,59 @@ func TestLibraryDynamicList(t *testing.T) {
}
func TestCcLibrarySharedWithBazelValidations(t *testing.T) {
t.Parallel()
bp := `
cc_library_shared {
name: "foo",
srcs: ["foo.cc"],
bazel_module: { label: "//foo/bar:bar" },
tidy: true,
}`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.BazelContext = android.MockBazelContext{
OutputBaseDir: "outputbase",
LabelToCcInfo: map[string]cquery.CcInfo{
"//foo/bar:bar": cquery.CcInfo{
CcObjectFiles: []string{"foo.o"},
Includes: []string{"include"},
SystemIncludes: []string{"system_include"},
RootDynamicLibraries: []string{"foo.so"},
TocFile: "foo.so.toc",
TidyFiles: []string{"foo.c.tidy"},
},
},
}
ctx := android.GroupFixturePreparers(
prepareForCcTest,
android.FixtureMergeEnv(map[string]string{
"ALLOW_LOCAL_TIDY_TRUE": "1",
}),
).RunTestWithConfig(t, config).TestContext
sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
producer := sharedFoo.(android.OutputFileProducer)
outputFiles, err := producer.OutputFiles("")
if err != nil {
t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
}
expectedOutputFiles := []string{"out/soong/.intermediates/foo/android_arm_armv7-a-neon_shared/validated/foo.so"}
android.AssertPathsRelativeToTopEquals(t, "output files", expectedOutputFiles, outputFiles)
tocFilePath := sharedFoo.(*Module).Toc()
if !tocFilePath.Valid() {
t.Errorf("Invalid tocFilePath: %s", tocFilePath)
}
tocFile := tocFilePath.Path()
expectedToc := "outputbase/execroot/__main__/foo.so.toc"
android.AssertStringEquals(t, "toc file", expectedToc, tocFile.String())
entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0]
expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
}
func TestCcLibrarySharedWithBazel(t *testing.T) {
t.Parallel()
bp := `

View File

@@ -488,13 +488,17 @@ func (h *prebuiltLibraryBazelHandler) processStaticBazelQueryResponse(ctx androi
return true
}
out := android.PathForBazelOut(ctx, staticLibs[0])
h.module.outputFile = android.OptionalPathForPath(out)
var outputPath android.Path = android.PathForBazelOut(ctx, staticLibs[0])
if len(ccInfo.TidyFiles) > 0 {
h.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
outputPath = android.AttachValidationActions(ctx, outputPath, h.module.tidyFiles)
}
depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(out).Build()
h.module.outputFile = android.OptionalPathForPath(outputPath)
depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(outputPath).Build()
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
StaticLibrary: out,
StaticLibrary: outputPath,
TransitiveStaticLibrariesForOrdering: depSet,
})
@@ -518,21 +522,26 @@ func (h *prebuiltLibraryBazelHandler) processSharedBazelQueryResponse(ctx androi
return true
}
out := android.PathForBazelOut(ctx, sharedLibs[0])
h.module.outputFile = android.OptionalPathForPath(out)
var outputPath android.Path = android.PathForBazelOut(ctx, sharedLibs[0])
if len(ccInfo.TidyFiles) > 0 {
h.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
outputPath = android.AttachValidationActions(ctx, outputPath, h.module.tidyFiles)
}
h.module.outputFile = android.OptionalPathForPath(outputPath)
// FIXME(b/214600441): We don't yet strip prebuilt shared libraries
h.library.unstrippedOutputFile = out
h.library.unstrippedOutputFile = outputPath
var toc android.Path
if len(ccInfo.TocFile) > 0 {
toc = android.PathForBazelOut(ctx, ccInfo.TocFile)
} else {
toc = out // Just reuse `out` so ninja still gets an input but won't matter
toc = outputPath // Just reuse `out` so ninja still gets an input but won't matter
}
info := SharedLibraryInfo{
SharedLibrary: out,
SharedLibrary: outputPath,
TableOfContents: android.OptionalPathForPath(toc),
Target: ctx.Target(),
}

View File

@@ -443,6 +443,75 @@ cc_prebuilt_library {
expectedStaticOutputFiles, staticOutputFiles.Strings())
}
func TestPrebuiltLibraryWithBazelValidations(t *testing.T) {
const bp = `
cc_prebuilt_library {
name: "foo",
shared: {
srcs: ["foo.so"],
},
static: {
srcs: ["foo.a"],
},
bazel_module: { label: "//foo/bar:bar" },
tidy: true,
}`
outBaseDir := "outputbase"
result := android.GroupFixturePreparers(
prepareForPrebuiltTest,
android.FixtureMergeEnv(map[string]string{
"ALLOW_LOCAL_TIDY_TRUE": "1",
}),
android.FixtureModifyConfig(func(config android.Config) {
config.BazelContext = android.MockBazelContext{
OutputBaseDir: outBaseDir,
LabelToCcInfo: map[string]cquery.CcInfo{
"//foo/bar:bar": cquery.CcInfo{
CcSharedLibraryFiles: []string{"foo.so"},
TidyFiles: []string{"foo.c.tidy"},
},
"//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{
CcStaticLibraryFiles: []string{"foo.a"},
TidyFiles: []string{"foo.c.tidy"},
},
},
}
}),
).RunTestWithBp(t, bp)
sharedFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
expectedOutputFile := "out/soong/.intermediates/foo/android_arm_armv7-a-neon_shared/validated/foo.so"
sharedInfo := result.ModuleProvider(sharedFoo, SharedLibraryInfoProvider).(SharedLibraryInfo)
android.AssertPathRelativeToTopEquals(t,
"prebuilt library shared target path did not exist or did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
expectedOutputFile, sharedInfo.SharedLibrary)
outputFiles, err := sharedFoo.(android.OutputFileProducer).OutputFiles("")
if err != nil {
t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
}
expectedOutputFiles := []string{expectedOutputFile}
android.AssertPathsRelativeToTopEquals(t,
"prebuilt library shared target output files did not match expected.",
expectedOutputFiles, outputFiles)
staticFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
staticInfo := result.ModuleProvider(staticFoo, StaticLibraryInfoProvider).(StaticLibraryInfo)
expectedStaticOutputFile := "out/soong/.intermediates/foo/android_arm_armv7-a-neon_static/validated/foo.a"
android.AssertPathRelativeToTopEquals(t,
"prebuilt library static target path did not exist or did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
expectedStaticOutputFile, staticInfo.StaticLibrary)
staticOutputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
if err != nil {
t.Errorf("Unexpected error getting cc_object staticOutputFiles %s", err)
}
expectedStaticOutputFiles := []string{expectedStaticOutputFile}
android.AssertPathsRelativeToTopEquals(t,
"prebuilt library static target output files did not match expected.",
expectedStaticOutputFiles, staticOutputFiles)
}
func TestPrebuiltLibraryWithBazelStaticDisabled(t *testing.T) {
const bp = `
cc_prebuilt_library {

View File

@@ -649,7 +649,11 @@ func (handler *ccTestBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleC
return
}
outputFilePath := android.PathForBazelOut(ctx, info.OutputFile)
var outputFilePath android.Path = android.PathForBazelOut(ctx, info.OutputFile)
if len(info.TidyFiles) > 0 {
handler.module.tidyFiles = android.PathsForBazelOut(ctx, info.TidyFiles)
outputFilePath = android.AttachValidationActions(ctx, outputFilePath, handler.module.tidyFiles)
}
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
handler.module.linker.(*testBinary).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput)