cmd/gomobile: clean-up the code using gobind for iOS

This CL cleans up the code using gobind by these fixes:

- Run the gobind command for each platform, instead of each target (=
  platform + arch).
- Run the gobind command in parallel with errgroup.Group.

This CL doesn't improve performance significantly, but should improve
readability by splitting the long for-range loop.

Updates golang/go#54770

Change-Id: I881810b95db0fa6a6d17982154591af467f1ebfe
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/437035
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Changkun Ou <mail@changkun.de>
Auto-Submit: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Hajime Hoshi <hajimehoshi@gmail.com>
diff --git a/cmd/gomobile/bind_iosapp.go b/cmd/gomobile/bind_iosapp.go
index b9beaea..47f5e98 100644
--- a/cmd/gomobile/bind_iosapp.go
+++ b/cmd/gomobile/bind_iosapp.go
@@ -14,6 +14,7 @@
 	"strings"
 	"text/template"
 
+	"golang.org/x/sync/errgroup"
 	"golang.org/x/tools/go/packages"
 )
 
@@ -38,6 +39,49 @@
 		return err
 	}
 
+	outDirsForPlatform := map[string]string{}
+	for _, t := range targets {
+		outDirsForPlatform[t.platform] = filepath.Join(tmpdir, t.platform)
+	}
+
+	// Run the gobind command for each platform
+	var wg errgroup.Group
+	for platform, outDir := range outDirsForPlatform {
+		platform := platform
+		outDir := outDir
+		wg.Go(func() error {
+			// Catalyst support requires iOS 13+
+			v, _ := strconv.ParseFloat(buildIOSVersion, 64)
+			if platform == "maccatalyst" && v < 13.0 {
+				return errors.New("catalyst requires -iosversion=13 or higher")
+			}
+
+			// Run gobind once per platform to generate the bindings
+			cmd := exec.Command(
+				gobind,
+				"-lang=go,objc",
+				"-outdir="+outDir,
+			)
+			cmd.Env = append(cmd.Env, "GOOS="+platformOS(platform))
+			cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
+			tags := append(buildTags[:], platformTags(platform)...)
+			cmd.Args = append(cmd.Args, "-tags="+strings.Join(tags, ","))
+			if bindPrefix != "" {
+				cmd.Args = append(cmd.Args, "-prefix="+bindPrefix)
+			}
+			for _, p := range pkgs {
+				cmd.Args = append(cmd.Args, p.PkgPath)
+			}
+			if err := runCmd(cmd); err != nil {
+				return err
+			}
+			return nil
+		})
+	}
+	if err := wg.Wait(); err != nil {
+		return err
+	}
+
 	modulesUsed, err := areGoModulesUsed()
 	if err != nil {
 		return err
@@ -46,36 +90,10 @@
 	var frameworkDirs []string
 	frameworkArchCount := map[string]int{}
 	for _, t := range targets {
-		// Catalyst support requires iOS 13+
-		v, _ := strconv.ParseFloat(buildIOSVersion, 64)
-		if t.platform == "maccatalyst" && v < 13.0 {
-			return errors.New("catalyst requires -iosversion=13 or higher")
-		}
-
-		outDir := filepath.Join(tmpdir, t.platform)
+		outDir := outDirsForPlatform[t.platform]
 		outSrcDir := filepath.Join(outDir, "src")
 		gobindDir := filepath.Join(outSrcDir, "gobind")
 
-		// Run gobind once per platform to generate the bindings
-		cmd := exec.Command(
-			gobind,
-			"-lang=go,objc",
-			"-outdir="+outDir,
-		)
-		cmd.Env = append(cmd.Env, "GOOS="+platformOS(t.platform))
-		cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
-		tags := append(buildTags[:], platformTags(t.platform)...)
-		cmd.Args = append(cmd.Args, "-tags="+strings.Join(tags, ","))
-		if bindPrefix != "" {
-			cmd.Args = append(cmd.Args, "-prefix="+bindPrefix)
-		}
-		for _, p := range pkgs {
-			cmd.Args = append(cmd.Args, p.PkgPath)
-		}
-		if err := runCmd(cmd); err != nil {
-			return err
-		}
-
 		env := appleEnv[t.String()][:]
 		sdk := getenv(env, "DARWIN_SDK")