Check NDK API level link compatibility.

Mixing NDK API levels is only supported when linking against something
equal or older.

Change-Id: I2c3022a3d75465b736f2e65160da3113cfd6e635
diff --git a/cc/cc.go b/cc/cc.go
index 8c2fe6f..62d02c5 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -20,6 +20,7 @@
 
 import (
 	"fmt"
+	"strconv"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -654,33 +655,69 @@
 
 	// Whether a module can link to another module, taking into
 	// account NDK linking.
-	linkTypeOk := func(from, to *Module) bool {
+	checkLinkType := func(from, to *Module) {
 		if from.Target().Os != android.Android {
 			// Host code is not restricted
-			return true
+			return
 		}
 		if from.Properties.Sdk_version == "" {
 			// Platform code can link to anything
-			return true
+			return
 		}
 		if _, ok := to.linker.(*toolchainLibraryLinker); ok {
 			// These are always allowed
-			return true
+			return
 		}
 		if _, ok := to.linker.(*ndkPrebuiltLibraryLinker); ok {
 			// These are allowed, but don't set sdk_version
-			return true
+			return
 		}
 		if _, ok := to.linker.(*ndkPrebuiltStlLinker); ok {
 			// These are allowed, but don't set sdk_version
-			return true
+			return
 		}
 		if _, ok := to.linker.(*stubLinker); ok {
 			// These aren't real libraries, but are the stub shared libraries that are included in
 			// the NDK.
-			return true
+			return
 		}
-		return to.Properties.Sdk_version != ""
+		if to.Properties.Sdk_version == "" {
+			// NDK code linking to platform code is never okay.
+			ctx.ModuleErrorf("depends on non-NDK-built library %q",
+				ctx.OtherModuleName(to))
+		}
+
+		// All this point we know we have two NDK libraries, but we need to
+		// check that we're not linking against anything built against a higher
+		// API level, as it is only valid to link against older or equivalent
+		// APIs.
+
+		if from.Properties.Sdk_version == "current" {
+			// Current can link against anything.
+			return
+		} else if to.Properties.Sdk_version == "current" {
+			// Current can't be linked against by anything else.
+			ctx.ModuleErrorf("links %q built against newer API version %q",
+				ctx.OtherModuleName(to), "current")
+		}
+
+		fromApi, err := strconv.Atoi(from.Properties.Sdk_version)
+		if err != nil {
+			ctx.PropertyErrorf("sdk_version",
+				"Invalid sdk_version value (must be int): %q",
+				from.Properties.Sdk_version)
+		}
+		toApi, err := strconv.Atoi(to.Properties.Sdk_version)
+		if err != nil {
+			ctx.PropertyErrorf("sdk_version",
+				"Invalid sdk_version value (must be int): %q",
+				to.Properties.Sdk_version)
+		}
+
+		if toApi > fromApi {
+			ctx.ModuleErrorf("links %q built against newer API version %q",
+				ctx.OtherModuleName(to), to.Properties.Sdk_version)
+		}
 	}
 
 	ctx.VisitDirectDeps(func(m blueprint.Module) {
@@ -755,9 +792,7 @@
 				}
 			}
 
-			if !linkTypeOk(c, cc) {
-				ctx.ModuleErrorf("depends on non-NDK-built library %q", name)
-			}
+			checkLinkType(c, cc)
 		}
 
 		var depPtr *android.Paths