Symlink prebuilt binaries on host.

This means binaries will run from their source location and look up
shared libs relative to there.

Test: m nothing
Test: Set up a prebuilt binary with shared libs, check that it can
  be executed during build, and check that its symlinks get updated
  when a shared lib is touched.
Bug: 145934348
Change-Id: I1a600c7163ce0ec34ee8caf0ffe87fef4feb3064
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 3af65d6..1ee096e 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -324,35 +324,68 @@
 type prebuiltBinaryLinker struct {
 	*binaryDecorator
 	prebuiltLinker
+
+	toolPath android.OptionalPath
 }
 
 var _ prebuiltLinkerInterface = (*prebuiltBinaryLinker)(nil)
 
+func (p *prebuiltBinaryLinker) hostToolPath() android.OptionalPath {
+	return p.toolPath
+}
+
 func (p *prebuiltBinaryLinker) link(ctx ModuleContext,
 	flags Flags, deps PathDeps, objs Objects) android.Path {
 	// TODO(ccross): verify shared library dependencies
 	if len(p.properties.Srcs) > 0 {
-		stripFlags := flagsToStripFlags(flags)
-
 		fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
 		in := p.Prebuilt.SingleSourcePath(ctx)
-
+		outputFile := android.PathForModuleOut(ctx, fileName)
 		p.unstrippedOutputFile = in
 
-		if p.stripper.NeedsStrip(ctx) {
-			stripped := android.PathForModuleOut(ctx, "stripped", fileName)
-			p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
-			in = stripped
-		}
+		if ctx.Host() {
+			// Host binaries are symlinked to their prebuilt source locations. That
+			// way they are executed directly from there so the linker resolves their
+			// shared library dependencies relative to that location (using
+			// $ORIGIN/../lib(64):$ORIGIN/lib(64) as RUNPATH). This way the prebuilt
+			// repository can supply the expected versions of the shared libraries
+			// without interference from what is in the out tree.
 
-		// Copy binaries to a name matching the final installed name
-		outputFile := android.PathForModuleOut(ctx, fileName)
-		ctx.Build(pctx, android.BuildParams{
-			Rule:        android.CpExecutable,
-			Description: "prebuilt",
-			Output:      outputFile,
-			Input:       in,
-		})
+			// These shared lib paths may point to copies of the libs in
+			// .intermediates, which isn't where the binary will load them from, but
+			// it's fine for dependency tracking. If a library dependency is updated,
+			// the symlink will get a new timestamp, along with any installed symlinks
+			// handled in make.
+			sharedLibPaths := deps.EarlySharedLibs
+			sharedLibPaths = append(sharedLibPaths, deps.SharedLibs...)
+			sharedLibPaths = append(sharedLibPaths, deps.LateSharedLibs...)
+
+			ctx.Build(pctx, android.BuildParams{
+				Rule:      android.Symlink,
+				Output:    outputFile,
+				Input:     in,
+				Implicits: sharedLibPaths,
+				Args: map[string]string{
+					"fromPath": "$$PWD/" + in.String(),
+				},
+			})
+
+			p.toolPath = android.OptionalPathForPath(outputFile)
+		} else {
+			if p.stripper.NeedsStrip(ctx) {
+				stripped := android.PathForModuleOut(ctx, "stripped", fileName)
+				p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, flagsToStripFlags(flags))
+				in = stripped
+			}
+
+			// Copy binaries to a name matching the final installed name
+			ctx.Build(pctx, android.BuildParams{
+				Rule:        android.CpExecutable,
+				Description: "prebuilt",
+				Output:      outputFile,
+				Input:       in,
+			})
+		}
 
 		return outputFile
 	}
@@ -379,6 +412,7 @@
 		binaryDecorator: binary,
 	}
 	module.linker = prebuilt
+	module.installer = prebuilt
 
 	module.AddProperties(&prebuilt.properties)