Merge "Remove GCC support from Make"
diff --git a/android/androidmk.go b/android/androidmk.go
index 1d11161..44c266a 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -141,6 +141,13 @@
 }
 
 func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
+	defer func() {
+		if r := recover(); r != nil {
+			panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s",
+				r, ctx.ModuleName(mod), ctx.ModuleSubDir(mod)))
+		}
+	}()
+
 	provider, ok := mod.(AndroidMkDataProvider)
 	if !ok {
 		return nil
diff --git a/android/config.go b/android/config.go
index 3a2a005..3ef202b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -572,6 +572,10 @@
 	return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng)
 }
 
+func (c *config) Debuggable() bool {
+	return Bool(c.productVariables.Debuggable)
+}
+
 func (c *config) DevicePrefer32BitExecutables() bool {
 	return Bool(c.productVariables.DevicePrefer32BitExecutables)
 }
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index ff8a878..d6018eb 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -76,8 +76,29 @@
 		p.libraryDecorator.exportIncludes(ctx, "-I")
 		p.libraryDecorator.reexportFlags(deps.ReexportedFlags)
 		p.libraryDecorator.reexportDeps(deps.ReexportedFlagsDeps)
-		// TODO(ccross): .toc optimization, stripping, packing
-		return p.Prebuilt.SingleSourcePath(ctx)
+
+		builderFlags := flagsToBuilderFlags(flags)
+
+		in := p.Prebuilt.SingleSourcePath(ctx)
+
+		if p.shared() {
+			libName := ctx.baseModuleName() + flags.Toolchain.ShlibSuffix()
+			if p.needsStrip(ctx) {
+				stripped := android.PathForModuleOut(ctx, "stripped", libName)
+				p.strip(ctx, in, stripped, builderFlags)
+				in = stripped
+			}
+
+			if !ctx.Darwin() && !ctx.Windows() {
+				// Optimize out relinking against shared libraries whose interface hasn't changed by
+				// depending on a table of contents file instead of the library itself.
+				tocFile := android.PathForModuleOut(ctx, libName+".toc")
+				p.tocFile = android.OptionalPathForPath(tocFile)
+				TransformSharedObjectToToc(ctx, in, tocFile, builderFlags)
+			}
+		}
+
+		return in
 	}
 
 	return nil
@@ -136,17 +157,24 @@
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 	// TODO(ccross): verify shared library dependencies
 	if len(p.properties.Srcs) > 0 {
-		// TODO(ccross): .toc optimization, stripping, packing
+		builderFlags := flagsToBuilderFlags(flags)
+
+		fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
+		in := p.Prebuilt.SingleSourcePath(ctx)
+
+		if p.needsStrip(ctx) {
+			stripped := android.PathForModuleOut(ctx, "stripped", fileName)
+			p.strip(ctx, in, stripped, builderFlags)
+			in = stripped
+		}
 
 		// Copy binaries to a name matching the final installed name
-		fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
 		outputFile := android.PathForModuleOut(ctx, fileName)
-
 		ctx.Build(pctx, android.BuildParams{
 			Rule:        android.CpExecutable,
 			Description: "prebuilt",
 			Output:      outputFile,
-			Input:       p.Prebuilt.SingleSourcePath(ctx),
+			Input:       in,
 		})
 
 		return outputFile
diff --git a/cc/strip.go b/cc/strip.go
index a7c2d4e..ec2450a 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -21,6 +21,7 @@
 type StripProperties struct {
 	Strip struct {
 		None         *bool
+		All          *bool
 		Keep_symbols *bool
 	}
 }
@@ -33,14 +34,19 @@
 	return !ctx.Config().EmbeddedInMake() && !Bool(stripper.StripProperties.Strip.None)
 }
 
-func (stripper *stripper) strip(ctx ModuleContext, in, out android.ModuleOutPath,
+func (stripper *stripper) strip(ctx ModuleContext, in android.Path, out android.ModuleOutPath,
 	flags builderFlags) {
 	if ctx.Darwin() {
 		TransformDarwinStrip(ctx, in, out)
 	} else {
-		flags.stripKeepSymbols = Bool(stripper.StripProperties.Strip.Keep_symbols)
-		// TODO(ccross): don't add gnu debuglink for user builds
-		flags.stripAddGnuDebuglink = true
+		if Bool(stripper.StripProperties.Strip.Keep_symbols) {
+			flags.stripKeepSymbols = true
+		} else if !Bool(stripper.StripProperties.Strip.All) {
+			flags.stripKeepMiniDebugInfo = true
+		}
+		if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo {
+			flags.stripAddGnuDebuglink = true
+		}
 		TransformStrip(ctx, in, out, flags)
 	}
 }