Add support for cc_test.

This behaves slightly differently than it does in the make based build.

1. The make based build manually passes -DGTEST_OS_ANDROID (or
   whatever). gtest-port.h already has logic that does this, so it's a
   no-op.
2. Host libraries are named identically, rather than libgtest_host.

Change-Id: Ic40a1025c698611d202cb7c8ec45abd8fe130065
diff --git a/cc/cc.go b/cc/cc.go
index 1ebd762..a9ed205 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -227,6 +227,9 @@
 	// Compile objects into final module
 	compileModule(common.AndroidModuleContext, ccFlags, ccDeps, []string)
 
+	// Install the built module.
+	installModule(common.AndroidModuleContext, ccFlags)
+
 	// Return the output file (.o, .a or .so) for use by other modules
 	outputFile() string
 }
@@ -307,6 +310,11 @@
 	if ctx.Failed() {
 		return
 	}
+
+	c.ccModuleType().installModule(ctx, flags)
+	if ctx.Failed() {
+		return
+	}
 }
 
 func (c *ccBase) ccModuleType() ccModuleType {
@@ -940,13 +948,6 @@
 	c.out = outputFile
 	c.exportIncludeDirs = pathtools.PrefixPaths(c.properties.Export_include_dirs,
 		common.ModuleSrcDir(ctx))
-
-	installDir := "lib"
-	if flags.toolchain.Is64Bit() {
-		installDir = "lib64"
-	}
-
-	ctx.InstallFile(installDir, outputFile)
 }
 
 func (c *ccLibrary) compileModule(ctx common.AndroidModuleContext,
@@ -966,6 +967,27 @@
 	}
 }
 
+func (c *ccLibrary) installStaticLibrary(ctx common.AndroidModuleContext, flags ccFlags) {
+	// Static libraries do not get installed.
+}
+
+func (c *ccLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags ccFlags) {
+	installDir := "lib"
+	if flags.toolchain.Is64Bit() {
+		installDir = "lib64"
+	}
+
+	ctx.InstallFile(installDir, c.out)
+}
+
+func (c *ccLibrary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
+	if c.libraryProperties.IsStatic {
+		c.installStaticLibrary(ctx, flags)
+	} else {
+		c.installSharedLibrary(ctx, flags)
+	}
+}
+
 //
 // Objects (for crt*.o)
 //
@@ -1017,6 +1039,10 @@
 	ctx.CheckbuildFile(outputFile)
 }
 
+func (c *ccObject) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
+	// Object files do not get installed.
+}
+
 func (c *ccObject) outputFile() string {
 	return c.out
 }
@@ -1027,6 +1053,7 @@
 
 type ccBinary struct {
 	ccDynamic
+	out              string
 	binaryProperties binaryProperties
 }
 
@@ -1099,12 +1126,61 @@
 	}
 
 	outputFile := filepath.Join(common.ModuleOutDir(ctx), c.getStem(ctx))
+	c.out = outputFile
 
 	TransformObjToDynamicBinary(ctx, objFiles, deps.sharedLibs, deps.staticLibs,
 		deps.lateStaticLibs, deps.wholeStaticLibs, deps.crtBegin, deps.crtEnd,
 		ccFlagsToBuilderFlags(flags), outputFile)
+}
 
-	ctx.InstallFile("bin", outputFile)
+func (c *ccBinary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
+	ctx.InstallFile("bin", c.out)
+}
+
+type ccTest struct {
+	ccBinary
+}
+
+var (
+	gtestLibs = []string{"libgtest", "libgtest_main"}
+)
+
+func (c *ccTest) collectDeps(ctx common.AndroidModuleContext, flags ccFlags) (ccDeps, ccFlags) {
+	deps, flags := c.ccBinary.collectDeps(ctx, flags)
+
+	flags.cFlags = append(flags.cFlags, "-DGTEST_HAS_STD_STRING")
+	if c.HostOrDevice().Host() {
+		flags.cFlags = append(flags.cFlags, "-O0", "-g")
+		flags.ldLibs = append(flags.ldLibs, "-lpthread")
+	}
+
+	// TODO(danalbert): Make gtest export its dependencies.
+	flags.includeDirs = append(flags.includeDirs, "external/gtest/include")
+
+	_, staticLibs, _ := c.collectDepsFromList(ctx, gtestLibs)
+	deps.staticLibs = append(deps.staticLibs, staticLibs...)
+
+	return deps, flags
+}
+
+func (c *ccTest) AndroidDynamicDependencies(ctx common.AndroidDynamicDependerModuleContext) []string {
+	ctx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, gtestLibs...)
+	deps := c.ccBinary.AndroidDynamicDependencies(ctx)
+	return append(deps, gtestLibs...)
+}
+
+func (c *ccTest) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
+	if c.HostOrDevice().Device() {
+		ctx.InstallFile("../data/nativetest/" + ctx.ModuleName(), c.out)
+	} else {
+		c.ccBinary.installModule(ctx, flags)
+	}
+}
+
+func NewCCTest() (blueprint.Module, []interface{}) {
+	module := &ccTest{}
+	return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported,
+		common.MultilibFirst, &module.binaryProperties)
 }
 
 //
@@ -1198,6 +1274,10 @@
 	ctx.CheckbuildFile(outputFile)
 }
 
+func (c *toolchainLibrary) installModule(ctx common.AndroidModuleContext, flags ccFlags) {
+	// Toolchain libraries do not get installed.
+}
+
 func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
 	if c, ok := mctx.Module().(*ccLibrary); ok {
 		var modules []blueprint.Module