From 80cb72e7af8e71b65e7d9e59fb4ec5d620134608 Mon Sep 17 00:00:00 2001 From: Changkun Ou Date: Mon, 30 Aug 2021 22:04:01 +0200 Subject: [PATCH] cmd/gomobile: use GOOS=ios for iOS builds This change permits gomobile to build iOS applications by properly set GOOS=ios in the build process. The change is locally tested on darwin/arm64, and golang.org/x/mobile/example/basic can be build using the following commands: gomobile build -target=android -o=basic.apk \ golang.org/x/mobile/example/basic gomobile build -target=ios -bundleid=org.golang.gomobiletest \ -o=basic.app golang.org/x/mobile/example/basic The built binaries are also tested on iOS 15 beta7 and Android 12 API31. Updates golang/go#47952 Fixes golang/go#47238 Change-Id: Ibf40a77933ac957640c78d0dbc1af043477e4b3a Reviewed-on: https://go-review.googlesource.com/c/mobile/+/346150 Reviewed-by: Dmitri Shuralyov Reviewed-by: Hajime Hoshi Trust: Dmitri Shuralyov Trust: Bryan C. Mills Run-TryBot: Hajime Hoshi TryBot-Result: Go Bot --- cmd/gomobile/bind.go | 10 ++-------- cmd/gomobile/bind_iosapp.go | 6 +++--- cmd/gomobile/bind_test.go | 3 ++- cmd/gomobile/build.go | 15 ++------------- cmd/gomobile/build_darwin_test.go | 8 +++----- cmd/gomobile/build_iosapp.go | 4 ++-- cmd/gomobile/build_test.go | 8 ++++---- cmd/gomobile/doc.go | 4 ++-- cmd/gomobile/env.go | 12 ++++++------ cmd/gomobile/main.go | 8 ++++---- example/basic/main.go | 3 +-- go.mod | 2 +- internal/mobileinit/mobileinit_ios.go | 3 --- 13 files changed, 32 insertions(+), 54 deletions(-) diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go index ef62d05..6a80e53 100644 --- a/cmd/gomobile/bind.go +++ b/cmd/gomobile/bind.go @@ -84,7 +84,7 @@ func runBind(cmd *command) error { if bindJavaPkg != "" && targetOS != "android" { return fmt.Errorf("-javapkg is supported only for android target") } - if bindPrefix != "" && targetOS != "darwin" { + if bindPrefix != "" && targetOS != "ios" { return fmt.Errorf("-prefix is supported only for ios target") } @@ -122,7 +122,7 @@ func runBind(cmd *command) error { switch targetOS { case "android": return goAndroidBind(gobind, pkgs, targetArchs) - case "darwin": + case "ios": if !xcodeAvailable() { return fmt.Errorf("-target=ios requires XCode") } @@ -217,9 +217,6 @@ func packagesConfig(targetOS string) *packages.Config { // Add CGO_ENABLED=1 explicitly since Cgo is disabled when GOOS is different from host OS. config.Env = append(os.Environ(), "GOARCH=arm64", "GOOS="+targetOS, "CGO_ENABLED=1") tags := buildTags - if targetOS == "darwin" { - tags = append(tags, "ios") - } if len(tags) > 0 { config.BuildFlags = []string{"-tags=" + strings.Join(tags, ",")} } @@ -232,9 +229,6 @@ func getModuleVersions(targetOS string, targetArch string, src string) (*modfile cmd.Env = append(os.Environ(), "GOOS="+targetOS, "GOARCH="+targetArch) tags := buildTags - if targetOS == "darwin" { - tags = append(tags, "ios") - } // TODO(hyangah): probably we don't need to add all the dependencies. cmd.Args = append(cmd.Args, "-m", "-json", "-tags="+strings.Join(tags, ","), "all") cmd.Dir = src diff --git a/cmd/gomobile/bind_iosapp.go b/cmd/gomobile/bind_iosapp.go index 846a63f..e9615e8 100644 --- a/cmd/gomobile/bind_iosapp.go +++ b/cmd/gomobile/bind_iosapp.go @@ -67,11 +67,11 @@ func goIOSBind(gobind string, pkgs []*packages.Package, archs []string) error { } for _, arch := range archs { - if err := writeGoMod("darwin", arch); err != nil { + if err := writeGoMod("ios", arch); err != nil { return err } - env := darwinEnv[arch] + env := iosEnv[arch] // Add the generated packages to GOPATH for reverse bindings. gopath := fmt.Sprintf("GOPATH=%s%c%s", tmpdir, filepath.ListSeparator, goEnv("GOPATH")) env = append(env, gopath) @@ -86,7 +86,7 @@ func goIOSBind(gobind string, pkgs []*packages.Package, archs []string) error { path, err := goIOSBindArchive(name, env, filepath.Join(tmpdir, "src")) if err != nil { - return fmt.Errorf("darwin-%s: %v", arch, err) + return fmt.Errorf("ios-%s: %v", arch, err) } cmd.Args = append(cmd.Args, "-arch", archClang(arch), path) } diff --git a/cmd/gomobile/bind_test.go b/cmd/gomobile/bind_test.go index b4d0657..5d6796c 100644 --- a/cmd/gomobile/bind_test.go +++ b/cmd/gomobile/bind_test.go @@ -196,7 +196,8 @@ var bindIOSTmpl = template.Must(template.New("output").Parse(`GOMOBILE={{.GOPATH WORK=$WORK GOOS=darwin CGO_ENABLED=1 gobind -lang=go,objc -outdir=$WORK -tags=ios{{if .Prefix}} -prefix={{.Prefix}}{{end}} golang.org/x/mobile/asset mkdir -p $WORK/src -PWD=$WORK/src GOOS=darwin GOARCH=arm64 CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go build -tags ios -x -buildmode=c-archive -o $WORK/{{.Output}}-arm64.a ./gobind +PWD=$WORK/src GOOS=ios GOARCH=arm64 CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy +PWD=$WORK/src GOOS=ios GOARCH=arm64 CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go build -x -buildmode=c-archive -o $WORK/{{.Output}}-arm64.a ./gobind rm -r -f "{{.Output}}.framework" mkdir -p {{.Output}}.framework/Versions/A/Headers ln -s A {{.Output}}.framework/Versions/Current diff --git a/cmd/gomobile/build.go b/cmd/gomobile/build.go index 83571fd..79705ad 100644 --- a/cmd/gomobile/build.go +++ b/cmd/gomobile/build.go @@ -127,13 +127,13 @@ func runBuildImpl(cmd *command) (*packages.Package, error) { if err != nil { return nil, err } - case "darwin": + case "ios": if !xcodeAvailable() { return nil, fmt.Errorf("-target=ios requires XCode") } if pkg.Name != "main" { for _, arch := range targetArchs { - if err := goBuild(pkg.PkgPath, darwinEnv[arch]); err != nil { + if err := goBuild(pkg.PkgPath, iosEnv[arch]); err != nil { return nil, err } } @@ -291,13 +291,6 @@ func goCmd(subcmd string, srcs []string, env []string, args ...string) error { func goCmdAt(at string, subcmd string, srcs []string, env []string, args ...string) error { cmd := exec.Command("go", subcmd) tags := buildTags - targetOS, _, err := parseBuildTarget(buildTarget) - if err != nil { - return err - } - if targetOS == "darwin" { - tags = append(tags, "ios") - } if len(tags) > 0 { cmd.Args = append(cmd.Args, "-tags", strings.Join(tags, " ")) } @@ -378,10 +371,6 @@ func parseBuildTarget(buildTarget string) (os string, archs []string, _ error) { } targetOS := os - if os == "ios" { - targetOS = "darwin" - } - seen := map[string]bool{} for _, arch := range archNames { if _, ok := seen[arch]; ok { diff --git a/cmd/gomobile/build_darwin_test.go b/cmd/gomobile/build_darwin_test.go index 50cf600..41fc382 100644 --- a/cmd/gomobile/build_darwin_test.go +++ b/cmd/gomobile/build_darwin_test.go @@ -104,11 +104,9 @@ mkdir -p $WORK/main echo "{{template "infoplist" .Xinfo}}" > $WORK/main/Info.plist mkdir -p $WORK/main/Images.xcassets/AppIcon.appiconset echo "{{.Xcontents}}" > $WORK/main/Images.xcassets/AppIcon.appiconset/Contents.json{{end}} -GOARM=7 GOOS=darwin GOARCH=arm CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch armv7 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch armv7 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch armv7 CGO_ENABLED=1 go build -tags tag1 ios -x {{if .Main}}-ldflags=-w -o=$WORK/arm {{end}}{{.Pkg}} -GOOS=darwin GOARCH=arm64 CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 go build -tags tag1 ios -x {{if .Main}}-ldflags=-w -o=$WORK/arm64 {{end}}{{.Pkg}} -GOOS=darwin GOARCH=386 CC=iphonesimulator-clang CXX=iphonesimulator-clang++ CGO_CFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch i386 CGO_CXXFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch i386 CGO_LDFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch i386 CGO_ENABLED=1 go build -tags tag1 ios -x {{if .Main}}-ldflags=-w -o=$WORK/386 {{end}}{{.Pkg}} -GOOS=darwin GOARCH=amd64 CC=iphonesimulator-clang CXX=iphonesimulator-clang++ CGO_CFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_CXXFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_LDFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_ENABLED=1 go build -tags tag1 ios -x {{if .Main}}-ldflags=-w -o=$WORK/amd64 {{end}}{{.Pkg}}{{if .Main}} -xcrun lipo -o $WORK/main/main -create $WORK/arm $WORK/arm64 $WORK/386 $WORK/amd64 +GOOS=ios GOARCH=arm64 CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 go build -tags tag1 -x {{if .Main}}-ldflags=-w -o=$WORK/arm64 {{end}}{{.Pkg}} +GOOS=ios GOARCH=amd64 CC=iphonesimulator-clang CXX=iphonesimulator-clang++ CGO_CFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_CXXFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_LDFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_ENABLED=1 go build -tags tag1 -x {{if .Main}}-ldflags=-w -o=$WORK/amd64 {{end}}{{.Pkg}}{{if .Main}} +xcrun lipo -o $WORK/main/main -create $WORK/arm64 $WORK/amd64 mkdir -p $WORK/main/assets xcrun xcodebuild -configuration Release -project $WORK/main.xcodeproj -allowProvisioningUpdates DEVELOPMENT_TEAM={{.TeamID}} mv $WORK/build/Release-iphoneos/main.app basic.app{{end}} diff --git a/cmd/gomobile/build_iosapp.go b/cmd/gomobile/build_iosapp.go index eeb1d7d..e516d27 100644 --- a/cmd/gomobile/build_iosapp.go +++ b/cmd/gomobile/build_iosapp.go @@ -80,12 +80,12 @@ func goIOSBuild(pkg *packages.Package, bundleID string, archs []string) (map[str for _, arch := range archs { path := filepath.Join(tmpdir, arch) // Disable DWARF; see golang.org/issues/25148. - if err := goBuild(src, darwinEnv[arch], "-ldflags=-w", "-o="+path); err != nil { + if err := goBuild(src, iosEnv[arch], "-ldflags=-w", "-o="+path); err != nil { return nil, err } if nmpkgs == nil { var err error - nmpkgs, err = extractPkgs(darwinArmNM, path) + nmpkgs, err = extractPkgs(iosArmNM, path) if err != nil { return nil, err } diff --git a/cmd/gomobile/build_test.go b/cmd/gomobile/build_test.go index eb75bc6..f7eab6c 100644 --- a/cmd/gomobile/build_test.go +++ b/cmd/gomobile/build_test.go @@ -128,10 +128,10 @@ func TestParseBuildTargetFlag(t *testing.T) { {"android,android/arm", false, "android", androidArchs}, {"android/arm", false, "android", "arm"}, - {"ios", false, "darwin", iosArchs}, - {"ios,ios/arm64", false, "darwin", iosArchs}, - {"ios/arm64", false, "darwin", "arm64"}, - {"ios/amd64", false, "darwin", "amd64"}, + {"ios", false, "ios", iosArchs}, + {"ios,ios/arm64", false, "ios", iosArchs}, + {"ios/arm64", false, "ios", "arm64"}, + {"ios/amd64", false, "ios", "amd64"}, {"", true, "", ""}, {"linux", true, "", ""}, diff --git a/cmd/gomobile/doc.go b/cmd/gomobile/doc.go index 5f86054..aeff5f6 100644 --- a/cmd/gomobile/doc.go +++ b/cmd/gomobile/doc.go @@ -9,10 +9,10 @@ Gomobile is a tool for building and running mobile apps written in Go. To install: - $ go get golang.org/x/mobile/cmd/gomobile + $ go install golang.org/x/mobile/cmd/gomobile@latest $ gomobile init -At least Go 1.10 is required. +At least Go 1.16 is required. For detailed instructions, see https://golang.org/wiki/Mobile. Usage: diff --git a/cmd/gomobile/env.go b/cmd/gomobile/env.go index 13b0ab0..de0b46e 100644 --- a/cmd/gomobile/env.go +++ b/cmd/gomobile/env.go @@ -17,10 +17,10 @@ var ( androidEnv map[string][]string // android arch -> []string - darwinEnv map[string][]string + iosEnv map[string][]string androidArmNM string - darwinArmNM string + iosArmNM string bitcodeEnabled bool ) @@ -139,8 +139,8 @@ func envInit() (err error) { return nil } - darwinArmNM = "nm" - darwinEnv = make(map[string][]string) + iosArmNM = "nm" + iosEnv = make(map[string][]string) for _, arch := range allArchs("ios") { var env []string var err error @@ -163,7 +163,7 @@ func envInit() (err error) { cflags += " -fembed-bitcode" } env = append(env, - "GOOS=darwin", + "GOOS=ios", "GOARCH="+arch, "CC="+clang, "CXX="+clang+"++", @@ -172,7 +172,7 @@ func envInit() (err error) { "CGO_LDFLAGS="+cflags+" -arch "+archClang(arch), "CGO_ENABLED=1", ) - darwinEnv[arch] = env + iosEnv[arch] = env } return nil diff --git a/cmd/gomobile/main.go b/cmd/gomobile/main.go index 91b90b4..9814a0d 100644 --- a/cmd/gomobile/main.go +++ b/cmd/gomobile/main.go @@ -94,8 +94,8 @@ func determineGoVersion() error { // Ignore unknown versions; it's probably a devel version. return nil } - if minor < 10 { - return errors.New("Go 1.10 or newer is required") + if minor < 16 { + return errors.New("Go 1.16 or newer is required") } return nil } @@ -186,10 +186,10 @@ var usageTmpl = template.Must(template.New("usage").Parse( To install: - $ go get golang.org/x/mobile/cmd/gomobile + $ go install golang.org/x/mobile/cmd/gomobile@latest $ gomobile init -At least Go 1.10 is required. +At least Go 1.16 is required. For detailed instructions, see https://golang.org/wiki/Mobile. Usage: diff --git a/example/basic/main.go b/example/basic/main.go index 110d052..697fe21 100644 --- a/example/basic/main.go +++ b/example/basic/main.go @@ -7,8 +7,7 @@ // An app that draws a green triangle on a red background. // -// Note: This demo is an early preview of Go 1.5. In order to build this -// program as an Android APK using the gomobile tool. +// In order to build this program as an Android APK, using the gomobile tool. // // See http://godoc.org/golang.org/x/mobile/cmd/gomobile to install gomobile. // diff --git a/go.mod b/go.mod index ec65e6a..c702aa4 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module golang.org/x/mobile -go 1.11 +go 1.16 require ( golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 diff --git a/internal/mobileinit/mobileinit_ios.go b/internal/mobileinit/mobileinit_ios.go index e0d1385..d41b228 100644 --- a/internal/mobileinit/mobileinit_ios.go +++ b/internal/mobileinit/mobileinit_ios.go @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build ios -// +build ios - package mobileinit import (