Optimizations to abi checking.

We now add export_static_lib_headers, export_generated_headers to the
filters while dumping the abi of a library using header-abi-dumper
(through -I<dir> additions to the invocation of header-abi-dumper and
header-abi-linker)

Also add support for zipped reference source based abi dumps.

Test: mm -j64 in hardware/interfaces/nfc/default/1.0 produces
android.hardware.nfc@1.0.so.lsdump with abi filtered out using generated
headers.

Test: Copied the linked abi dumps produced by mm -j64 in bionic/libc to
prebuilts/abi-dumps/ndk and gzipped them. Ran mm -j64 again in
bionic/libc and verified header-abi-diff getting invoked.

Bug: 32750600

Change-Id: I26210af908c87a6143e39fa25f50307acb68a387
diff --git a/android/paths.go b/android/paths.go
index a23dd74..26b72d1 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -584,10 +584,10 @@
 	var vndkOrNdkDir string
 	var ext string
 	if isSourceDump {
-		ext = ".lsdump"
+		ext = ".lsdump.gz"
 		sourceOrBinaryDir = "source-based"
 	} else {
-		ext = ".bdump"
+		ext = ".bdump.gz"
 		sourceOrBinaryDir = "binary-based"
 	}
 	if vndkOrNdk {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 3ce01d2..2a3b344 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -149,6 +149,7 @@
 			fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES += ", library.sAbiOutputFile.String())
 			if library.sAbiDiff.Valid() && !library.static() {
 				fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES += ", library.sAbiDiff.String())
+				fmt.Fprintln(w, "HEADER_ABI_DIFFS += ", library.sAbiDiff.String())
 			}
 		}
 
diff --git a/cc/builder.go b/cc/builder.go
index f8b3e02..51c4ce9 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -158,9 +158,10 @@
 
 	_ = pctx.SourcePathVariable("sAbiDumper", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/header-abi-dumper")
 
+	// -w has been added since header-abi-dumper does not need to produce any sort of diagnostic information.
 	sAbiDump = pctx.AndroidStaticRule("sAbiDump",
 		blueprint.RuleParams{
-			Command:     "rm -f $out && $sAbiDumper -o ${out} $in $exportDirs -- $cFlags -Wno-packed -Qunused-arguments -isystem ${config.RSIncludePath}",
+			Command:     "rm -f $out && $sAbiDumper -o ${out} $in $exportDirs -- $cFlags -w -isystem ${config.RSIncludePath}",
 			CommandDeps: []string{"$sAbiDumper"},
 		},
 		"cFlags", "exportDirs")
@@ -177,6 +178,7 @@
 		"symbolFile", "arch", "api", "exportedHeaderFlags")
 
 	_ = pctx.SourcePathVariable("sAbiDiffer", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/header-abi-diff")
+
 	// Abidiff check turned on in advice-only mode. Builds will not fail on abi incompatibilties / extensions.
 	sAbiDiff = pctx.AndroidStaticRule("sAbiDiff",
 		blueprint.RuleParams{
@@ -184,6 +186,11 @@
 			CommandDeps: []string{"$sAbiDiffer"},
 		},
 		"referenceDump", "libName", "arch")
+
+	unzipRefSAbiDump = pctx.AndroidStaticRule("unzipRefSAbiDump",
+		blueprint.RuleParams{
+			Command: "gunzip -c $in > $out",
+		})
 )
 
 func init() {
@@ -631,6 +638,17 @@
 	return android.OptionalPathForPath(outputFile)
 }
 
+func UnzipRefDump(ctx android.ModuleContext, zippedRefDump android.Path, baseName string) android.Path {
+	outputFile := android.PathForModuleOut(ctx, baseName+"_ref.lsdump")
+	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
+		Rule:        unzipRefSAbiDump,
+		Description: "gunzip" + outputFile.Base(),
+		Output:      outputFile,
+		Input:       zippedRefDump,
+	})
+	return outputFile
+}
+
 func SourceAbiDiff(ctx android.ModuleContext, inputDump android.Path, referenceDump android.Path,
 	baseName string) android.OptionalPath {
 	outputFile := android.PathForModuleOut(ctx, baseName+".abidiff")
diff --git a/cc/cc.go b/cc/cc.go
index 8069a90..43825ca 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -429,8 +429,7 @@
 
 // Create source abi dumps if the module belongs to the list of VndkLibraries.
 func (ctx *moduleContextImpl) createVndkSourceAbiDump() bool {
-	return ctx.ctx.Device() && (inList(ctx.baseModuleName(), config.LLndkLibraries())) ||
-		(inList(ctx.baseModuleName(), config.VndkLibraries()))
+	return ctx.ctx.Device() && ((Bool(ctx.mod.Properties.Vendor_available)) || (inList(ctx.baseModuleName(), config.LLndkLibraries())))
 }
 
 func (ctx *moduleContextImpl) selectedStl() string {
@@ -920,6 +919,9 @@
 						depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags)
 						depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps,
 							genRule.GeneratedSourceFiles()...)
+						// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
+						c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags)
+
 					}
 				} else {
 					ctx.ModuleErrorf("module %q is not a genrule", name)
@@ -969,6 +971,12 @@
 				if t.reexportFlags {
 					depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...)
 					depPaths.ReexportedFlagsDeps = append(depPaths.ReexportedFlagsDeps, deps...)
+					// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
+					// Re-exported flags from shared library dependencies are not included as those shared libraries
+					// will be included in the vndk set.
+					if tag == staticExportDepTag || tag == headerExportDepTag {
+						c.sabi.Properties.ReexportedIncludeFlags = append(c.sabi.Properties.ReexportedIncludeFlags, flags...)
+					}
 				}
 			}
 
diff --git a/cc/library.go b/cc/library.go
index d6a85e9..997344c 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -317,6 +317,27 @@
 	return library.baseCompiler.compilerFlags(ctx, flags)
 }
 
+func extractExportIncludesFromFlags(flags []string) []string {
+	// This method is used in the  generation of rules which produce
+	// abi-dumps for source files. Exported headers are needed to infer the
+	// abi exported by a library and filter out the rest of the abi dumped
+	// from a source. We extract the include flags exported by a library.
+	// This includes the flags exported which are re-exported from static
+	// library dependencies, exported header library dependencies and
+	// generated header dependencies. Re-exported shared library include
+	// flags are not in this set since shared library dependencies will
+	// themselves be included in the vndk. -isystem headers are not included
+	// since for bionic libraries, abi-filtering is taken care of by version
+	// scripts.
+	var exportedIncludes []string
+	for _, flag := range flags {
+		if strings.HasPrefix(flag, "-I") {
+			exportedIncludes = append(exportedIncludes, flag)
+		}
+	}
+	return exportedIncludes
+}
+
 func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
 	if !library.buildShared() && !library.buildStatic() {
 		if len(library.baseCompiler.Properties.Srcs) > 0 {
@@ -330,13 +351,15 @@
 		}
 		return Objects{}
 	}
-	if ctx.createVndkSourceAbiDump() || (library.sabi.Properties.CreateSAbiDumps && ctx.Device()) {
+	if (ctx.createVndkSourceAbiDump() || (library.sabi.Properties.CreateSAbiDumps && ctx.Device())) && !ctx.Vendor() {
 		exportIncludeDirs := android.PathsForModuleSrc(ctx, library.flagExporter.Properties.Export_include_dirs)
 		var SourceAbiFlags []string
 		for _, dir := range exportIncludeDirs.Strings() {
-			SourceAbiFlags = append(SourceAbiFlags, "-I "+dir)
+			SourceAbiFlags = append(SourceAbiFlags, "-I"+dir)
 		}
-
+		for _, reexportedInclude := range extractExportIncludesFromFlags(library.sabi.Properties.ReexportedIncludeFlags) {
+			SourceAbiFlags = append(SourceAbiFlags, reexportedInclude)
+		}
 		flags.SAbiFlags = SourceAbiFlags
 		total_length := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) + len(library.Properties.Shared.Srcs) +
 			len(library.Properties.Static.Srcs)
@@ -573,7 +596,7 @@
 
 func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string) {
 	//Also take into account object re-use.
-	if len(objs.sAbiDumpFiles) > 0 && ctx.createVndkSourceAbiDump() {
+	if len(objs.sAbiDumpFiles) > 0 && ctx.createVndkSourceAbiDump() && !ctx.Vendor() {
 		refSourceDumpFile := android.PathForVndkRefAbiDump(ctx, "current", fileName, vndkVsNdk(ctx), true)
 		versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
 		var symbolFile android.OptionalPath
@@ -583,12 +606,16 @@
 		exportIncludeDirs := android.PathsForModuleSrc(ctx, library.flagExporter.Properties.Export_include_dirs)
 		var SourceAbiFlags []string
 		for _, dir := range exportIncludeDirs.Strings() {
-			SourceAbiFlags = append(SourceAbiFlags, "-I "+dir)
+			SourceAbiFlags = append(SourceAbiFlags, "-I"+dir)
+		}
+		for _, reexportedInclude := range extractExportIncludesFromFlags(library.sabi.Properties.ReexportedIncludeFlags) {
+			SourceAbiFlags = append(SourceAbiFlags, reexportedInclude)
 		}
 		exportedHeaderFlags := strings.Join(SourceAbiFlags, " ")
 		library.sAbiOutputFile = TransformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, symbolFile, "current", fileName, exportedHeaderFlags)
 		if refSourceDumpFile.Valid() {
-			library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(), refSourceDumpFile.Path(), fileName)
+			unzippedRefDump := UnzipRefDump(ctx, refSourceDumpFile.Path(), fileName)
+			library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(), unzippedRefDump, fileName)
 		}
 	}
 }
diff --git a/cc/makevars.go b/cc/makevars.go
index 8bf034a..a1e97a5 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -42,6 +42,7 @@
 	ctx.Strict("RS_LLVM_PREBUILTS_VERSION", "${config.RSClangVersion}")
 	ctx.Strict("RS_LLVM_PREBUILTS_BASE", "${config.RSClangBase}")
 	ctx.Strict("RS_LLVM_PREBUILTS_PATH", "${config.RSLLVMPrebuiltsPath}")
+	ctx.Strict("RS_LLVM_INCLUDES", "${config.RSIncludePath}")
 	ctx.Strict("RS_CLANG", "${config.RSLLVMPrebuiltsPath}/clang")
 	ctx.Strict("RS_LLVM_AS", "${config.RSLLVMPrebuiltsPath}/llvm-as")
 	ctx.Strict("RS_LLVM_LINK", "${config.RSLLVMPrebuiltsPath}/llvm-link")
diff --git a/cc/sabi.go b/cc/sabi.go
index 7ae31c9..01ef737 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -22,7 +22,8 @@
 )
 
 type SAbiProperties struct {
-	CreateSAbiDumps bool `blueprint:"mutated"`
+	CreateSAbiDumps        bool `blueprint:"mutated"`
+	ReexportedIncludeFlags []string
 }
 
 type sabi struct {
@@ -45,7 +46,7 @@
 
 func sabiDepsMutator(mctx android.TopDownMutatorContext) {
 	if c, ok := mctx.Module().(*Module); ok &&
-		((inList(c.Name(), config.VndkLibraries())) || (inList(c.Name(), config.LLndkLibraries())) ||
+		(Bool(c.Properties.Vendor_available) || (inList(c.Name(), config.LLndkLibraries())) ||
 			(c.sabi != nil && c.sabi.Properties.CreateSAbiDumps)) {
 		mctx.VisitDirectDeps(func(m blueprint.Module) {
 			tag := mctx.OtherModuleDependencyTag(m)