Filter duplicate sources in ART's codegen customizer.

With this change, it is now possible to write the following in ART
Blueprint files:

  codegen: {
      mips: {
          srcs: ["disassembler_mips.cc"],
      },
      mips64: {
          srcs: ["disassembler_mips.cc"],
      },
  },

and have it work even if the `mips` and `mips64` are both enabled.

Before this change, this construction would have been rejected with
the following error message:

  "FAILED: ninja: […]: multiple rules generate […]disassembler_mips.o"

Test: m test-art-host
Bug: 119090273
Change-Id: I0a20a65ce7ab308644f3018a89fa96e5bdcdbdc4
diff --git a/build/codegen.go b/build/codegen.go
index f407e5d..a9966f2 100644
--- a/build/codegen.go
+++ b/build/codegen.go
@@ -41,21 +41,7 @@
 		deviceArches = strings.Split(e, " ")
 	}
 
-	addCodegenArchProperties := func(host bool, archName string) {
-		type props struct {
-			Target struct {
-				Android *CodegenCommonArchProperties
-				Host    *CodegenCommonArchProperties
-			}
-		}
-
-		type libraryProps struct {
-			Target struct {
-				Android *CodegenLibraryArchProperties
-				Host    *CodegenLibraryArchProperties
-			}
-		}
-
+	getCodegenArchProperties := func(archName string) *codegenArchProperties {
 		var arch *codegenArchProperties
 		switch archName {
 		case "arm":
@@ -72,42 +58,86 @@
 			arch = &c.Codegen.X86_64
 		default:
 			ctx.ModuleErrorf("Unknown codegen architecture %q", archName)
-			return
+		}
+		return arch
+	}
+
+	appendCodegenSourceArchProperties := func(p *CodegenSourceArchProperties, archName string) {
+		arch := getCodegenArchProperties(archName)
+		p.Srcs = append(p.Srcs, arch.CodegenSourceArchProperties.Srcs...)
+	}
+
+	addCodegenSourceArchProperties := func(host bool, p *CodegenSourceArchProperties) {
+		type sourceProps struct {
+			Target struct {
+				Android *CodegenSourceArchProperties
+				Host    *CodegenSourceArchProperties
+			}
 		}
 
-		p := &props{}
-		l := &libraryProps{}
+		sp := &sourceProps{}
 		if host {
-			p.Target.Host = &arch.CodegenCommonArchProperties
-			l.Target.Host = &arch.CodegenLibraryArchProperties
+			sp.Target.Host = p
 		} else {
-			p.Target.Android = &arch.CodegenCommonArchProperties
-			l.Target.Android = &arch.CodegenLibraryArchProperties
+			sp.Target.Android = p
+		}
+		ctx.AppendProperties(sp)
+	}
+
+	addCodegenArchProperties := func(host bool, archName string) {
+		type commonProps struct {
+			Target struct {
+				Android *CodegenCommonArchProperties
+				Host    *CodegenCommonArchProperties
+			}
 		}
 
-		ctx.AppendProperties(p)
+		type libraryProps struct {
+			Target struct {
+				Android *CodegenLibraryArchProperties
+				Host    *CodegenLibraryArchProperties
+			}
+		}
+
+		arch := getCodegenArchProperties(archName)
+
+		cp := &commonProps{}
+		lp := &libraryProps{}
+		if host {
+			cp.Target.Host = &arch.CodegenCommonArchProperties
+			lp.Target.Host = &arch.CodegenLibraryArchProperties
+		} else {
+			cp.Target.Android = &arch.CodegenCommonArchProperties
+			lp.Target.Android = &arch.CodegenLibraryArchProperties
+		}
+
+		ctx.AppendProperties(cp)
 		if library {
-			ctx.AppendProperties(l)
+			ctx.AppendProperties(lp)
 		}
 	}
 
-	for _, arch := range deviceArches {
-		addCodegenArchProperties(false, arch)
-		if ctx.Failed() {
-			return
+	addCodegenProperties := func(host bool, arches []string) {
+		sourceProps := &CodegenSourceArchProperties{}
+		for _, arch := range arches {
+			appendCodegenSourceArchProperties(sourceProps, arch)
+			addCodegenArchProperties(host, arch)
 		}
+		sourceProps.Srcs = android.FirstUniqueStrings(sourceProps.Srcs)
+		addCodegenSourceArchProperties(host, sourceProps)
 	}
 
-	for _, arch := range hostArches {
-		addCodegenArchProperties(true, arch)
-		if ctx.Failed() {
-			return
-		}
-	}
+	addCodegenProperties(false /* host */, deviceArches)
+	addCodegenProperties(true /* host */, hostArches)
+}
+
+// These properties are allowed to contain the same source file name in different architectures.
+// They we will be deduplicated automatically.
+type CodegenSourceArchProperties struct {
+	Srcs []string
 }
 
 type CodegenCommonArchProperties struct {
-	Srcs     []string
 	Cflags   []string
 	Cppflags []string
 }
@@ -123,6 +153,7 @@
 }
 
 type codegenArchProperties struct {
+	CodegenSourceArchProperties
 	CodegenCommonArchProperties
 	CodegenLibraryArchProperties
 }