Install symlinks with same suffix and extension as installed file

Move symlink installation into the binaryDecorator so that it can
access the suffix and extension when installing symlinks.  Also
consolidates the symlink and symlink_preferred_arch handling.

Test: m -j clang, ls -l out/host/windows-x86/bin/clang++.exe
Change-Id: I1204afb71fac87b276bd6b625b52ee21274855a0
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 709ac59..380babc 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -140,6 +140,11 @@
 		if Bool(binary.Properties.Static_executable) {
 			fmt.Fprintln(w, "LOCAL_FORCE_STATIC_EXECUTABLE := true")
 		}
+
+		if len(binary.symlinks) > 0 {
+			fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS := "+strings.Join(binary.symlinks, " "))
+		}
+
 		return nil
 	})
 }
@@ -211,9 +216,6 @@
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file))
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
-		if len(installer.Properties.Symlinks) > 0 {
-			fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS := "+strings.Join(installer.Properties.Symlinks, " "))
-		}
 		return nil
 	})
 }
diff --git a/cc/binary.go b/cc/binary.go
index 1aba6eb..1634a83 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -37,6 +37,10 @@
 	// if set, install a symlink to the preferred architecture
 	Symlink_preferred_arch bool
 
+	// install symlinks to the binary.  Symlink names will have the suffix and the binary
+	// extension (if any) appended
+	Symlinks []string `android:"arch_variant"`
+
 	DynamicLinker string `blueprint:"mutated"`
 }
 
@@ -69,6 +73,9 @@
 	Properties BinaryLinkerProperties
 
 	toolPath android.OptionalPath
+
+	// Names of symlinks to be installed for use in LOCAL_MODULE_SYMLINKS
+	symlinks []string
 }
 
 var _ linker = (*binaryDecorator)(nil)
@@ -173,16 +180,6 @@
 			binary.Properties.Static_executable = nil
 		}
 	}
-
-	if binary.Properties.Symlink_preferred_arch {
-		if binary.Properties.Stem == "" && binary.Properties.Suffix == "" {
-			ctx.PropertyErrorf("symlink_preferred_arch", "must also specify stem or suffix")
-		}
-		if ctx.TargetPrimary() {
-			binary.baseInstaller.Properties.Symlinks = append(binary.baseInstaller.Properties.Symlinks,
-				ctx.baseModuleName())
-		}
-	}
 }
 
 func (binary *binaryDecorator) static() bool {
@@ -302,6 +299,24 @@
 
 func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
 	binary.baseInstaller.install(ctx, file)
+	for _, symlink := range binary.Properties.Symlinks {
+		binary.symlinks = append(binary.symlinks,
+			symlink+binary.Properties.Suffix+binary.baseInstaller.path.Ext())
+	}
+
+	if binary.Properties.Symlink_preferred_arch {
+		if binary.Properties.Stem == "" && binary.Properties.Suffix == "" {
+			ctx.PropertyErrorf("symlink_preferred_arch", "must also specify stem or suffix")
+		}
+		if ctx.TargetPrimary() {
+			binary.symlinks = append(binary.symlinks, ctx.baseModuleName())
+		}
+	}
+
+	for _, symlink := range binary.symlinks {
+		ctx.InstallSymlink(binary.baseInstaller.installDir(ctx), symlink, binary.baseInstaller.path)
+	}
+
 	if ctx.Os().Class == android.Host {
 		binary.toolPath = android.OptionalPathForPath(binary.baseInstaller.path)
 	}
diff --git a/cc/installer.go b/cc/installer.go
index 8ce9541..64f87d9 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -25,9 +25,6 @@
 type InstallerProperties struct {
 	// install to a subdirectory of the default install path for the module
 	Relative_install_path string `android:"arch_variant"`
-
-	// install symlinks to the module
-	Symlinks []string `android:"arch_variant"`
 }
 
 type installLocation int
@@ -62,7 +59,7 @@
 	return []interface{}{&installer.Properties}
 }
 
-func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) {
+func (installer *baseInstaller) installDir(ctx ModuleContext) android.OutputPath {
 	subDir := installer.dir
 	if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
 		subDir = installer.dir64
@@ -70,11 +67,11 @@
 	if !ctx.Host() && !ctx.Arch().Native {
 		subDir = filepath.Join(subDir, ctx.Arch().ArchType.String())
 	}
-	dir := android.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path, installer.relative)
-	installer.path = ctx.InstallFile(dir, file)
-	for _, symlink := range installer.Properties.Symlinks {
-		ctx.InstallSymlink(dir, symlink, installer.path)
-	}
+	return android.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path, installer.relative)
+}
+
+func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) {
+	installer.path = ctx.InstallFile(installer.installDir(ctx), file)
 }
 
 func (installer *baseInstaller) inData() bool {