Add header-abi-checker for Vndk abi checks.

header-abi-dumper: dumps abi exported by source files for Vndk.
header-abi-linker: links abi dumps produced by header-abi-dumper.
header-abi-diff: compares linked dumps.

Test: mm -j64 showcommands > make_log in bionic/libc.
      This produced linked dumps in out/soong/.intermediates.
      Copied these dumps to
      prebuilts/abi-dumps/ndk/current/arm64/source-based/.
      Changed the abi and re-ran mm -j64 showcommands > make_log
      confirmed that the build reported compatibility breakge without
      actually failing (advisory mode).

Change-Id: Iccad6908fe68a80f47230751671d156893b96ead
diff --git a/cc/library.go b/cc/library.go
index cb85bd3..e2ec584 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -21,6 +21,7 @@
 	"github.com/google/blueprint/pathtools"
 
 	"android/soong/android"
+	"android/soong/cc/config"
 )
 
 type LibraryProperties struct {
@@ -220,9 +221,17 @@
 
 	sanitize *sanitize
 
+	sabi *sabi
+
 	// Output archive of gcno coverage information files
 	coverageOutputFile android.OptionalPath
 
+	// linked Source Abi Dump
+	sAbiOutputFile android.OptionalPath
+
+	// Source Abi Diff
+	sAbiDiff android.OptionalPath
+
 	// Decorated interafaces
 	*baseCompiler
 	*baseLinker
@@ -316,7 +325,20 @@
 		}
 		return Objects{}
 	}
+	if ctx.createVndkSourceAbiDump() || (library.sabi.Properties.CreateSAbiDumps && ctx.Device()) {
+		exportIncludeDirs := android.PathsForModuleSrc(ctx, library.flagExporter.Properties.Export_include_dirs)
+		var SourceAbiFlags []string
+		for _, dir := range exportIncludeDirs.Strings() {
+			SourceAbiFlags = append(SourceAbiFlags, "-I "+dir)
+		}
 
+		flags.SAbiFlags = SourceAbiFlags
+		total_length := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) + len(library.Properties.Shared.Srcs) +
+			len(library.Properties.Static.Srcs)
+		if total_length > 0 {
+			flags.SAbiDump = true
+		}
+	}
 	objs := library.baseCompiler.compile(ctx, flags, deps)
 	library.reuseObjects = objs
 	buildFlags := flagsToBuilderFlags(flags)
@@ -534,11 +556,45 @@
 
 	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
 	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
+
+	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...)
+	objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
+
 	library.coverageOutputFile = TransformCoverageFilesToLib(ctx, objs, builderFlags, library.getLibName(ctx))
+	library.linkSAbiDumpFiles(ctx, objs, fileName)
 
 	return ret
 }
 
+func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string) {
+	//Also take into account object re-use.
+	if len(objs.sAbiDumpFiles) > 0 && ctx.createVndkSourceAbiDump() {
+		refSourceDumpFile := android.PathForVndkRefAbiDump(ctx, "current", fileName, vndkVsNdk(ctx), true)
+		versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
+		var symbolFile android.OptionalPath
+		if versionScript.Valid() {
+			symbolFile = versionScript
+		}
+		exportIncludeDirs := android.PathsForModuleSrc(ctx, library.flagExporter.Properties.Export_include_dirs)
+		var SourceAbiFlags []string
+		for _, dir := range exportIncludeDirs.Strings() {
+			SourceAbiFlags = append(SourceAbiFlags, "-I "+dir)
+		}
+		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)
+		}
+	}
+}
+
+func vndkVsNdk(ctx ModuleContext) bool {
+	if inList(ctx.baseModuleName(), config.LLndkLibraries()) {
+		return false
+	}
+	return true
+}
+
 func (library *libraryDecorator) link(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 
@@ -656,6 +712,7 @@
 		baseLinker:    NewBaseLinker(),
 		baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem),
 		sanitize:      module.sanitize,
+		sabi:          module.sabi,
 	}
 
 	module.compiler = library