Gerrit Bot has uploaded this change for review.
cmd/gomobile: support GOOS=ios
This is is a follow-up from my previous PR (#65). It make gomobile aware of GOOS=ios
and adds support for specifying specific Apple platforms, instead of lumping them under
the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,maccatalyst,macos
It also supports the special "darwin" platform which expands to all supported Apple platforms.
This PR also fixes a number of broken iOS tests. Is there a macOS / Xcode trybot for this repo?
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: c7287ff9f6773eeeee7651d23e497dbd9d1a6a4e
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
A cmd/gomobile/build_darwinapp.go
D cmd/gomobile/build_iosapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/init_test.go
M cmd/gomobile/writer_test.go
12 files changed, 905 insertions(+), 808 deletions(-)
diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go
index ef62d05..5c00902 100644
--- a/cmd/gomobile/bind.go
+++ b/cmd/gomobile/bind.go
@@ -76,19 +76,18 @@
args := cmd.flag.Args()
- targetOS, targetArchs, err := parseBuildTarget(buildTarget)
+ targetPlatforms, targetArchs, err := parseBuildTarget(buildTarget)
if err != nil {
return fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
}
- if bindJavaPkg != "" && targetOS != "android" {
- return fmt.Errorf("-javapkg is supported only for android target")
- }
- if bindPrefix != "" && targetOS != "darwin" {
- return fmt.Errorf("-prefix is supported only for ios target")
- }
-
- if targetOS == "android" {
+ if isAndroidPlatform(targetPlatforms[0]) {
+ if bindJavaPkg != "" {
+ return fmt.Errorf("-javapkg is supported only for android target")
+ }
+ if bindPrefix != "" {
+ return fmt.Errorf("-prefix is supported only for darwin targets")
+ }
if _, err := ndkRoot(); err != nil {
return err
}
@@ -98,7 +97,7 @@
if !buildN {
gobind, err = exec.LookPath("gobind")
if err != nil {
- return errors.New("gobind was not found. Please run gomobile init before trying again.")
+ return errors.New("gobind was not found. Please run gomobile init before trying again")
}
} else {
gobind = "gobind"
@@ -107,7 +106,10 @@
if len(args) == 0 {
args = append(args, ".")
}
- pkgs, err := importPackages(args, targetOS)
+
+ // TODO(ydnar): this should work, unless build tags affect loading a single package.
+ // Should we try to import packages with different build tags per platform?
+ pkgs, err := packages.Load(packagesConfig(targetPlatforms[0]), args...)
if err != nil {
return err
}
@@ -115,28 +117,23 @@
// check if any of the package is main
for _, pkg := range pkgs {
if pkg.Name == "main" {
- return fmt.Errorf("binding 'main' package (%s) is not supported", pkg.PkgPath)
+ return fmt.Errorf(`binding "main" package (%s) is not supported`, pkg.PkgPath)
}
}
- switch targetOS {
- case "android":
+ switch {
+ case isAndroidPlatform(targetPlatforms[0]):
return goAndroidBind(gobind, pkgs, targetArchs)
- case "darwin":
+ case isDarwinPlatform(targetPlatforms[0]):
if !xcodeAvailable() {
- return fmt.Errorf("-target=ios requires XCode")
+ return fmt.Errorf("-target=%q requires Xcode", buildTarget)
}
- return goIOSBind(gobind, pkgs, targetArchs)
+ return goDarwinbind(gobind, pkgs, targetPlatforms, targetArchs)
default:
return fmt.Errorf(`invalid -target=%q`, buildTarget)
}
}
-func importPackages(args []string, targetOS string) ([]*packages.Package, error) {
- config := packagesConfig(targetOS)
- return packages.Load(config, args...)
-}
-
var (
bindPrefix string // -prefix
bindJavaPkg string // -javapkg
@@ -212,14 +209,13 @@
return generate(f)
}
-func packagesConfig(targetOS string) *packages.Config {
+func packagesConfig(targetPlatform string) *packages.Config {
config := &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")
- }
+ config.Env = append(os.Environ(), "GOARCH=arm64", "GOOS="+platformOS(targetPlatform), "CGO_ENABLED=1")
+
+ tags := append(buildTags[:], platformTags(targetPlatform)...)
+
if len(tags) > 0 {
config.BuildFlags = []string{"-tags=" + strings.Join(tags, ",")}
}
@@ -227,14 +223,12 @@
}
// getModuleVersions returns a module information at the directory src.
-func getModuleVersions(targetOS string, targetArch string, src string) (*modfile.File, error) {
+func getModuleVersions(targetPlatform string, targetArch string, src string) (*modfile.File, error) {
cmd := exec.Command("go", "list")
- cmd.Env = append(os.Environ(), "GOOS="+targetOS, "GOARCH="+targetArch)
+ cmd.Env = append(os.Environ(), "GOOS="+platformOS(targetPlatform), "GOARCH="+targetArch)
- tags := buildTags
- if targetOS == "darwin" {
- tags = append(tags, "ios")
- }
+ tags := append(buildTags[:], platformTags(targetPlatform)...)
+
// 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
@@ -287,7 +281,7 @@
}
// writeGoMod writes go.mod file at $WORK/src when Go modules are used.
-func writeGoMod(targetOS string, targetArch string) error {
+func writeGoMod(targetPlatform string, targetArch string) error {
m, err := areGoModulesUsed()
if err != nil {
return err
@@ -298,7 +292,7 @@
}
return writeFile(filepath.Join(tmpdir, "src", "go.mod"), func(w io.Writer) error {
- f, err := getModuleVersions(targetOS, targetArch, ".")
+ f, err := getModuleVersions(targetPlatform, targetArch, ".")
if err != nil {
return err
}
diff --git a/cmd/gomobile/bind_iosapp.go b/cmd/gomobile/bind_darwinapp.go
similarity index 84%
rename from cmd/gomobile/bind_iosapp.go
rename to cmd/gomobile/bind_darwinapp.go
index 83d9e3f..05a1472 100644
--- a/cmd/gomobile/bind_iosapp.go
+++ b/cmd/gomobile/bind_darwinapp.go
@@ -5,26 +5,29 @@
package main
import (
+ "errors"
"fmt"
"io"
"os/exec"
"path/filepath"
+ "strconv"
"strings"
"text/template"
"golang.org/x/tools/go/packages"
)
-func goIOSBind(gobind string, pkgs []*packages.Package, archs []string) error {
+func goDarwinbind(gobind string, pkgs []*packages.Package, targetPlatforms, targetArchs []string) error {
// Run gobind to generate the bindings
cmd := exec.Command(
gobind,
"-lang=go,objc",
"-outdir="+tmpdir,
)
- cmd.Env = append(cmd.Env, "GOOS=darwin")
+ cmd.Env = append(cmd.Env, "GOOS=ios")
cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
- tags := append(buildTags, "ios")
+ // TODO(ydnar): move this cmd into the inner platform loop below
+ tags := append(buildTags, platformTags(targetPlatforms[0])...)
cmd.Args = append(cmd.Args, "-tags="+strings.Join(tags, ","))
if bindPrefix != "" {
cmd.Args = append(cmd.Args, "-prefix="+bindPrefix)
@@ -66,20 +69,31 @@
// create separate framework for ios,simulator and catalyst
// every target has at least one arch (arm64 and x86_64)
var frameworkDirs []string
- for _, target := range iOSTargets {
- frameworkDir := filepath.Join(tmpdir, target, title+".framework")
+ for _, platform := range targetPlatforms {
+ // 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")
+ }
+
+ frameworkDir := filepath.Join(tmpdir, platform, title+".framework")
frameworkDirs = append(frameworkDirs, frameworkDir)
- for index, arch := range iOSTargetArchs(target) {
+ for index, arch := range platformArchs(platform) {
+ // Skip unrequested architectures
+ if !contains(targetArchs, arch) {
+ continue
+ }
+
fileBases := make([]string, len(pkgs)+1)
for i, pkg := range pkgs {
fileBases[i] = bindPrefix + strings.Title(pkg.Name)
}
fileBases[len(fileBases)-1] = "Universe"
- env := darwinEnv[target+"_"+arch]
+ env := darwinEnv[platform+"/"+arch]
- if err := writeGoMod("darwin", getenv(env, "GOARCH")); err != nil {
+ if err := writeGoMod(platform, getenv(env, "GOARCH")); err != nil {
return err
}
@@ -95,9 +109,9 @@
}
}
- path, err := goIOSBindArchive(name, env, filepath.Join(tmpdir, "src"))
+ path, err := goDarwinBindArchive(name+"-"+platform+"-"+arch, env, filepath.Join(tmpdir, "src"))
if err != nil {
- return fmt.Errorf("darwin-%s: %v", arch, err)
+ return fmt.Errorf("%s/%s: %v", platform, arch, err)
}
versionsDir := filepath.Join(frameworkDir, "Versions")
@@ -239,9 +253,8 @@
export *
}`))
-func goIOSBindArchive(name string, env []string, gosrc string) (string, error) {
- arch := getenv(env, "GOARCH")
- archive := filepath.Join(tmpdir, name+"-"+arch+".a")
+func goDarwinBindArchive(name string, env []string, gosrc string) (string, error) {
+ archive := filepath.Join(tmpdir, name+".a")
err := goBuildAt(gosrc, "./gobind", env, "-buildmode=c-archive", "-o", archive)
if err != nil {
return "", err
diff --git a/cmd/gomobile/bind_test.go b/cmd/gomobile/bind_test.go
index fed8142..805e2fa 100644
--- a/cmd/gomobile/bind_test.go
+++ b/cmd/gomobile/bind_test.go
@@ -194,29 +194,29 @@
var bindIOSTmpl = template.Must(template.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile
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
+GOOS=ios CGO_ENABLED=1 gobind -lang=go,objc -outdir=$WORK -tags=ios{{if .Prefix}} -prefix={{.Prefix}}{{end}} golang.org/x/mobile/asset
rm -r -f "{{.Output}}.xcframework"
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
-mkdir -p $WORK/arm64/{{.Output}}.framework/Versions/A/Headers
-ln -s A $WORK/arm64/{{.Output}}.framework/Versions/Current
-ln -s Versions/Current/Headers $WORK/arm64/{{.Output}}.framework/Headers
-ln -s Versions/Current/{{.Output}} $WORK/arm64/{{.Output}}.framework/{{.Output}}
-xcrun lipo -create -arch arm64 $WORK/{{.Output}}-arm64.a -o $WORK/arm64/{{.Output}}.framework/Versions/A/{{.Output}}
-cp $WORK/src/gobind/{{.Prefix}}Asset.objc.h $WORK/arm64/{{.Output}}.framework/Versions/A/Headers/{{.Prefix}}Asset.objc.h
-mkdir -p $WORK/arm64/{{.Output}}.framework/Versions/A/Headers
-cp $WORK/src/gobind/Universe.objc.h $WORK/arm64/{{.Output}}.framework/Versions/A/Headers/Universe.objc.h
-mkdir -p $WORK/arm64/{{.Output}}.framework/Versions/A/Headers
-cp $WORK/src/gobind/ref.h $WORK/arm64/{{.Output}}.framework/Versions/A/Headers/ref.h
-mkdir -p $WORK/arm64/{{.Output}}.framework/Versions/A/Headers
-mkdir -p $WORK/arm64/{{.Output}}.framework/Versions/A/Headers
-mkdir -p $WORK/arm64/{{.Output}}.framework/Versions/A/Resources
-ln -s Versions/Current/Resources $WORK/arm64/{{.Output}}.framework/Resources
-mkdir -p $WORK/arm64/{{.Output}}.framework/Resources
-mkdir -p $WORK/arm64/{{.Output}}.framework/Versions/A/Modules
-ln -s Versions/Current/Modules $WORK/arm64/{{.Output}}.framework/Modules
-xcrun lipo $WORK/arm64/{{.Output}}.framework/Versions/A/{{.Output}} -thin arm64 -output $WORK/arm64/{{.Output}}.framework/Versions/A/{{.Output}}
-xcodebuild -create-xcframework -framework $WORK/arm64/{{.Output}}.framework -framework $WORK/amd64/{{.Output}}.framework -framework $WORK/catalyst/{{.Output}}.framework -output {{.Output}}.xcframework
+PWD=$WORK/src GOOS=ios GOARCH=arm64 GOFLAGS=-tags=ios CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go mod tidy
+PWD=$WORK/src GOOS=ios GOARCH=arm64 GOFLAGS=-tags=ios CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 GOPATH=$WORK:$GOPATH go build -x -buildmode=c-archive -o $WORK/{{.Output}}-ios-arm64.a ./gobind
+mkdir -p $WORK/ios/{{.Output}}.framework/Versions/A/Headers
+ln -s A $WORK/ios/{{.Output}}.framework/Versions/Current
+ln -s Versions/Current/Headers $WORK/ios/{{.Output}}.framework/Headers
+ln -s Versions/Current/{{.Output}} $WORK/ios/{{.Output}}.framework/{{.Output}}
+xcrun lipo -create -arch arm64 $WORK/{{.Output}}-ios-arm64.a -o $WORK/ios/{{.Output}}.framework/Versions/A/{{.Output}}
+cp $WORK/src/gobind/{{.Prefix}}Asset.objc.h $WORK/ios/{{.Output}}.framework/Versions/A/Headers/{{.Prefix}}Asset.objc.h
+mkdir -p $WORK/ios/{{.Output}}.framework/Versions/A/Headers
+cp $WORK/src/gobind/Universe.objc.h $WORK/ios/{{.Output}}.framework/Versions/A/Headers/Universe.objc.h
+mkdir -p $WORK/ios/{{.Output}}.framework/Versions/A/Headers
+cp $WORK/src/gobind/ref.h $WORK/ios/{{.Output}}.framework/Versions/A/Headers/ref.h
+mkdir -p $WORK/ios/{{.Output}}.framework/Versions/A/Headers
+mkdir -p $WORK/ios/{{.Output}}.framework/Versions/A/Headers
+mkdir -p $WORK/ios/{{.Output}}.framework/Versions/A/Resources
+ln -s Versions/Current/Resources $WORK/ios/{{.Output}}.framework/Resources
+mkdir -p $WORK/ios/{{.Output}}.framework/Resources
+mkdir -p $WORK/ios/{{.Output}}.framework/Versions/A/Modules
+ln -s Versions/Current/Modules $WORK/ios/{{.Output}}.framework/Modules
+xcodebuild -create-xcframework -framework $WORK/ios/{{.Output}}.framework -framework $WORK/iossimulator/{{.Output}}.framework -output {{.Output}}.xcframework
`))
func TestBindIOSAll(t *testing.T) {
diff --git a/cmd/gomobile/build.go b/cmd/gomobile/build.go
index 072af00..65b2b73 100644
--- a/cmd/gomobile/build.go
+++ b/cmd/gomobile/build.go
@@ -8,11 +8,13 @@
import (
"bufio"
+ "errors"
"fmt"
"io"
"os"
"os/exec"
"regexp"
+ "strconv"
"strings"
"golang.org/x/tools/go/packages"
@@ -47,7 +49,7 @@
are copied into the output.
Flag -iosversion sets the minimal version of the iOS SDK to compile against.
-The default version is 7.0.
+The default version is 13.0.
Flag -androidapi sets the Android API version to compile against.
The default and minimum is 15.
@@ -81,7 +83,7 @@
args := cmd.flag.Args()
- targetOS, targetArchs, err := parseBuildTarget(buildTarget)
+ targetPlatforms, targetArchs, err := parseBuildTarget(buildTarget)
if err != nil {
return nil, fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
}
@@ -96,10 +98,14 @@
cmd.usage()
os.Exit(1)
}
- pkgs, err := packages.Load(packagesConfig(targetOS), buildPath)
+
+ // TODO(ydnar): this should work, unless build tags affect loading a single package.
+ // Should we try to import packages with different build tags per platform?
+ pkgs, err := packages.Load(packagesConfig(targetPlatforms[0]), buildPath)
if err != nil {
return nil, err
}
+
// len(pkgs) can be more than 1 e.g., when the specified path includes `...`.
if len(pkgs) != 1 {
cmd.usage()
@@ -113,8 +119,8 @@
}
var nmpkgs map[string]bool
- switch targetOS {
- case "android":
+ switch {
+ case isAndroidPlatform(targetPlatforms[0]):
if pkg.Name != "main" {
for _, arch := range targetArchs {
if err := goBuild(pkg.PkgPath, androidEnv[arch]); err != nil {
@@ -127,14 +133,26 @@
if err != nil {
return nil, err
}
- case "darwin":
+ case isDarwinPlatform(targetPlatforms[0]):
if !xcodeAvailable() {
- return nil, fmt.Errorf("-target=ios requires XCode")
+ return nil, fmt.Errorf("-target=%s requires XCode", buildTarget)
}
if pkg.Name != "main" {
- for _, arch := range targetArchs {
- if err := goBuild(pkg.PkgPath, darwinEnv[arch]); err != nil {
- return nil, err
+ for _, platform := range targetPlatforms {
+ // Catalyst support requires iOS 13+
+ v, _ := strconv.ParseFloat(buildIOSVersion, 64)
+ if platform == "maccatalyst" && v < 13.0 {
+ return nil, errors.New("catalyst requires -iosversion=13 or higher")
+ }
+
+ for _, arch := range platformArchs(platform) {
+ // Skip unrequested architectures
+ if !contains(targetArchs, arch) {
+ continue
+ }
+ if err := goBuild(pkg.PkgPath, darwinEnv[platform+"/"+arch]); err != nil {
+ return nil, err
+ }
}
}
return pkg, nil
@@ -142,7 +160,7 @@
if buildBundleID == "" {
return nil, fmt.Errorf("-target=ios requires -bundleid set")
}
- nmpkgs, err = goIOSBuild(pkg, buildBundleID, targetArchs)
+ nmpkgs, err = goDarwinBuild(pkg, buildBundleID, targetPlatforms, targetArchs)
if err != nil {
return nil, err
}
@@ -155,7 +173,7 @@
return pkg, nil
}
-var nmRE = regexp.MustCompile(`[0-9a-f]{8} t (?:.*/vendor/)?(golang.org/x.*/[^.]*)`)
+var nmRE = regexp.MustCompile(`[0-9a-f]{8} t (?:.*/vendor/|_)?(golang.org/x.*/[^.]*)`)
func extractPkgs(nm string, path string) (map[string]bool, error) {
if buildN {
@@ -236,7 +254,7 @@
cmd.flag.StringVar(&buildLdflags, "ldflags", "", "")
cmd.flag.StringVar(&buildTarget, "target", "android", "")
cmd.flag.StringVar(&buildBundleID, "bundleid", "", "")
- cmd.flag.StringVar(&buildIOSVersion, "iosversion", "7.0", "")
+ cmd.flag.StringVar(&buildIOSVersion, "iosversion", "13.0", "")
cmd.flag.IntVar(&buildAndroidAPI, "androidapi", minAndroidAPI, "")
cmd.flag.BoolVar(&buildA, "a", false, "")
@@ -291,15 +309,8 @@
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, " "))
+ cmd.Args = append(cmd.Args, "-tags", strings.Join(tags, ","))
}
if buildV {
cmd.Args = append(cmd.Args, "-v")
@@ -339,64 +350,68 @@
return runCmd(cmd)
}
-func parseBuildTarget(buildTarget string) (os string, archs []string, _ error) {
+// parseBuildTarget parses buildTarget into 1 or more platforms and architectures.
+// Returns an error if buildTarget contains invalid input.
+// Example valid target strings:
+// android
+// android/arm64,android/386,android/amd64
+// ios,simulator,catalyst
+// macos/amd64
+// darwin
+func parseBuildTarget(buildTarget string) (targetPlatforms, targetArchs []string, _ error) {
if buildTarget == "" {
- return "", nil, fmt.Errorf(`invalid target ""`)
+ return nil, nil, fmt.Errorf(`invalid target ""`)
}
- all := false
- archNames := []string{}
- for i, p := range strings.Split(buildTarget, ",") {
- osarch := strings.SplitN(p, "/", 2) // len(osarch) > 0
- if osarch[0] != "android" && osarch[0] != "ios" {
- return "", nil, fmt.Errorf(`unsupported os`)
+ platforms := map[string]bool{}
+ archs := map[string]bool{}
+
+ var isAndroid, isDarwin bool
+ for _, target := range strings.Split(buildTarget, ",") {
+ tuple := strings.SplitN(target, "/", 2)
+ platform := tuple[0]
+ hasArch := len(tuple) == 2
+
+ if isAndroidPlatform(platform) {
+ isAndroid = true
+ }
+ if isDarwinPlatform(platform) {
+ isDarwin = true
+ }
+ if isAndroid && isDarwin {
+ return nil, nil, fmt.Errorf(`cannot mix android and darwin platforms`)
}
- if i == 0 {
- os = osarch[0]
+ expanded, err := expandPlatform(platform)
+ if err != nil {
+ return nil, nil, err
}
-
- if os != osarch[0] {
- return "", nil, fmt.Errorf(`cannot target different OSes`)
- }
-
- if len(osarch) == 1 {
- all = true
- } else {
- archNames = append(archNames, osarch[1])
- }
- }
-
- // verify all archs are supported one while deduping.
- isSupported := func(os, arch string) bool {
- for _, a := range allArchs(os) {
- if a == arch {
- return true
+ for _, p := range expanded {
+ if !platforms[p] {
+ platforms[p] = true
+ targetPlatforms = append(targetPlatforms, p)
+ if !hasArch {
+ for _, arch := range platformArchs(p) {
+ if !archs[arch] {
+ archs[arch] = true
+ targetArchs = append(targetArchs, arch)
+ }
+ }
+ }
}
}
- return false
- }
- targetOS := os
- if os == "ios" {
- targetOS = "darwin"
- }
-
- seen := map[string]bool{}
- for _, arch := range archNames {
- if _, ok := seen[arch]; ok {
- continue
+ if hasArch {
+ arch := tuple[1]
+ if !isSupportedArch(platform, arch) {
+ return nil, nil, fmt.Errorf(`unsupported platform/arch: %q`, target)
+ }
+ if !archs[arch] {
+ archs[arch] = true
+ targetArchs = append(targetArchs, arch)
+ }
}
- if !isSupported(os, arch) {
- return "", nil, fmt.Errorf(`unsupported arch: %q`, arch)
- }
-
- seen[arch] = true
- archs = append(archs, arch)
}
- if all {
- return targetOS, allArchs(os), nil
- }
- return targetOS, archs, nil
+ return targetPlatforms, targetArchs, nil
}
diff --git a/cmd/gomobile/build_darwin_test.go b/cmd/gomobile/build_darwin_test.go
index cfe42c9..781777a 100644
--- a/cmd/gomobile/build_darwin_test.go
+++ b/cmd/gomobile/build_darwin_test.go
@@ -12,7 +12,7 @@
"text/template"
)
-func TestIOSBuild(t *testing.T) {
+func TestDarwinBuild(t *testing.T) {
defer func() {
xout = os.Stderr
buildN = false
@@ -20,14 +20,9 @@
}()
buildN = true
buildX = true
- buildTarget = "ios"
+ buildTarget = "darwin"
buildBundleID = "org.golang.todo"
gopath = filepath.SplitList(goEnv("GOPATH"))[0]
- oldTags := buildTags
- buildTags = []string{"tag1"}
- defer func() {
- buildTags = oldTags
- }()
tests := []struct {
pkg string
main bool
@@ -43,7 +38,7 @@
} else {
buildO = ""
}
- cmdBuild.flag.Parse([]string{test.pkg})
+ cmdBuild.flag.Parse([]string{"-tags", "tag1", test.pkg})
err := runBuild(cmdBuild)
if err != nil {
t.Log(buf.String())
@@ -101,11 +96,13 @@
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 GOFLAGS=-tags=ios CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 go build -tags tag1 -x {{if .Main}}-ldflags=-w -o=$WORK/ios/arm64 {{end}}{{.Pkg}}
+GOOS=ios GOARCH=amd64 GOFLAGS=-tags=ios,iossimulator CC=iphonesimulator-clang CXX=iphonesimulator-clang++ CGO_CFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_CXXFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_LDFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=13.0 {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_ENABLED=1 go build -tags tag1 -x {{if .Main}}-ldflags=-w -o=$WORK/iossimulator/amd64 {{end}}{{.Pkg}}
+GOOS=darwin GOARCH=arm64 GOFLAGS=-tags=macos,maccatalyst CC=macosx-clang CXX=macosx-clang++ CGO_CFLAGS=-isysroot=macosx -target arm64-apple-ios13.0-macabi {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=macosx -target arm64-apple-ios13.0-macabi {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=macosx -target arm64-apple-ios13.0-macabi {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 go build -tags tag1 -x {{if .Main}}-ldflags=-w -o=$WORK/maccatalyst/arm64 {{end}}{{.Pkg}}
+GOOS=darwin GOARCH=amd64 GOFLAGS=-tags=macos,maccatalyst CC=macosx-clang CXX=macosx-clang++ CGO_CFLAGS=-isysroot=macosx -target x86_64-apple-ios13.0-macabi {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_CXXFLAGS=-isysroot=macosx -target x86_64-apple-ios13.0-macabi {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_LDFLAGS=-isysroot=macosx -target x86_64-apple-ios13.0-macabi {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_ENABLED=1 go build -tags tag1 -x {{if .Main}}-ldflags=-w -o=$WORK/maccatalyst/amd64 {{end}}{{.Pkg}}
+GOOS=darwin GOARCH=arm64 GOFLAGS=-tags=macos CC=macosx-clang CXX=macosx-clang++ CGO_CFLAGS=-isysroot=macosx {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_CXXFLAGS=-isysroot=macosx {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_LDFLAGS=-isysroot=macosx {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch arm64 CGO_ENABLED=1 go build -tags tag1 -x {{if .Main}}-ldflags=-w -o=$WORK/macos/arm64 {{end}}{{.Pkg}}
+GOOS=darwin GOARCH=amd64 GOFLAGS=-tags=macos CC=macosx-clang CXX=macosx-clang++ CGO_CFLAGS=-isysroot=macosx {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_CXXFLAGS=-isysroot=macosx {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_LDFLAGS=-isysroot=macosx {{if .BitcodeEnabled}}-fembed-bitcode {{end}}-arch x86_64 CGO_ENABLED=1 go build -tags tag1 -x {{if .Main}}-ldflags=-w -o=$WORK/macos/amd64 {{end}}{{.Pkg}}{{if .Main}}
+xcrun lipo -o $WORK/main/main -create $WORK/ios/arm64 $WORK/iossimulator/amd64 $WORK/maccatalyst/arm64 $WORK/maccatalyst/amd64 $WORK/macos/arm64 $WORK/macos/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_darwinapp.go b/cmd/gomobile/build_darwinapp.go
new file mode 100644
index 0000000..7966b79
--- /dev/null
+++ b/cmd/gomobile/build_darwinapp.go
@@ -0,0 +1,616 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "crypto/x509"
+ "encoding/pem"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "strings"
+ "text/template"
+
+ "golang.org/x/tools/go/packages"
+)
+
+func goDarwinBuild(pkg *packages.Package, bundleID string, targetPlatforms, targetArchs []string) (map[string]bool, error) {
+ src := pkg.PkgPath
+ if buildO != "" && !strings.HasSuffix(buildO, ".app") {
+ return nil, fmt.Errorf("-o must have an .app for -target=ios")
+ }
+
+ productName := rfc1034Label(path.Base(pkg.PkgPath))
+ if productName == "" {
+ productName = "ProductName" // like xcode.
+ }
+
+ projPbxproj := new(bytes.Buffer)
+ if err := projPbxprojTmpl.Execute(projPbxproj, projPbxprojTmplData{
+ BitcodeEnabled: bitcodeEnabled,
+ }); err != nil {
+ return nil, err
+ }
+
+ infoplist := new(bytes.Buffer)
+ if err := infoplistTmpl.Execute(infoplist, infoplistTmplData{
+ // TODO: better bundle id.
+ BundleID: bundleID + "." + productName,
+ Name: strings.Title(path.Base(pkg.PkgPath)),
+ }); err != nil {
+ return nil, err
+ }
+
+ files := []struct {
+ name string
+ contents []byte
+ }{
+ {tmpdir + "/main.xcodeproj/project.pbxproj", projPbxproj.Bytes()},
+ {tmpdir + "/main/Info.plist", infoplist.Bytes()},
+ {tmpdir + "/main/Images.xcassets/AppIcon.appiconset/Contents.json", []byte(contentsJSON)},
+ }
+
+ for _, file := range files {
+ if err := mkdir(filepath.Dir(file.name)); err != nil {
+ return nil, err
+ }
+ if buildX {
+ printcmd("echo \"%s\" > %s", file.contents, file.name)
+ }
+ if !buildN {
+ if err := ioutil.WriteFile(file.name, file.contents, 0644); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ // We are using lipo tool to build multiarchitecture binaries.
+ cmd := exec.Command(
+ "xcrun", "lipo",
+ "-o", filepath.Join(tmpdir, "main/main"),
+ "-create",
+ )
+
+ var nmpkgs map[string]bool
+ for _, platform := range targetPlatforms {
+ for _, arch := range platformArchs(platform) {
+ // Skip unrequested architectures
+ if !contains(targetArchs, arch) {
+ continue
+ }
+
+ path := filepath.Join(tmpdir, platform, arch)
+
+ // Disable DWARF; see golang.org/issues/25148.
+ if err := goBuild(src, darwinEnv[platform+"/"+arch], "-ldflags=-w", "-o="+path); err != nil {
+ return nil, err
+ }
+ if nmpkgs == nil {
+ var err error
+ nmpkgs, err = extractPkgs(darwinArmNM, path)
+ if err != nil {
+ return nil, err
+ }
+ }
+ cmd.Args = append(cmd.Args, path)
+ }
+ }
+
+ if err := runCmd(cmd); err != nil {
+ return nil, err
+ }
+
+ // TODO(jbd): Set the launcher icon.
+ if err := iosCopyAssets(pkg, tmpdir); err != nil {
+ return nil, err
+ }
+
+ // Detect the team ID
+ teamID, err := detectTeamID()
+ if err != nil {
+ return nil, err
+ }
+
+ // Build and move the release build to the output directory.
+ cmdStrings := []string{
+ "xcodebuild",
+ "-configuration", "Release",
+ "-project", tmpdir + "/main.xcodeproj",
+ "-allowProvisioningUpdates",
+ "DEVELOPMENT_TEAM=" + teamID,
+ }
+
+ cmd = exec.Command("xcrun", cmdStrings...)
+ if err := runCmd(cmd); err != nil {
+ return nil, err
+ }
+
+ // TODO(jbd): Fallback to copying if renaming fails.
+ if buildO == "" {
+ n := pkg.PkgPath
+ if n == "." {
+ // use cwd name
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, fmt.Errorf("cannot create .app; cannot get the current working dir: %v", err)
+ }
+ n = cwd
+ }
+ n = path.Base(n)
+ buildO = n + ".app"
+ }
+ if buildX {
+ printcmd("mv %s %s", tmpdir+"/build/Release-iphoneos/main.app", buildO)
+ }
+ if !buildN {
+ // if output already exists, remove.
+ if err := os.RemoveAll(buildO); err != nil {
+ return nil, err
+ }
+ if err := os.Rename(tmpdir+"/build/Release-iphoneos/main.app", buildO); err != nil {
+ return nil, err
+ }
+ }
+ return nmpkgs, nil
+}
+
+func detectTeamID() (string, error) {
+ // Grabs the first certificate for "Apple Development"; will not work if there
+ // are multiple certificates and the first is not desired.
+ cmd := exec.Command(
+ "security", "find-certificate",
+ "-c", "Apple Development", "-p",
+ )
+ pemString, err := cmd.Output()
+ if err != nil {
+ err = fmt.Errorf("failed to pull the signing certificate to determine your team ID: %v", err)
+ return "", err
+ }
+
+ block, _ := pem.Decode(pemString)
+ if block == nil {
+ err = fmt.Errorf("failed to decode the PEM to determine your team ID: %s", pemString)
+ return "", err
+ }
+
+ cert, err := x509.ParseCertificate(block.Bytes)
+ if err != nil {
+ err = fmt.Errorf("failed to parse your signing certificate to determine your team ID: %v", err)
+ return "", err
+ }
+
+ if len(cert.Subject.OrganizationalUnit) == 0 {
+ err = fmt.Errorf("the signing certificate has no organizational unit (team ID).")
+ return "", err
+ }
+
+ return cert.Subject.OrganizationalUnit[0], nil
+}
+
+func iosCopyAssets(pkg *packages.Package, xcodeProjDir string) error {
+ dstAssets := xcodeProjDir + "/main/assets"
+ if err := mkdir(dstAssets); err != nil {
+ return err
+ }
+
+ // TODO(hajimehoshi): This works only with Go tools that assume all source files are in one directory.
+ // Fix this to work with other Go tools.
+ srcAssets := filepath.Join(filepath.Dir(pkg.GoFiles[0]), "assets")
+ fi, err := os.Stat(srcAssets)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // skip walking through the directory to deep copy.
+ return nil
+ }
+ return err
+ }
+ if !fi.IsDir() {
+ // skip walking through to deep copy.
+ return nil
+ }
+ // if assets is a symlink, follow the symlink.
+ srcAssets, err = filepath.EvalSymlinks(srcAssets)
+ if err != nil {
+ return err
+ }
+ return filepath.Walk(srcAssets, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ if name := filepath.Base(path); strings.HasPrefix(name, ".") {
+ // Do not include the hidden files.
+ return nil
+ }
+ if info.IsDir() {
+ return nil
+ }
+ dst := dstAssets + "/" + path[len(srcAssets)+1:]
+ return copyFile(dst, path)
+ })
+}
+
+type infoplistTmplData struct {
+ BundleID string
+ Name string
+}
+
+var infoplistTmpl = template.Must(template.New("infoplist").Parse(`<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>main</string>
+ <key>CFBundleIdentifier</key>
+ <string>{{.BundleID}}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>{{.Name}}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
+`))
+
+type projPbxprojTmplData struct {
+ BitcodeEnabled bool
+}
+
+var projPbxprojTmpl = template.Must(template.New("projPbxproj").Parse(`// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 254BB84F1B1FD08900C56DE9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 254BB84E1B1FD08900C56DE9 /* Images.xcassets */; };
+ 254BB8681B1FD16500C56DE9 /* main in Resources */ = {isa = PBXBuildFile; fileRef = 254BB8671B1FD16500C56DE9 /* main */; };
+ 25FB30331B30FDEE0005924C /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 25FB30321B30FDEE0005924C /* assets */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 254BB83E1B1FD08900C56DE9 /* main.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = main.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 254BB8421B1FD08900C56DE9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 254BB84E1B1FD08900C56DE9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
+ 254BB8671B1FD16500C56DE9 /* main */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = main; sourceTree = "<group>"; };
+ 25FB30321B30FDEE0005924C /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = assets; path = main/assets; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXGroup section */
+ 254BB8351B1FD08900C56DE9 = {
+ isa = PBXGroup;
+ children = (
+ 25FB30321B30FDEE0005924C /* assets */,
+ 254BB8401B1FD08900C56DE9 /* main */,
+ 254BB83F1B1FD08900C56DE9 /* Products */,
+ );
+ sourceTree = "<group>";
+ usesTabs = 0;
+ };
+ 254BB83F1B1FD08900C56DE9 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 254BB83E1B1FD08900C56DE9 /* main.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 254BB8401B1FD08900C56DE9 /* main */ = {
+ isa = PBXGroup;
+ children = (
+ 254BB8671B1FD16500C56DE9 /* main */,
+ 254BB84E1B1FD08900C56DE9 /* Images.xcassets */,
+ 254BB8411B1FD08900C56DE9 /* Supporting Files */,
+ );
+ path = main;
+ sourceTree = "<group>";
+ };
+ 254BB8411B1FD08900C56DE9 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 254BB8421B1FD08900C56DE9 /* Info.plist */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 254BB83D1B1FD08900C56DE9 /* main */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 254BB8611B1FD08900C56DE9 /* Build configuration list for PBXNativeTarget "main" */;
+ buildPhases = (
+ 254BB83C1B1FD08900C56DE9 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = main;
+ productName = main;
+ productReference = 254BB83E1B1FD08900C56DE9 /* main.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 254BB8361B1FD08900C56DE9 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0630;
+ ORGANIZATIONNAME = Developer;
+ TargetAttributes = {
+ 254BB83D1B1FD08900C56DE9 = {
+ CreatedOnToolsVersion = 6.3.1;
+ };
+ };
+ };
+ buildConfigurationList = 254BB8391B1FD08900C56DE9 /* Build configuration list for PBXProject "main" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 254BB8351B1FD08900C56DE9;
+ productRefGroup = 254BB83F1B1FD08900C56DE9 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 254BB83D1B1FD08900C56DE9 /* main */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 254BB83C1B1FD08900C56DE9 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 25FB30331B30FDEE0005924C /* assets in Resources */,
+ 254BB8681B1FD16500C56DE9 /* main in Resources */,
+ 254BB84F1B1FD08900C56DE9 /* Images.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 254BB8601B1FD08900C56DE9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ {{if not .BitcodeEnabled}}ENABLE_BITCODE = NO;{{end}}
+ };
+ name = Release;
+ };
+ 254BB8631B1FD08900C56DE9 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = main/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 254BB8391B1FD08900C56DE9 /* Build configuration list for PBXProject "main" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 254BB8601B1FD08900C56DE9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 254BB8611B1FD08900C56DE9 /* Build configuration list for PBXNativeTarget "main" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 254BB8631B1FD08900C56DE9 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 254BB8361B1FD08900C56DE9 /* Project object */;
+}
+`))
+
+const contentsJSON = `{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
+`
+
+// rfc1034Label sanitizes the name to be usable in a uniform type identifier.
+// The sanitization is similar to xcode's rfc1034identifier macro that
+// replaces illegal characters (not conforming the rfc1034 label rule) with '-'.
+func rfc1034Label(name string) string {
+ // * Uniform type identifier:
+ //
+ // According to
+ // https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html
+ //
+ // A uniform type identifier is a Unicode string that usually contains characters
+ // in the ASCII character set. However, only a subset of the ASCII characters are
+ // permitted. You may use the Roman alphabet in upper and lower case (A–Z, a–z),
+ // the digits 0 through 9, the dot (“.”), and the hyphen (“-”). This restriction
+ // is based on DNS name restrictions, set forth in RFC 1035.
+ //
+ // Uniform type identifiers may also contain any of the Unicode characters greater
+ // than U+007F.
+ //
+ // Note: the actual implementation of xcode does not allow some unicode characters
+ // greater than U+007f. In this implementation, we just replace everything non
+ // alphanumeric with "-" like the rfc1034identifier macro.
+ //
+ // * RFC1034 Label
+ //
+ // <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+ // <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+ // <let-dig-hyp> ::= <let-dig> | "-"
+ // <let-dig> ::= <letter> | <digit>
+ const surrSelf = 0x10000
+ begin := false
+
+ var res []rune
+ for i, r := range name {
+ if r == '.' && !begin {
+ continue
+ }
+ begin = true
+
+ switch {
+ case 'a' <= r && r <= 'z', 'A' <= r && r <= 'Z':
+ res = append(res, r)
+ case '0' <= r && r <= '9':
+ if i == 0 {
+ res = append(res, '-')
+ } else {
+ res = append(res, r)
+ }
+ default:
+ if r < surrSelf {
+ res = append(res, '-')
+ } else {
+ res = append(res, '-', '-')
+ }
+ }
+ }
+ return string(res)
+}
diff --git a/cmd/gomobile/build_iosapp.go b/cmd/gomobile/build_iosapp.go
deleted file mode 100644
index 67fe3b5..0000000
--- a/cmd/gomobile/build_iosapp.go
+++ /dev/null
@@ -1,608 +0,0 @@
-// Copyright 2015 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "bytes"
- "crypto/x509"
- "encoding/pem"
- "fmt"
- "io/ioutil"
- "os"
- "os/exec"
- "path"
- "path/filepath"
- "strings"
- "text/template"
-
- "golang.org/x/tools/go/packages"
-)
-
-func goIOSBuild(pkg *packages.Package, bundleID string, archs []string) (map[string]bool, error) {
- src := pkg.PkgPath
- if buildO != "" && !strings.HasSuffix(buildO, ".app") {
- return nil, fmt.Errorf("-o must have an .app for -target=ios")
- }
-
- productName := rfc1034Label(path.Base(pkg.PkgPath))
- if productName == "" {
- productName = "ProductName" // like xcode.
- }
-
- projPbxproj := new(bytes.Buffer)
- if err := projPbxprojTmpl.Execute(projPbxproj, projPbxprojTmplData{
- BitcodeEnabled: bitcodeEnabled,
- }); err != nil {
- return nil, err
- }
-
- infoplist := new(bytes.Buffer)
- if err := infoplistTmpl.Execute(infoplist, infoplistTmplData{
- // TODO: better bundle id.
- BundleID: bundleID + "." + productName,
- Name: strings.Title(path.Base(pkg.PkgPath)),
- }); err != nil {
- return nil, err
- }
-
- files := []struct {
- name string
- contents []byte
- }{
- {tmpdir + "/main.xcodeproj/project.pbxproj", projPbxproj.Bytes()},
- {tmpdir + "/main/Info.plist", infoplist.Bytes()},
- {tmpdir + "/main/Images.xcassets/AppIcon.appiconset/Contents.json", []byte(contentsJSON)},
- }
-
- for _, file := range files {
- if err := mkdir(filepath.Dir(file.name)); err != nil {
- return nil, err
- }
- if buildX {
- printcmd("echo \"%s\" > %s", file.contents, file.name)
- }
- if !buildN {
- if err := ioutil.WriteFile(file.name, file.contents, 0644); err != nil {
- return nil, err
- }
- }
- }
-
- // We are using lipo tool to build multiarchitecture binaries.
- cmd := exec.Command(
- "xcrun", "lipo",
- "-o", filepath.Join(tmpdir, "main/main"),
- "-create",
- )
- var nmpkgs map[string]bool
- 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 {
- return nil, err
- }
- if nmpkgs == nil {
- var err error
- nmpkgs, err = extractPkgs(darwinArmNM, path)
- if err != nil {
- return nil, err
- }
- }
- cmd.Args = append(cmd.Args, path)
- }
-
- if err := runCmd(cmd); err != nil {
- return nil, err
- }
-
- // TODO(jbd): Set the launcher icon.
- if err := iosCopyAssets(pkg, tmpdir); err != nil {
- return nil, err
- }
-
- // Detect the team ID
- teamID, err := detectTeamID()
- if err != nil {
- return nil, err
- }
-
- // Build and move the release build to the output directory.
- cmdStrings := []string{
- "xcodebuild",
- "-configuration", "Release",
- "-project", tmpdir + "/main.xcodeproj",
- "-allowProvisioningUpdates",
- "DEVELOPMENT_TEAM=" + teamID,
- }
-
- cmd = exec.Command("xcrun", cmdStrings...)
- if err := runCmd(cmd); err != nil {
- return nil, err
- }
-
- // TODO(jbd): Fallback to copying if renaming fails.
- if buildO == "" {
- n := pkg.PkgPath
- if n == "." {
- // use cwd name
- cwd, err := os.Getwd()
- if err != nil {
- return nil, fmt.Errorf("cannot create .app; cannot get the current working dir: %v", err)
- }
- n = cwd
- }
- n = path.Base(n)
- buildO = n + ".app"
- }
- if buildX {
- printcmd("mv %s %s", tmpdir+"/build/Release-iphoneos/main.app", buildO)
- }
- if !buildN {
- // if output already exists, remove.
- if err := os.RemoveAll(buildO); err != nil {
- return nil, err
- }
- if err := os.Rename(tmpdir+"/build/Release-iphoneos/main.app", buildO); err != nil {
- return nil, err
- }
- }
- return nmpkgs, nil
-}
-
-func detectTeamID() (string, error) {
- // Grabs the first certificate for "iPhone Developer"; will not work if there
- // are multiple certificates and the first is not desired.
- cmd := exec.Command(
- "security", "find-certificate",
- "-c", "iPhone Developer", "-p",
- )
- pemString, err := cmd.Output()
- if err != nil {
- err = fmt.Errorf("failed to pull the signing certificate to determine your team ID: %v", err)
- return "", err
- }
-
- block, _ := pem.Decode(pemString)
- if block == nil {
- err = fmt.Errorf("failed to decode the PEM to determine your team ID: %s", pemString)
- return "", err
- }
-
- cert, err := x509.ParseCertificate(block.Bytes)
- if err != nil {
- err = fmt.Errorf("failed to parse your signing certificate to determine your team ID: %v", err)
- return "", err
- }
-
- if len(cert.Subject.OrganizationalUnit) == 0 {
- err = fmt.Errorf("the signing certificate has no organizational unit (team ID).")
- return "", err
- }
-
- return cert.Subject.OrganizationalUnit[0], nil
-}
-
-func iosCopyAssets(pkg *packages.Package, xcodeProjDir string) error {
- dstAssets := xcodeProjDir + "/main/assets"
- if err := mkdir(dstAssets); err != nil {
- return err
- }
-
- // TODO(hajimehoshi): This works only with Go tools that assume all source files are in one directory.
- // Fix this to work with other Go tools.
- srcAssets := filepath.Join(filepath.Dir(pkg.GoFiles[0]), "assets")
- fi, err := os.Stat(srcAssets)
- if err != nil {
- if os.IsNotExist(err) {
- // skip walking through the directory to deep copy.
- return nil
- }
- return err
- }
- if !fi.IsDir() {
- // skip walking through to deep copy.
- return nil
- }
- // if assets is a symlink, follow the symlink.
- srcAssets, err = filepath.EvalSymlinks(srcAssets)
- if err != nil {
- return err
- }
- return filepath.Walk(srcAssets, func(path string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
- if name := filepath.Base(path); strings.HasPrefix(name, ".") {
- // Do not include the hidden files.
- return nil
- }
- if info.IsDir() {
- return nil
- }
- dst := dstAssets + "/" + path[len(srcAssets)+1:]
- return copyFile(dst, path)
- })
-}
-
-type infoplistTmplData struct {
- BundleID string
- Name string
-}
-
-var infoplistTmpl = template.Must(template.New("infoplist").Parse(`<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>en</string>
- <key>CFBundleExecutable</key>
- <string>main</string>
- <key>CFBundleIdentifier</key>
- <string>{{.BundleID}}</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>{{.Name}}</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersionString</key>
- <string>1.0</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1</string>
- <key>LSRequiresIPhoneOS</key>
- <true/>
- <key>UILaunchStoryboardName</key>
- <string>LaunchScreen</string>
- <key>UIRequiredDeviceCapabilities</key>
- <array>
- <string>armv7</string>
- </array>
- <key>UISupportedInterfaceOrientations</key>
- <array>
- <string>UIInterfaceOrientationPortrait</string>
- <string>UIInterfaceOrientationLandscapeLeft</string>
- <string>UIInterfaceOrientationLandscapeRight</string>
- </array>
- <key>UISupportedInterfaceOrientations~ipad</key>
- <array>
- <string>UIInterfaceOrientationPortrait</string>
- <string>UIInterfaceOrientationPortraitUpsideDown</string>
- <string>UIInterfaceOrientationLandscapeLeft</string>
- <string>UIInterfaceOrientationLandscapeRight</string>
- </array>
-</dict>
-</plist>
-`))
-
-type projPbxprojTmplData struct {
- BitcodeEnabled bool
-}
-
-var projPbxprojTmpl = template.Must(template.New("projPbxproj").Parse(`// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 46;
- objects = {
-
-/* Begin PBXBuildFile section */
- 254BB84F1B1FD08900C56DE9 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 254BB84E1B1FD08900C56DE9 /* Images.xcassets */; };
- 254BB8681B1FD16500C56DE9 /* main in Resources */ = {isa = PBXBuildFile; fileRef = 254BB8671B1FD16500C56DE9 /* main */; };
- 25FB30331B30FDEE0005924C /* assets in Resources */ = {isa = PBXBuildFile; fileRef = 25FB30321B30FDEE0005924C /* assets */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
- 254BB83E1B1FD08900C56DE9 /* main.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = main.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 254BB8421B1FD08900C56DE9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
- 254BB84E1B1FD08900C56DE9 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
- 254BB8671B1FD16500C56DE9 /* main */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = main; sourceTree = "<group>"; };
- 25FB30321B30FDEE0005924C /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = assets; path = main/assets; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXGroup section */
- 254BB8351B1FD08900C56DE9 = {
- isa = PBXGroup;
- children = (
- 25FB30321B30FDEE0005924C /* assets */,
- 254BB8401B1FD08900C56DE9 /* main */,
- 254BB83F1B1FD08900C56DE9 /* Products */,
- );
- sourceTree = "<group>";
- usesTabs = 0;
- };
- 254BB83F1B1FD08900C56DE9 /* Products */ = {
- isa = PBXGroup;
- children = (
- 254BB83E1B1FD08900C56DE9 /* main.app */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- 254BB8401B1FD08900C56DE9 /* main */ = {
- isa = PBXGroup;
- children = (
- 254BB8671B1FD16500C56DE9 /* main */,
- 254BB84E1B1FD08900C56DE9 /* Images.xcassets */,
- 254BB8411B1FD08900C56DE9 /* Supporting Files */,
- );
- path = main;
- sourceTree = "<group>";
- };
- 254BB8411B1FD08900C56DE9 /* Supporting Files */ = {
- isa = PBXGroup;
- children = (
- 254BB8421B1FD08900C56DE9 /* Info.plist */,
- );
- name = "Supporting Files";
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 254BB83D1B1FD08900C56DE9 /* main */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 254BB8611B1FD08900C56DE9 /* Build configuration list for PBXNativeTarget "main" */;
- buildPhases = (
- 254BB83C1B1FD08900C56DE9 /* Resources */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = main;
- productName = main;
- productReference = 254BB83E1B1FD08900C56DE9 /* main.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 254BB8361B1FD08900C56DE9 /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastUpgradeCheck = 0630;
- ORGANIZATIONNAME = Developer;
- TargetAttributes = {
- 254BB83D1B1FD08900C56DE9 = {
- CreatedOnToolsVersion = 6.3.1;
- };
- };
- };
- buildConfigurationList = 254BB8391B1FD08900C56DE9 /* Build configuration list for PBXProject "main" */;
- compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = 254BB8351B1FD08900C56DE9;
- productRefGroup = 254BB83F1B1FD08900C56DE9 /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 254BB83D1B1FD08900C56DE9 /* main */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 254BB83C1B1FD08900C56DE9 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 25FB30331B30FDEE0005924C /* assets in Resources */,
- 254BB8681B1FD16500C56DE9 /* main in Resources */,
- 254BB84F1B1FD08900C56DE9 /* Images.xcassets in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- 254BB8601B1FD08900C56DE9 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 8.3;
- MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- {{if not .BitcodeEnabled}}ENABLE_BITCODE = NO;{{end}}
- };
- name = Release;
- };
- 254BB8631B1FD08900C56DE9 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- INFOPLIST_FILE = main/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 254BB8391B1FD08900C56DE9 /* Build configuration list for PBXProject "main" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 254BB8601B1FD08900C56DE9 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 254BB8611B1FD08900C56DE9 /* Build configuration list for PBXNativeTarget "main" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 254BB8631B1FD08900C56DE9 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 254BB8361B1FD08900C56DE9 /* Project object */;
-}
-`))
-
-const contentsJSON = `{
- "images" : [
- {
- "idiom" : "iphone",
- "size" : "29x29",
- "scale" : "2x"
- },
- {
- "idiom" : "iphone",
- "size" : "29x29",
- "scale" : "3x"
- },
- {
- "idiom" : "iphone",
- "size" : "40x40",
- "scale" : "2x"
- },
- {
- "idiom" : "iphone",
- "size" : "40x40",
- "scale" : "3x"
- },
- {
- "idiom" : "iphone",
- "size" : "60x60",
- "scale" : "2x"
- },
- {
- "idiom" : "iphone",
- "size" : "60x60",
- "scale" : "3x"
- },
- {
- "idiom" : "ipad",
- "size" : "29x29",
- "scale" : "1x"
- },
- {
- "idiom" : "ipad",
- "size" : "29x29",
- "scale" : "2x"
- },
- {
- "idiom" : "ipad",
- "size" : "40x40",
- "scale" : "1x"
- },
- {
- "idiom" : "ipad",
- "size" : "40x40",
- "scale" : "2x"
- },
- {
- "idiom" : "ipad",
- "size" : "76x76",
- "scale" : "1x"
- },
- {
- "idiom" : "ipad",
- "size" : "76x76",
- "scale" : "2x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
-`
-
-// rfc1034Label sanitizes the name to be usable in a uniform type identifier.
-// The sanitization is similar to xcode's rfc1034identifier macro that
-// replaces illegal characters (not conforming the rfc1034 label rule) with '-'.
-func rfc1034Label(name string) string {
- // * Uniform type identifier:
- //
- // According to
- // https://developer.apple.com/library/ios/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html
- //
- // A uniform type identifier is a Unicode string that usually contains characters
- // in the ASCII character set. However, only a subset of the ASCII characters are
- // permitted. You may use the Roman alphabet in upper and lower case (A–Z, a–z),
- // the digits 0 through 9, the dot (“.”), and the hyphen (“-”). This restriction
- // is based on DNS name restrictions, set forth in RFC 1035.
- //
- // Uniform type identifiers may also contain any of the Unicode characters greater
- // than U+007F.
- //
- // Note: the actual implementation of xcode does not allow some unicode characters
- // greater than U+007f. In this implementation, we just replace everything non
- // alphanumeric with "-" like the rfc1034identifier macro.
- //
- // * RFC1034 Label
- //
- // <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
- // <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
- // <let-dig-hyp> ::= <let-dig> | "-"
- // <let-dig> ::= <letter> | <digit>
- const surrSelf = 0x10000
- begin := false
-
- var res []rune
- for i, r := range name {
- if r == '.' && !begin {
- continue
- }
- begin = true
-
- switch {
- case 'a' <= r && r <= 'z', 'A' <= r && r <= 'Z':
- res = append(res, r)
- case '0' <= r && r <= '9':
- if i == 0 {
- res = append(res, '-')
- } else {
- res = append(res, r)
- }
- default:
- if r < surrSelf {
- res = append(res, '-')
- } else {
- res = append(res, '-', '-')
- }
- }
- }
- return string(res)
-}
diff --git a/cmd/gomobile/build_test.go b/cmd/gomobile/build_test.go
index 7a55603..162fa73 100644
--- a/cmd/gomobile/build_test.go
+++ b/cmd/gomobile/build_test.go
@@ -115,44 +115,46 @@
`))
func TestParseBuildTargetFlag(t *testing.T) {
- androidArchs := strings.Join(allArchs("android"), ",")
- iosArchs := strings.Join(allArchs("ios"), ",")
+ androidArchs := strings.Join(platformArchs("android"), ",")
+ darwinArchs := strings.Join(platformArchs("darwin"), ",")
tests := []struct {
- in string
- wantErr bool
- wantOS string
- wantArchs string
+ in string
+ wantErr bool
+ wantPlatforms string
+ wantArchs string
}{
{"android", false, "android", androidArchs},
{"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,iossimulator", darwinArchs},
+ {"ios,ios/arm64", false, "ios,iossimulator", darwinArchs},
+ {"ios/arm64", false, "ios,iossimulator", "arm64"},
{"", true, "", ""},
{"linux", true, "", ""},
{"android/x86", true, "", ""},
{"android/arm5", true, "", ""},
+ {"ios/amd64", true, "", ""},
{"ios/mips", true, "", ""},
{"android,ios", true, "", ""},
{"ios,android", true, "", ""},
}
for _, tc := range tests {
- gotOS, gotArchs, err := parseBuildTarget(tc.in)
+ p, a, err := parseBuildTarget(tc.in)
+ gotPlatforms := strings.Join(p, ",")
+ gotArchs := strings.Join(a, ",")
if tc.wantErr {
if err == nil {
- t.Errorf("-target=%q; want error, got (%q, %q, nil)", tc.in, gotOS, gotArchs)
+ t.Errorf("-target=%q; want error, got (%q, %q, nil)", tc.in, gotPlatforms, gotArchs)
}
continue
}
- if err != nil || gotOS != tc.wantOS || strings.Join(gotArchs, ",") != tc.wantArchs {
- t.Errorf("-target=%q; want (%v, [%v], nil), got (%q, %q, %v)",
- tc.in, tc.wantOS, tc.wantArchs, gotOS, gotArchs, err)
+ if err != nil || gotPlatforms != tc.wantPlatforms || gotArchs != tc.wantArchs {
+ t.Errorf("-target=%q; want (%q, %q, nil), got (%q, %q, %v)",
+ tc.in, tc.wantPlatforms, tc.wantArchs, gotPlatforms, gotArchs, err)
}
}
}
diff --git a/cmd/gomobile/env.go b/cmd/gomobile/env.go
index b342f3e..16d7022 100644
--- a/cmd/gomobile/env.go
+++ b/cmd/gomobile/env.go
@@ -25,38 +25,101 @@
bitcodeEnabled bool
)
-func allArchs(targetOS string) []string {
- switch targetOS {
+// expandPlatform returns a list of currently-supported SDKs for platform.
+func expandPlatform(platform string) (platforms []string, _ error) {
+ switch platform {
+ case "android":
+ return []string{"android"}, nil
case "ios":
+ // Preserve existing -target=ios behavior
+ return []string{"ios", "iossimulator"}, nil
+ case "iossimulator":
+ return []string{"iossimulator"}, nil
+ case "macos":
+ return []string{"macos"}, nil
+ case "maccatalyst":
+ return []string{"maccatalyst"}, nil
+ // The "darwin" platform actually builds for multiple Apple platforms:
+ // iOS, iPadOS, MacCatalyst (iOS on macOS), and macOS.
+ // TODO: support watchOS and tvOS?
+ case "darwin":
+ return darwinPlatforms, nil
+ default:
+ return nil, fmt.Errorf("unexpected platform: %s", platform)
+ }
+}
+
+func isAndroidPlatform(platform string) bool {
+ return platform == "android"
+}
+
+func isDarwinPlatform(platform string) bool {
+ return contains(darwinPlatforms, platform)
+}
+
+var darwinPlatforms = []string{"ios", "iossimulator", "maccatalyst", "macos"}
+
+func platformArchs(platform string) []string {
+ switch platform {
+ case "ios":
+ // Only build iOS on arm64
+ return []string{"arm64"}
+ case "iossimulator":
+ // Only build iOS simulator on amd64
+ return []string{"amd64"}
+ case "macos", "maccatalyst", "darwin":
return []string{"arm64", "amd64"}
case "android":
return []string{"arm", "arm64", "386", "amd64"}
default:
- panic(fmt.Sprintf("unexpected target OS: %s", targetOS))
+ panic(fmt.Sprintf("unexpected platform: %s", platform))
}
}
-// iOSTargets lists Apple platforms as individual sub-targets.
-// The gomobile "ios" target actually builds for multiple Apple platforms:
-// iOS, iPadOS, MacCatalyst (iOS on macOS), and macOS.
-// TODO: support watchOS and tvOS?
-var iOSTargets = []string{"simulator", "ios", "catalyst", "macos"}
+func isSupportedArch(platform, arch string) bool {
+ return contains(platformArchs(platform), arch)
+}
-func iOSTargetArchs(target string) []string {
- switch target {
- case "simulator":
- return []string{"arm64", "amd64"}
- case "ios":
- return []string{"arm64"}
- case "catalyst":
- return []string{"arm64", "amd64"}
- case "macos":
- return []string{"arm64", "amd64"}
+// platformOS returns the correct GOOS value for platform.
+func platformOS(platform string) string {
+ switch platform {
+ case "android":
+ return "android"
+ case "ios", "iossimulator":
+ return "ios"
+ case "macos", "maccatalyst":
+ return "darwin"
default:
- panic(fmt.Sprintf("unexpected iOS target: %s", target))
+ panic(fmt.Sprintf("unexpected platform: %s", platform))
}
}
+func platformTags(platform string) []string {
+ switch platform {
+ case "android":
+ return []string{"android"}
+ case "ios":
+ return []string{"ios"}
+ case "iossimulator":
+ return []string{"ios", "iossimulator"}
+ case "macos":
+ return []string{"macos"}
+ case "maccatalyst":
+ return []string{"macos", "maccatalyst"}
+ default:
+ panic(fmt.Sprintf("unexpected platform: %s", platform))
+ }
+}
+
+func contains(haystack []string, needle string) bool {
+ for _, v := range haystack {
+ if v == needle {
+ return true
+ }
+ }
+ return false
+}
+
func buildEnvInit() (cleanup func(), err error) {
// Find gomobilepath.
gopath := goEnv("GOPATH")
@@ -162,31 +225,35 @@
darwinArmNM = "nm"
darwinEnv = make(map[string][]string)
- for _, target := range iOSTargets {
- for _, arch := range iOSTargetArchs(target) {
+ for _, platform := range darwinPlatforms {
+ for _, arch := range platformArchs(platform) {
var env []string
+ var goos, clang, cflags string
var err error
- var clang, cflags string
- switch target {
+ switch platform {
case "ios":
+ goos = "ios"
clang, cflags, err = envClang("iphoneos")
cflags += " -miphoneos-version-min=" + buildIOSVersion
- case "simulator":
+ case "iossimulator":
+ goos = "ios"
clang, cflags, err = envClang("iphonesimulator")
cflags += " -mios-simulator-version-min=" + buildIOSVersion
- case "catalyst":
+ case "maccatalyst":
+ goos = "darwin"
clang, cflags, err = envClang("macosx")
switch arch {
case "amd64":
- cflags += " -target x86_64-apple-ios13.0-macabi"
+ cflags += " -target x86_64-apple-ios" + buildIOSVersion + "-macabi"
case "arm64":
- cflags += " -target arm64-apple-ios13.0-macabi"
+ cflags += " -target arm64-apple-ios" + buildIOSVersion + "-macabi"
}
case "macos":
+ goos = "darwin"
// Note: the SDK is called "macosx", not "macos"
clang, cflags, err = envClang("macosx")
default:
- panic(fmt.Errorf("unknown ios target: %q", arch))
+ panic(fmt.Errorf("unknown darwin target: %q", arch))
}
if err != nil {
@@ -197,8 +264,9 @@
cflags += " -fembed-bitcode"
}
env = append(env,
- "GOOS=darwin",
+ "GOOS="+goos,
"GOARCH="+arch,
+ "GOFLAGS="+"-tags="+strings.Join(platformTags(platform), ","),
"CC="+clang,
"CXX="+clang+"++",
"CGO_CFLAGS="+cflags+" -arch "+archClang(arch),
@@ -206,7 +274,7 @@
"CGO_LDFLAGS="+cflags+" -arch "+archClang(arch),
"CGO_ENABLED=1",
)
- darwinEnv[target+"_"+arch] = env
+ darwinEnv[platform+"/"+arch] = env
}
}
diff --git a/cmd/gomobile/init.go b/cmd/gomobile/init.go
index 00b9a56..172d015 100644
--- a/cmd/gomobile/init.go
+++ b/cmd/gomobile/init.go
@@ -167,7 +167,7 @@
}
}
- for _, arch := range allArchs("android") {
+ for _, arch := range platformArchs("android") {
t := ndk[arch]
abi := t.arch
if abi == "arm" {
diff --git a/cmd/gomobile/init_test.go b/cmd/gomobile/init_test.go
index 1849252..fb708b2 100644
--- a/cmd/gomobile/init_test.go
+++ b/cmd/gomobile/init_test.go
@@ -170,7 +170,7 @@
rm -r -f "$GOMOBILE"
mkdir -p $GOMOBILE
WORK={{.GOPATH}}/pkg/gomobile/work
-go install -x golang.org/x/mobile/cmd/gobind
+go install -tags tag1 -x golang.org/x/mobile/cmd/gobind
cp $OPENAL_PATH/include/AL/al.h $GOMOBILE/include/AL/al.h
mkdir -p $GOMOBILE/include/AL
cp $OPENAL_PATH/include/AL/alc.h $GOMOBILE/include/AL/alc.h
diff --git a/cmd/gomobile/writer_test.go b/cmd/gomobile/writer_test.go
index ae6e2c7..a082835 100644
--- a/cmd/gomobile/writer_test.go
+++ b/cmd/gomobile/writer_test.go
@@ -125,7 +125,7 @@
android:versionCode="1"
android:versionName="1.0">
-
+
<application android:label="FakeApp" android:hasCode="false" android:debuggable="true">
<activity android:name="android.app.NativeActivity"
android:label="FakeApp"
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Patch set 1:Run-TryBot +1
Attention is currently required from: Hyang-Ah Hana Kim.
1 comment:
Patchset:
1. The current `-target` value is GOOS or GOOS/GOARCH, and this change conflicts with this convention. If we want to do, we need more discussion.
2. My intuition is that we can use GOOS=ios for ios and iosimulator and GOOS=darwin (without ios tag) for macos and maccatalyst. Doesn't this work? IIUC, `ios` build tag is for Go 1.15 and older, which don't recognize GOOS=ios, and we can remove this anyway.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
3 comments:
Patchset:
1 of 2 TryBots failed. […]
Ack
1. […]
1. gomobile’s `ios` target predates GOOS=ios, and just rewrote it to `darwin` anyway, so the convention is more of a coincidence. Internally, the gomobile code referred to the -target argument as a platform (see cmd/gomobile/version.go).
I’d love to have that discussion!
2. macos and maccatalyst are really quite different, so it doesn’t make sense to bundle them under a single platform name. The former has access to AppKit, and the latter UIKit, effectively being iOS-on-macOS.
I can’t think of a credible alternative to build tags to allow Go code (and embedded C) to discriminate between the various Apple platforms, especially if we add support for tvOS and watchOS.
Thanks for the review. I’d love to have the discussion about the `-target` arg.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
1 comment:
Patchset:
1. […]
One thing to note: this change preserves the ability for gomobile to bundle multiple Apple/darwin platforms together into a single fat XCFramework. The new -target features lets a user specify only the platform(s) they want, e.g.
-target=ios,macos
-target=ios,maccatalyst
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #2 to this change.
cmd/gomobile: support GOOS=ios
This is is a follow-up from my previous PR (#65). It make gomobile aware of GOOS=ios
and adds support for specifying specific Apple platforms, instead of lumping them under
the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,maccatalyst,macos
It also supports the special "darwin" platform which expands to all supported Apple platforms.
This PR also fixes a number of broken iOS tests. Is there a macOS / Xcode trybot for this repo?
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 9444da25019879289e4d0a50eb61cd4e05f328f6
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
A cmd/gomobile/build_darwinapp.go
D cmd/gomobile/build_iosapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/writer_test.go
11 files changed, 905 insertions(+), 807 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
1 comment:
Patchset:
macos and maccatalyst are really quite different, so it doesn’t make sense to bundle them under a single platform name. The former has access to AppKit, and the latter UIKit, effectively being iOS-on-macOS.
Go compiler needs to know whether `ios` or `!ios` for a slight different implementation in runtime (IIUC). For Go users, `ios` and `!ios` are useful to know e.g., whether UIKit is available or not. In this sense, just `ios` and `!ios` are enough. Even if we have `macos` or `macoscatalyst`, there is nothing new we can do. Perhaps Catalyst is a little different thing from both `ios` and `!ios`, then I might be wrong.
I'm pretty hesitate to add new build tags that seems to be a kind of GOOS, even though they are not actual GOOS. Hana, what do you think?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
1 comment:
Patchset:
> macos and maccatalyst are really quite different, so it doesn’t make sense to bundle them under a […]
ios and !ios are not sufficient to know if UIKit is available. UIKit is available on the maccatalyst SDK, but not macos. Similarly, ios has OpenGLES, while catalyst and macos have OpenGL.
I originally started with an additional arg `-darwinsdks` that would allow the user to specify which Apple/darwin SDKs to target. However, the complexity of a third layer of platform discrimination didn’t seem worth it.
After reading Hana’s comment in version.go, it seemed more straightforward to use the platform part of the -target arg, which was already stretched with `ios` meaning `ios` + `catalyst` + `macos` in the current master branch.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
1 comment:
Patchset:
ios and !ios are not sufficient to know if UIKit is available. UIKit is available on the maccatalyst SDK, but not macos. Similarly, ios has OpenGLES, while catalyst and macos have OpenGL.
Hmm, interesting. I'd like to see the table what are available and what are not in iOS, macOS, and macOS Catalyst. I think this require more discussion. Can you file a new issue for this to discuss how we should distinguish them?
(BTW, I thought UIKit is available only when TARGET_OS_IPHONE is 1, but is that correct? If so, is TARGET_OS_IPHONE 1 on macOS Catalyst)
For the argument design, I'd like to know Hana's opinion.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
1 comment:
Patchset:
Someone already filed an issue! https://github.com/golang/go/issues/47212
(BTW, I thought UIKit is available only when TARGET_OS_IPHONE is 1, but is that correct? If so, is TARGET_OS_IPHONE 1 on macOS Catalyst)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #3 to this change.
cmd/gomobile: support GOOS=ios
This is is a follow-up from my previous PR (#65). It make gomobile aware of GOOS=ios
and adds support for specifying specific Apple platforms, instead of lumping them under
the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,maccatalyst,macos
It also supports the special "darwin" platform which expands to all supported Apple platforms.
This PR also fixes a number of broken iOS tests. Is there a macOS / Xcode trybot for this repo?
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 8b6abc23ae004012b50a0c5486b51a329eb666fb
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
A cmd/gomobile/build_darwinapp.go
D cmd/gomobile/build_iosapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
12 files changed, 905 insertions(+), 802 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
1 comment:
Patchset:
Thanks, so can we say `ios` (not `!ios`) for macOS Catalyst, from TARGET_OS_IPHONE...? (OpenGL might be in a different situation though)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #4 to this change.
cmd/gomobile: support GOOS=ios
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,maccatalyst,macos
A special "darwin" platform expands to all supported Apple platforms.
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 8b6abc23ae004012b50a0c5486b51a329eb666fb
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
A cmd/gomobile/build_darwinapp.go
D cmd/gomobile/build_iosapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
12 files changed, 905 insertions(+), 802 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #5 to this change.
cmd/gomobile: support GOOS=ios
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,maccatalyst,macos
A special "darwin" platform expands to all supported Apple platforms.
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 5527f9f8fe47a11771ba8be66ed3415bb4e18c7f
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
R cmd/gomobile/build_darwinapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
11 files changed, 312 insertions(+), 209 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
1 comment:
Patchset:
> Sorry! https://stackoverflow.com/a/49560690 […]
This is one way to handle it, with a combination of build tags and C:
https://github.com/ydnar/gomobile/blob/master/gl/work.go
This would need to be reworked to support UIKit on Catalyst:
https://github.com/golang/mobile/blob/master/app/darwin_ios.go
(in addition to OpenGL vs OpenGLES)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #6 to this change.
cmd/gomobile: support GOOS=ios
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,maccatalyst,macos
A special "darwin" platform expands to all supported Apple platforms.
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 77eab9e9c37785ded36b64a0e76a0b6daddee38f
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
R cmd/gomobile/build_darwinapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
12 files changed, 344 insertions(+), 240 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #7 to this change.
cmd/gomobile: support GOOS=ios
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,maccatalyst,macos
A special "darwin" platform expands to all supported Apple platforms.
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 708f5c686766b5808ab2e7ed9e557848187d342e
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
R cmd/gomobile/build_darwinapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
12 files changed, 330 insertions(+), 253 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #8 to this change.
cmd/gomobile: support GOOS=ios
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,maccatalyst,macos
A special "darwin" platform expands to all supported Apple platforms.
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 59bb0634c0bb63f7fc966f307a87275cabfe1eba
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
R cmd/gomobile/build_darwinapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
12 files changed, 336 insertions(+), 256 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
1 comment:
Patchset:
This is one way to handle it, with a combination of build tags and C: […]
I found a bug which relates to this in cgo: https://golang.org/issues/47228
Currently, Catalyst builds only succeed with -tags=ios.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #9 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 59bb0634c0bb63f7fc966f307a87275cabfe1eba
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
R cmd/gomobile/build_darwinapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
12 files changed, 336 insertions(+), 256 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #10 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 59bb0634c0bb63f7fc966f307a87275cabfe1eba
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
R cmd/gomobile/bind_darwinapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
R cmd/gomobile/build_darwinapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
12 files changed, 336 insertions(+), 256 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #11 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 2f07876477f029111d5be6e0839d6f72b73b619b
GitHub-Pull-Request: golang/mobile#70
---
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
A cmd/gomobile/bind_darwinapp.go
D cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
R cmd/gomobile/build_darwinapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
13 files changed, 591 insertions(+), 432 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
2 comments:
Patchset:
I found a bug which relates to this in cgo: https://golang.org/issues/47228 […]
Done
Patchset:
Hi folks, any update? I’d love to see this merged.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
1 comment:
Patchset:
Hi folks, any update? I’d love to see this merged.
I think we have not reached the agreement: https://github.com/golang/go/issues/47212#issuecomment-884432908
ping Hana
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #12 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 78f94de3b428e3e6d39c7138522b5b96cf5b6593
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
A cmd/gomobile/bind_darwinapp.go
D cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_darwin_test.go
R cmd/gomobile/build_darwinapp.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
16 files changed, 642 insertions(+), 457 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig.
11 comments:
File .gitignore:
Patch Set #12, Line 6: *.xcramework
xcframework?
Patchset:
Thanks for this PR and, sorry for the delay.
File cmd/gomobile/bind.go:
Patch Set #12, Line 216: arm64
Is this still ok to always assume arm64?
Patch Set #12, Line 285: dir string, targetPlatform string, targetArch string)
(dir, targetPlatform, targetArch string)
File cmd/gomobile/bind_darwinapp.go:
Patch Set #12, Line 20: goDarwinbind
goDarwinBind
File cmd/gomobile/build.go:
Patch Set #12, Line 353: 1 or more platforms and architectures.
What's the relationship between platforms and architectures?
If it returns {ios,iossimulator,maccatalyst} and {arm64}, should the caller interpret to build ios on arm64, iossimulator on arm64, maccatalyst on arm64?
What do you think if parseBuildTarget returns []struct{platform, arch string} that includes only the pairs that make sense?
-target=ios => {{ios, arm64}, {iossimulator, amd64}}
-target=iossimulator => {{iossimulator,amd64}}, ...
Q. does iossimulator/arm64 make sense? (simulator on M1?)
Patch Set #12, Line 385: if platform == "ios" {
Is it true that iossimulator needs to be added unconditionally if ios/arm64 (hasArch = true) is specified?
File cmd/gomobile/build_test.go:
{"ios,ios/arm64", false, "ios,iossimulator", "arm64"},
{"ios/arm64", false, "ios,iossimulator", "arm64"},
is iossimulator/arm64 a valid combination?
Patch Set #12, Line 141: {"ios/amd64", true, "", ""},
ios/arm64
iossimulator/amd64
and test cases for maccos, maccatalyst?
File cmd/gomobile/doc.go:
Patch Set #12, Line 68: -prefix flag.
Can you please add a paragraph to explain the difference among ios, iossimulator, macos, and maccatalyst here? More specifically, the meaning of `ios` needs clarification.
And, what is 'macos' target for?
File cmd/gomobile/env.go:
Patch Set #12, Line 227: cflags += " -target x86_64-apple-ios" + buildIOSVersion + "-macabi"
bitcodeFlag is not necessary even when bitcodeEnabled=true?
https://developer.apple.com/documentation/xcode/building-your-app-to-include-debugging-information says bitcode is not available for macos/catalyst apps. Does it mean that bigcodeFlag shouldn't be used for arm64, too?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
2 comments:
Patchset:
Hi Hana, I’m in the middle of rebasing this on top of master. So some things might shift a bit. Thanks for the review!
File cmd/gomobile/build_test.go:
{"ios,ios/arm64", false, "ios,iossimulator", "arm64"},
{"ios/arm64", false, "ios,iossimulator", "arm64"},
is iossimulator/arm64 a valid combination?
iossimulator/arm64 is a valid combination distinct from ios/arm64, since the simulator is a separate SDK.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
9 comments:
File .gitignore:
Patch Set #12, Line 6: *.xcramework
xcframework?
Done
Patchset:
Hana: more feedback for your review. I also pushed a new version, rebased on master.
File cmd/gomobile/bind.go:
Patch Set #12, Line 216: arm64
Is this still ok to always assume arm64?
This is a really good question. I have a TODO in runBuildImpl():
// TODO(ydnar): this should work, unless build tags affect loading a single package.
// Should we try to import packages with different build tags per platform?
Patch Set #12, Line 285: dir string, targetPlatform string, targetArch string)
(dir, targetPlatform, targetArch string)
Done
File cmd/gomobile/bind_darwinapp.go:
Patch Set #12, Line 20: goDarwinbind
goDarwinBind
Done
File cmd/gomobile/build.go:
Patch Set #12, Line 353: 1 or more platforms and architectures.
What's the relationship between platforms and architectures?
If it returns {ios,iossimulator,maccatalyst} and {arm64}, should the caller interpret to build ios on arm64, iossimulator on arm64, maccatalyst on arm64?
The platform idiom was my attempt to rationalize the difference between the gomobile target and Apple’s SDKs, in a way that doesn’t ignore the Android side.
I elected not to make a bigger change to the return value of parseBuildTarget, but maybe that makes sense.
What do you think if parseBuildTarget returns []struct{platform, arch string} that includes only the pairs that make sense?
-target=ios => {{ios, arm64}, {iossimulator, amd64}}
-target=iossimulator => {{iossimulator,amd64}}, ...
Yeah, this is probably better. Thanks!
Q. does iossimulator/arm64 make sense? (simulator on M1?)
Yep. The simulator is a distinct platform/SDK. Sigh
Patch Set #12, Line 385: if platform == "ios" {
Is it true that iossimulator needs to be added unconditionally if ios/arm64 (hasArch = true) is spec […]
That’s a good question. I favored attempting to preserve existing behavior for -target=ios/arm64. I could go either way—what do you think?
File cmd/gomobile/doc.go:
Patch Set #12, Line 68: -prefix flag.
Can you please add a paragraph to explain the difference among ios, iossimulator, macos, and maccatalyst here? More specifically, the meaning of `ios` needs clarification.
Sure thing.
And, what is 'macos' target for?
Since the Objective-C binding capabilities of gomobile aren’t technically limited to iOS, gomobile can be used to build an XCFramework that can be embedded in a macOS app (non-Catalyst).
Furthermore, it can generate a fat XCFramework that includes macOS and iOS/simulator slices, which was the original motivation for this CL.
File cmd/gomobile/env.go:
Patch Set #12, Line 227: cflags += " -target x86_64-apple-ios" + buildIOSVersion + "-macabi"
bitcodeFlag is not necessary even when bitcodeEnabled=true?
https://developer.apple.com/documentation/xcode/building-your-app-to-include-debugging-information says bitcode is not available for macos/catalyst apps. Does it mean that bitcodeFlag shouldn't be used for arm64, too?
There was an earlier commit on master that removed the flag and made bitcode non-optional. I didn’t encounter any issues when building with bitcode enabled on arm64 for macOS or macCatalyst targets, but you could be right.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #13 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 4be809c6993e14fa795cb4e05a10b83cf9171c1e
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
R cmd/gomobile/build_apple.go
R cmd/gomobile/build_apple_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
15 files changed, 584 insertions(+), 348 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig.
10 comments:
File cmd/gomobile/bind.go:
Patch Set #12, Line 216: arm64
This is a really good question. I have a TODO in runBuildImpl(): […]
I think previously, gomobile assumed only mobile devices, and arm64 support is almost always assumed. So, this made sense. Now there are iossimulator and non-mobile targets :-( so this may need to be revisited. Is it possible to pass the first arch entry here?
This is used to build a package targeted for bind code generation. In most cases, I guess the bind code itself is not os/arch dependent, and we need to generate the bind code only once. If that's not the case, I hope users run gomobile with architecture specific target. By allowing to pass one of the archs the user selects, I think we can avoid requiring arm64 build.
File cmd/gomobile/bind_iosapp.go:
Patch Set #13, Line 59: // Run gobind once per platform to generate the bindings
This is another change. gobind generates source code for binding based on the exported APIs. Previously we assumed the exported APIs are stable and the generated obj-c code doesn't have much of platform-specific code, so it ran only once and reused to build for different architectures.
With this change, for example, if -target=ios, targetPlatforms will have [ios, iossimulator], and we will run gobind twice. Why do people want to generate different binding code for ios and iossimulator?
File cmd/gomobile/build.go:
Patch Set #12, Line 353: 1 or more platforms and architectures.
> What's the relationship between platforms and architectures? […]
This change is already big and I won't ask you for bigger change. Can you please add TODO here to clean up this parseBuildTarget? I see that later the archs bits that don't make sense get filtered out, but that's too subtle. Centralizing the build target decision as much as possible seems better. Currently it's not clear whether both iossimulator/arm64, iossimulator/amd64 will be included when a user specifies -target=ios/arm64.
Patch Set #12, Line 385: if platform == "ios" {
That’s a good question. I favored attempting to preserve existing behavior for -target=ios/arm64. […]
I thought,
for -target=ios, gomobile built ios/arm64, and ios/amd64 (which was for simulator).
for -target=ios/arm64, gomobile built only iphoneos+arm64 target previously.
for -target=ios/amd64, simulator+amd64 target was included.
By unconditionally adding iossimulator, I think there is no way to skip the build for simulator after this change.
File cmd/gomobile/build.go:
Patch Set #13, Line 149: Skip unrequested architectures
Code reads 'skip unsupported architectures'..
And, how did we end up here if -target flag parse check already does the check?
Is it a side-effect of simply computing cartesian product of parseBuildTarget results that didn't preserve the precise list of requested platform/arch pairs?
File cmd/gomobile/build_apple.go:
Patch Set #13, Line 83: // e.g. ios/arm64 + iossimulator/amd64
Does it mean building ios/arm64 + iossimulator/arm64 together is impossible?
Patch Set #13, Line 97: iosArmNM
Looks like we need to rename this - no longer iosArm specific I guess.
File cmd/gomobile/doc.go:
Patch Set #12, Line 44: either android (the default) or ios, iossimulator, macos, maccatalyst.
The -target flag takes either android (the default), or one or more comma-delimited Apple platform names.
Patch Set #12, Line 68: -prefix flag.
> Can you please add a paragraph to explain the difference among ios, iossimulator, macos, and macca […]
Please clarify the distinction between ios and iossimulator in the doc at least.
And, ios/arm64 is accepted, right?
File cmd/gomobile/env.go:
Patch Set #13, Line 219: if arch != "amd64" { // TODO(ydnar): should this be == "arm64"?
I think == "arm64" is better (more consistent with the maccatalyst case)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
8 comments:
Patchset:
Thanks!
File cmd/gomobile/bind.go:
Patch Set #12, Line 216: arm64
I think previously, gomobile assumed only mobile devices, and arm64 support is almost always assumed […]
Passing an explicit arch makes sense. I can make that change.
File cmd/gomobile/bind_iosapp.go:
Patch Set #13, Line 59: // Run gobind once per platform to generate the bindings
This is another change. gobind generates source code for binding based on the exported APIs. Previously we assumed the exported APIs are stable and the generated obj-c code doesn't have much of platform-specific code, so it ran only once and reused to build for different architectures.
This matters more if it’s building a fat XCFramework for both macos and ios. Given the significant platform API differences, this seemed necessary.
With this change, for example, if -target=ios, targetPlatforms will have [ios, iossimulator], and we will run gobind twice. Why do people want to generate different binding code for ios and iossimulator?
Running it twice (once for ios and once for iossimulator) is more expensive than running it once, but I felt it was better than putting in special-case code to elide the second run for iossimulator and copy the generated code.
I guess—in theory—we could have an additional `iossimulator` tag that can trigger special-case code that only runs on the simulator for debugging purposes.
File cmd/gomobile/build.go:
Patch Set #12, Line 353: 1 or more platforms and architectures.
This change is already big and I won't ask you for bigger change. […]
Agree, will do.
File cmd/gomobile/build.go:
Patch Set #13, Line 149: Skip unrequested architectures
Code reads 'skip unsupported architectures'.. […]
This is a byproduct of parseBuildTarget returning two slices instead of your (IMO better) proposal of a slice of {platform, arch}.
It’s really designed to skip building the `ios/amd64` tuple.
File cmd/gomobile/build_apple.go:
Patch Set #13, Line 83: // e.g. ios/arm64 + iossimulator/amd64
Does it mean building ios/arm64 + iossimulator/arm64 together is impossible?
You found the weirdness. Despite iphoneos and iphonesimulator being separate SDKs, you can’t have both with the same arch in a single fat XCFramework, so it skips the simulator slice if it already merged the ios slice.
I’ve verified this works on device and simulator. Not sure the best way to test this.
File cmd/gomobile/doc.go:
Patch Set #12, Line 44: either android (the default) or ios, iossimulator, macos, maccatalyst.
The -target flag takes either android (the default), or one or more comma-delimited Apple platform n […]
Done
File cmd/gomobile/env.go:
Patch Set #13, Line 219: if arch != "amd64" { // TODO(ydnar): should this be == "arm64"?
I think == "arm64" is better (more consistent with the maccatalyst case)
Done
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #14 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: b15fb8cced6d6fed5d0a2abe82640ccdb93088e3
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
R cmd/gomobile/build_apple.go
R cmd/gomobile/build_apple_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
15 files changed, 606 insertions(+), 348 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #15 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 1b95e9dd4751753bd504cf35eda48005e0e1d252
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
R cmd/gomobile/build_apple_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
16 files changed, 598 insertions(+), 359 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #16 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 37aff26bb3e4ed74797d25e620f566a5bcde413c
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
R cmd/gomobile/build_apple_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
16 files changed, 594 insertions(+), 359 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
6 comments:
Patchset:
@Hana I went ahead and modified parseBuildTarget per your suggestion. It turned out to be pretty straightforward. I also made a few other fixes per your feedback.
File cmd/gomobile/bind.go:
Patch Set #12, Line 216: arm64
Passing an explicit arch makes sense. I can make that change.
Done
File cmd/gomobile/build.go:
Patch Set #12, Line 353: 1 or more platforms and architectures.
Agree, will do.
Done.
Patch Set #12, Line 385: if platform == "ios" {
I thought, […]
Fixed this in last round. `iossimulator` will now only be added if -target=ios. Any other value for -target, including -target=ios/arm64 will not automatically build for iossimulator.
File cmd/gomobile/build.go:
Patch Set #13, Line 149: Skip unrequested architectures
This is a byproduct of parseBuildTarget returning two slices instead of your (IMO better) proposal o […]
Removed this in favor of parseBuildTarget returning a slice of guaranteed-to-work platform/arch tuples.
File cmd/gomobile/build_apple.go:
Patch Set #13, Line 97: iosArmNM
Looks like we need to rename this - no longer iosArm specific I guess.
Done
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig.
Patch set 16:Run-TryBot +1Trust +1
7 comments:
File cmd/gomobile/bind_iosapp.go:
Patch Set #13, Line 59: // Run gobind once per platform to generate the bindings
> This is another change. gobind generates source code for binding based on the exported APIs. […]
Ack
File cmd/gomobile/build_apple.go:
Patch Set #13, Line 83: // e.g. ios/arm64 + iossimulator/amd64
You found the weirdness. […]
Ack
File cmd/gomobile/build_test.go:
{"ios,ios/arm64", false, "ios,iossimulator", "arm64"},
{"ios/arm64", false, "ios,iossimulator", "arm64"},
iossimulator/arm64 is a valid combination distinct from ios/arm64, since the simulator is a separate […]
Ack
Patch Set #12, Line 141: {"ios/amd64", true, "", ""},
ios/arm64 […]
Ack
File cmd/gomobile/build_test.go:
Patch Set #16, Line 118: wantAndroid := "android/" + strings.Join(platformArchs("android"), ",android/")
wish we had a map function.
File cmd/gomobile/doc.go:
Patch Set #12, Line 68: -prefix flag.
Please clarify the distinction between ios and iossimulator in the doc at least. […]
ok, maybe followup cl.
File cmd/gomobile/env.go:
Patch Set #12, Line 227: cflags += " -target x86_64-apple-ios" + buildIOSVersion + "-macabi"
> bitcodeFlag is not necessary even when bitcodeEnabled=true? […]
Ack
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig.
Patch set 16:-Run-TryBot-Trust
2 comments:
File cmd/gomobile/build_apple_test.go:
this should be added back.
why is it commented out?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig.
Gerrit Bot uploaded patch set #17 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 7471be384fb95a40601b3f836981fd8186a74f58
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
R cmd/gomobile/build_apple_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
16 files changed, 594 insertions(+), 356 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
2 comments:
File cmd/gomobile/build_apple_test.go:
this should be added back.
Oops, I missed it in the rebase. Fixed!
why is it commented out?
Good catch. This test caught a related bug in runBuildImpl.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #18 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 0c08a475aff39610e37a71935b8243dee76f15f8
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
A cmd/gomobile/build_apple_test.go
D cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
17 files changed, 708 insertions(+), 461 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
Patch set 18:Run-TryBot +1
Attention is currently required from: Hyang-Ah Hana Kim.
4 comments:
Commit Message:
Patch Set #18, Line 26: Fixes https://golang.org/issues/47212
Fixes golang/go#47212
Updates golang/go#47228
File cmd/gomobile/env.go:
Patch Set #18, Line 63: return "darwin"
Hmm, when `macoscatalyst` is specified, isn't GOOS `ios`?
* `macos` indicates a regular macOS application
* `macoscatalyst` indicates an iOS application that works on macOS
Is this correct?
Patch Set #18, Line 80: return []string{"ios", "macos", "maccatalyst"}
A similar question: even after golang/go#47228 is fixed, which should we treat a Catalyst application an iOS application or a macOS application?
File cmd/gomobile/writer_test.go:
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim.
1 comment:
File cmd/gomobile/env.go:
Patch Set #18, Line 80: return []string{"ios", "macos", "maccatalyst"}
A similar question: even after golang/go#47228 is fixed, which should we treat a Catalyst applicatio […]
From https://github.com/golang/go/issues/47228#issuecomment-915267671, we will keep using GOOS=ios for macOS Catalyst, right?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
3 comments:
Patchset:
Catalyst is weird!
File cmd/gomobile/env.go:
Patch Set #18, Line 63: return "darwin"
Hmm, when `macoscatalyst` is specified, isn't GOOS `ios`? […]
Catalyst is iOS APIs (like UIKit) on macOS. Some things, like OpenGLES, are simply not available.
AppKit is still available under the hood:
https://developer.apple.com/documentation/uikit/mac_catalyst
Patch Set #18, Line 80: return []string{"ios", "macos", "maccatalyst"}
From https://github. […]
It’s the inverse (Catalyst is macOS that has support for most of the iOS APIs). What made this work (without changing Go itself) is GOOS=darwin with the ios build tag. Otherwise it was compiling bits that wouldn’t work for a macOS library.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
2 comments:
File cmd/gomobile/env.go:
Patch Set #18, Line 63: return "darwin"
Catalyst is iOS APIs (like UIKit) on macOS. Some things, like OpenGLES, are simply not available. […]
Thanks. I'd be happy if you could leave a comment about what Catalyst is and why GOOS=darwin instead of GOOS=ios is chosen here.
Patch Set #18, Line 80: return []string{"ios", "macos", "maccatalyst"}
It’s the inverse (Catalyst is macOS that has support for most of the iOS APIs). […]
Thanks, I'd want more comments to explain this situation like the above.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
1 comment:
File cmd/gomobile/env.go:
Patch Set #18, Line 63: return "darwin"
Thanks. […]
https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets/49560690#49560690
In Catalyist, `TARGET_OS_IPHONE` is defined but `GOOS` is `darwin`. This seems inconsistent but it is because Go is not ready. Is this correct?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #19 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: fb52b1e2856eb7c9995279bfd67fd68dc7b46465
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
A cmd/gomobile/bind_apple.go
D cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
A cmd/gomobile/build_apple_test.go
D cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
18 files changed, 851 insertions(+), 575 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Hyang-Ah Hana Kim, Hajime Hoshi.
2 comments:
Patchset:
I added comments that should help provide the necessary context for why GOOS=darwin for -target=maccatalyst.
I also added a couple TODOs to look at later, since I think this PR is big enough.
One nit: the example apps will build and run on an iPhone, but will not currently build for macos or maccatalyst because of a dependency on GLKit. The OpenGL/OpenGLES difference can be worked around with build tags, but GLKit, and OpenGL in general, is deprecated on all Apple platforms.
I suppose it would be possible to make this work by using something like ANGLE (https://github.com/kakashidinho/metalangle), but that should probably be reserved for apps that aren’t built with `gomobile build`.
File cmd/gomobile/env.go:
Patch Set #18, Line 63: return "darwin"
https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets/49560690#49560690 […]
Yeah, it’s weird.`TARGET_OS_IPHONE` really means "not straight macOS".
I’ll add a comment explaining why GOOS=darwin for maccatalyst.
Copied from the StackOverflow link:
TARGET_OS_MAC will be 1 for (probably) any Cocoa application running on an Apple platform.
TARGET_OS_OSX will only be 1 for macOS targets
TARGET_OS_IPHONE will be 1 for any non-Mac Apple products
TARGET_OS_IOS is just for iOS
TARGET_OS_MACCATALYST is just for Project Catalyst. It seems TARGET_OS_UIKITFORMAC will also work.
TARGET_OS_TV is just for tvOS
TARGET_OS_WATCH is just for watchOS
TARGET_OS_BRIDGE is just for bridgeOS (which currently doesn't even support 3rd-party apps so you'll likely always see that be 0)
TARGET_OS_DRIVERKIT will be 1 when building for DriverKit
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
Patch set 19:Code-Review +1
3 comments:
Patchset:
+Dmitri
File cmd/gomobile/env.go:
Patch Set #18, Line 80: return []string{"ios", "macos", "maccatalyst"}
Thanks, I'd want more comments to explain this situation like the above.
Ack
File cmd/gomobile/env.go:
Patch Set #19, Line 63: return "darwin"
Could you also leave comments here? ('see below' might be fine)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
Patch set 19:Run-TryBot +1
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #20 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 42bfc793be9d9c9e877f7a2d5c67119af3e2b6c6
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
A cmd/gomobile/bind_apple.go
D cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
A cmd/gomobile/build_apple_test.go
D cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M cmd/gomobile/writer_test.go
M example/bind/ios/README
A example/swift-package/Makefile
A example/swift-package/Package.swift
A example/swift-package/README.md
A example/swift-package/Sources/GetGo/get.go
A example/swift-package/Sources/GetKit/GetKit.swift
A example/swift-package/Tests/GetKitTests/GetTest.swift
24 files changed, 961 insertions(+), 575 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #21 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,macos,maccatalyst
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Updates https://golang.org/issues/47212
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
4 comments:
Commit Message:
Fixes golang/go#47212 […]
Ack
Patchset:
BTW, thanks for your patience reviewing my first big CL to Go (esp Hana and Hojime!).
I added an example Swift package with tests that shows how to build a binary XCFramework using gomobile for multiple targets that can be integrated into an iOS, macOS, or macCatalyst app.
File cmd/gomobile/env.go:
Patch Set #1, Line 63: switch platform {
Ack
File cmd/gomobile/writer_test.go:
Editor removed trailing tab on save. Want me to revert or leave it?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
1 comment:
File cmd/gomobile/writer_test.go:
Editor removed trailing tab on save. […]
Please revert this. In general, unnecessary changes should not be included in a CL when possible.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #22 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,macos,maccatalyst
It preserves the current behavior of -target=ios, which will build for ios
and iossimulator on supported architectures (arm64 and amd64).
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
2 comments:
Patchset:
Ack
Ack
File cmd/gomobile/writer_test.go:
Please revert this. In general, unnecessary changes should not be included in a CL when possible.
Ack
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #23 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,macos,maccatalyst
It preserves the current behavior of -target=ios, which will build for ios
and iossimulator on supported architectures (arm64 and amd64).
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Updates https://golang.org/issues/47212
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 14c8d17d536935ec81942b7ff3d77f3e03834c16
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
A cmd/gomobile/bind_apple.go
D cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
A cmd/gomobile/build_apple_test.go
D cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M example/bind/ios/README
A example/swift-package/Makefile
A example/swift-package/Package.swift
A example/swift-package/README.md
A example/swift-package/Sources/GetGo/get.go
A example/swift-package/Sources/GetKit/GetKit.swift
A example/swift-package/Tests/GetKitTests/GetTest.swift
23 files changed, 960 insertions(+), 574 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim.
Patch set 23:Run-TryBot +1Trust +1
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim.
1 comment:
File example/swift-package/README.md:
Is this new example needed in this CL? Sorry if I missed a discussion about this. As I cannot read Swift, I cannot review this part anyway...
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
1 comment:
File example/swift-package/README.md:
Is this new example needed in this CL? Sorry if I missed a discussion about this. […]
I think it’s helpful to show a minimal example of an XCFramework for multiple Apple platforms.
Unfortunately the other examples won’t build for macos or maccatalyst because of a dependency on deprecated APIs (GLKit). Updating these would be a significantly larger change.
You can see it work by running `make test` from the examples/swift-package directory. The embedded Go package exports a `func Get` that fetches a URL using (net/http).Get and returns the response bytes. If you have a Mac, you can give it a go!
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #24 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It make gomobile aware
of GOOS=ios and adds support for specifying specific Apple platforms,
instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,macos,maccatalyst
It preserves the current behavior of -target=ios, which will build for ios
and iossimulator on supported architectures (arm64 and amd64).
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Updates https://golang.org/issues/47228
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim.
Patch set 24:Trust +1
1 comment:
Patchset:
ping Dmitri
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hajime Hoshi.
2 comments:
File cmd/gomobile/bind_apple.go:
Patch Set #24, Line 1: // Copyright 2015 The Go Authors. All rights reserved.
would be nice if this file remains as bind_ios.go for now in this Cl, and then rename in the follow up change due to gerrit's limitation - the files are significantly changed too so gerrit doesn't seem to realize this as a renamed file any more.
File example/swift-package/README.md:
I think it’s helpful to show a minimal example of an XCFramework for multiple Apple platforms. […]
Thanks for the example - but I think this CL grew too large for our taste. It's ok to submit the example as a separate CL. If it was a gerrit CL, you could've stacked the related CLs. Unfortunately, github PR -> gerrit CL workflow doesn't allow it. Can you please make the example as a separate PR as a follow up change?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hajime Hoshi.
Gerrit Bot uploaded patch set #25 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It makes gomobile
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
3 comments:
Patchset:
Done. I’ll file two followup PRs after this is merged:
1. that adds the Swift package example
2. renames the ios/darwin files to apple
File cmd/gomobile/bind_apple.go:
Patch Set #24, Line 1: // Copyright 2015 The Go Authors. All rights reserved.
would be nice if this file remains as bind_ios. […]
Done
File example/swift-package/README.md:
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
Gerrit Bot uploaded patch set #26 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It makes gomobile
aware of GOOS=ios and adds support for specifying specific Apple
platforms, instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,macos,maccatalyst
It preserves the current behavior of -target=ios, which will build for
ios and iossimulator on supported architectures (arm64 and amd64).
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Updates https://golang.org/issues/47228
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 942f3b8dc1a9ad379974ea07b1bab00f62d2e380
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
M cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M example/bind/ios/README
15 files changed, 650 insertions(+), 369 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
1 comment:
File example/swift-package/README.md:
Here you go! http://golang.org/cl/350150
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hajime Hoshi.
Patch set 26:Run-TryBot +1Code-Review +2Trust +1
2 comments:
File .gitignore:
Patch Set #26, Line 11: .build
what is this for?
File cmd/gomobile/build.go:
Patch Set #26, Line 429: type orderedSet struct {
can this be deleted?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
2 comments:
File .gitignore:
Patch Set #26, Line 11: .build
what is this for?
Swift Package Manager, by default, stores compiled artifacts in ./.build.
File cmd/gomobile/build.go:
Patch Set #26, Line 429: type orderedSet struct {
can this be deleted?
Yes will do
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
Patch set 26:Trust +1
1 comment:
File .gitignore:
Patch Set #26, Line 11: .build
Swift Package Manager, by default, stores compiled artifacts in ./.build.
Can we add this at your next CL (the Swift example)?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #27 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It makes gomobile
aware of GOOS=ios and adds support for specifying specific Apple
platforms, instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,macos,maccatalyst
It preserves the current behavior of -target=ios, which will build for
ios and iossimulator on supported architectures (arm64 and amd64).
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Updates https://golang.org/issues/47228
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 4ca2ca50508235f959a83e13fbdbdd86d8be4608
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
M cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M example/bind/ios/README
15 files changed, 625 insertions(+), 370 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #28 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It makes gomobile
aware of GOOS=ios and adds support for specifying specific Apple
platforms, instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,macos,maccatalyst
It preserves the current behavior of -target=ios, which will build for
ios and iossimulator on supported architectures (arm64 and amd64).
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Updates https://golang.org/issues/47228
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: b08c472c7ab694921fc0ead5fda477e0f1452799
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
M cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
M example/bind/ios/README
M example/ivy/ios/README.md
M example/ivy/ios/ivy.xcodeproj/project.pbxproj
17 files changed, 647 insertions(+), 383 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim, Hajime Hoshi.
3 comments:
File .gitignore:
Patch Set #26, Line 11: .build
Can we add this at your next CL (the Swift example)?
Ack
Patchset:
@Hana per your comment in golang.org/cl/350150, I was able to make minimal changes to enable Ivy to work with the new .xcframework files and macOS via Mac Catalyst.
The existing README is missing one obvious step, which is assigning the PRODUCT_BUNDLE_IDENTIFIER so it can be built, so I can either:
1. ignore this and leave it
2. set PRODUCT_BUNDLE_IDENTIFIER to "io.robpike.$(PRODUCT_NAME:rfc1034identifier)"
3. update the README to note that users will need to manually set it before building
My preference is (2), since using any variation of "com.google.*" failed with Xcode managed certificates.
In addition, I added a couple files to .gitignore which Xcode writes when the user edits the Xcode project necessary to build the Ivy iOS app. These seemed analogous to the Android Studio files ignored below.
File cmd/gomobile/build.go:
Patch Set #26, Line 429: type orderedSet struct {
Yes will do
Done
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim.
Patch set 28:Run-TryBot +1Trust +1
1 comment:
Patchset:
TRY=ios
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov.
Patch set 28:Code-Review +2Trust +1
2 comments:
Patchset:
SlowBots beginning. Status page: https://farmer.golang. […]
Due to https://github.com/golang/go/issues/48419 we cannot use ios builder right now.
File example/bind/ios/README:
Patch Set #28, Line 1: 1. Use gomobile bind to bind the golang.org/x/mobile/example/bind/hello package.
Please have this and .gitignore update to handle ivy build in a separate CL.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim.
2 comments:
Patchset:
Due to https://github.com/golang/go/issues/48419 we cannot use ios builder right now.
Dang. Is this a macOS builder or running on iOS?
(asking because it needs to run on macOS for Xcode)
File example/bind/ios/README:
Patch Set #28, Line 1: 1. Use gomobile bind to bind the golang.org/x/mobile/example/bind/hello package.
Please have this and .gitignore update to handle ivy build in a separate CL.
Sure. It’s OK to have the example docs out of sync in the meantime?
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim.
Gerrit Bot uploaded patch set #29 to this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It makes gomobile
aware of GOOS=ios and adds support for specifying specific Apple
platforms, instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,macos,maccatalyst
It preserves the current behavior of -target=ios, which will build for
ios and iossimulator on supported architectures (arm64 and amd64).
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Updates https://golang.org/issues/47228
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 01ab28e63fe6890a9f9783e3fc41b1c895b0274d
GitHub-Pull-Request: golang/mobile#70
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
M cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
14 files changed, 621 insertions(+), 365 deletions(-)
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Dmitri Shuralyov, Hyang-Ah Hana Kim.
1 comment:
File example/bind/ios/README:
Patch Set #28, Line 1: 1. Use gomobile bind to bind the golang.org/x/mobile/example/bind/hello package.
Sure. […]
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Randy Reddig, Dmitri Shuralyov.
Patch set 29:Code-Review +2Trust +1
2 comments:
Patchset:
Dang. Is this a macOS builder or running on iOS? […]
Just checked the builder - it seems like this repository is currently not running on any of the macOS builders. iOS builder is a strange one - if I remember correctly, that's not suitable for x/mobile tests (it's primarily to run Go project's std tests to make sure core libraries run on 'iOS'). So, sadly there is builder now.
Another sad news is that there is no plan to have a macOS builder for this repo.
Patchset:
Submitting.
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
Hyang-Ah Hana Kim submitted this change.
cmd/gomobile: improve support for macOS and Catalyst
This is is a follow-up from my previous PR (#65). It makes gomobile
aware of GOOS=ios and adds support for specifying specific Apple
platforms, instead of overloading the "ios" platform.
Supported platforms: ios, iossimulator, macos, and maccatalyst
These can now be specified the -target argument to gomobile, e.g.:
gomobile build -target=ios,iossimulator,macos,maccatalyst
It preserves the current behavior of -target=ios, which will build for
ios and iossimulator on supported architectures (arm64 and amd64).
It adds platform-specific build tags so Go code can discriminate between
different Apple platforms like maccatalyst (UIKit on macOS).
This PR also fixes a number of broken tests.
TODO: cgo has a bug where c-archive builds targeting Catalyst will fail
unless -tags=ios is supplied. See https://golang.org/issues/47228
Fixes https://golang.org/issues/47212
Updates https://golang.org/issues/47228
Change-Id: Ib1a2f5302c5edd0704c13ffbe8f4061211f50d4e
GitHub-Last-Rev: 01ab28e63fe6890a9f9783e3fc41b1c895b0274d
GitHub-Pull-Request: golang/mobile#70
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/334689
Reviewed-by: Hyang-Ah Hana Kim <hya...@gmail.com>
Trust: Hyang-Ah Hana Kim <hya...@gmail.com>
Trust: Hajime Hoshi <hajim...@gmail.com>
---
M .gitignore
M cmd/gomobile/bind.go
M cmd/gomobile/bind_androidapp.go
M cmd/gomobile/bind_iosapp.go
M cmd/gomobile/bind_test.go
M cmd/gomobile/build.go
M cmd/gomobile/build_androidapp.go
R cmd/gomobile/build_apple.go
M cmd/gomobile/build_darwin_test.go
M cmd/gomobile/build_test.go
M cmd/gomobile/doc.go
M cmd/gomobile/env.go
M cmd/gomobile/init.go
M cmd/gomobile/version.go
14 files changed, 621 insertions(+), 365 deletions(-)
diff --git a/.gitignore b/.gitignore
index c7abc86..0e17991 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
*.apk
*.app
*.framework
+*.xcframework
*.aar
*.iml
.idea
diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go
index 6a80e53..efbc896 100644
--- a/cmd/gomobile/bind.go
+++ b/cmd/gomobile/bind.go
@@ -23,14 +23,14 @@
var cmdBind = &command{
run: runBind,
Name: "bind",
- Usage: "[-target android|ios] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]",
+ Usage: "[-target android|" + strings.Join(applePlatforms, "|") + "] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]",
Short: "build a library for Android and iOS",
Long: `
Bind generates language bindings for the package named by the import
path, and compiles a library for the named target system.
-The -target flag takes a target system name, either android (the
-default) or ios.
+The -target flag takes either android (the default), or one or more
+comma-delimited Apple platforms (` + strings.Join(applePlatforms, ", ") + `).
For -target android, the bind command produces an AAR (Android ARchive)
file that archives the precompiled Java API stub classes, the compiled
@@ -52,9 +52,9 @@
can be selected by specifying target type with the architecture name. E.g.,
-target=android/arm,android/386.
-For -target ios, gomobile must be run on an OS X machine with Xcode
-installed. The generated Objective-C types can be prefixed with the -prefix
-flag.
+For Apple -target platforms, gomobile must be run on an OS X machine with
+Xcode installed. The generated Objective-C types can be prefixed with the
+-prefix flag.
For -target android, the -bootclasspath and -classpath flags are used to
control the bootstrap classpath and the classpath for Go wrappers to Java
@@ -76,29 +76,29 @@
args := cmd.flag.Args()
- targetOS, targetArchs, err := parseBuildTarget(buildTarget)
+ targets, err := parseBuildTarget(buildTarget)
if err != nil {
return fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
}
- if bindJavaPkg != "" && targetOS != "android" {
- return fmt.Errorf("-javapkg is supported only for android target")
- }
- if bindPrefix != "" && targetOS != "ios" {
- return fmt.Errorf("-prefix is supported only for ios target")
- }
-
- if targetOS == "android" {
+ if isAndroidPlatform(targets[0].platform) {
+ if bindPrefix != "" {
+ return fmt.Errorf("-prefix is supported only for Apple targets")
+ }
if _, err := ndkRoot(); err != nil {
return err
}
+ } else {
+ if bindJavaPkg != "" {
+ return fmt.Errorf("-javapkg is supported only for android target")
+ }
}
var gobind string
if !buildN {
gobind, err = exec.LookPath("gobind")
if err != nil {
- return errors.New("gobind was not found. Please run gomobile init before trying again.")
+ return errors.New("gobind was not found. Please run gomobile init before trying again")
}
} else {
gobind = "gobind"
@@ -107,7 +107,10 @@
if len(args) == 0 {
args = append(args, ".")
}
- pkgs, err := importPackages(args, targetOS)
+
+ // TODO(ydnar): this should work, unless build tags affect loading a single package.
+ // Should we try to import packages with different build tags per platform?
+ pkgs, err := packages.Load(packagesConfig(targets[0]), args...)
if err != nil {
return err
}
@@ -115,28 +118,23 @@
// check if any of the package is main
for _, pkg := range pkgs {
if pkg.Name == "main" {
- return fmt.Errorf("binding 'main' package (%s) is not supported", pkg.PkgPath)
+ return fmt.Errorf(`binding "main" package (%s) is not supported`, pkg.PkgPath)
}
}
- switch targetOS {
- case "android":
- return goAndroidBind(gobind, pkgs, targetArchs)
- case "ios":
+ switch {
+ case isAndroidPlatform(targets[0].platform):
+ return goAndroidBind(gobind, pkgs, targets)
+ case isApplePlatform(targets[0].platform):
if !xcodeAvailable() {
- return fmt.Errorf("-target=ios requires XCode")
+ return fmt.Errorf("-target=%q requires Xcode", buildTarget)
}
- return goIOSBind(gobind, pkgs, targetArchs)
+ return goAppleBind(gobind, pkgs, targets)
default:
return fmt.Errorf(`invalid -target=%q`, buildTarget)
}
}
-func importPackages(args []string, targetOS string) ([]*packages.Package, error) {
- config := packagesConfig(targetOS)
- return packages.Load(config, args...)
-}
-
var (
bindPrefix string // -prefix
bindJavaPkg string // -javapkg
@@ -212,11 +210,12 @@
return generate(f)
}
-func packagesConfig(targetOS string) *packages.Config {
+func packagesConfig(t targetInfo) *packages.Config {
config := &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
+ config.Env = append(os.Environ(), "GOARCH="+t.arch, "GOOS="+platformOS(t.platform), "CGO_ENABLED=1")
+ tags := append(buildTags[:], platformTags(t.platform)...)
+
if len(tags) > 0 {
config.BuildFlags = []string{"-tags=" + strings.Join(tags, ",")}
}
@@ -224,11 +223,12 @@
}
// getModuleVersions returns a module information at the directory src.
-func getModuleVersions(targetOS string, targetArch string, src string) (*modfile.File, error) {
+func getModuleVersions(targetPlatform string, targetArch string, src string) (*modfile.File, error) {
cmd := exec.Command("go", "list")
- cmd.Env = append(os.Environ(), "GOOS="+targetOS, "GOARCH="+targetArch)
+ cmd.Env = append(os.Environ(), "GOOS="+platformOS(targetPlatform), "GOARCH="+targetArch)
- tags := buildTags
+ tags := append(buildTags[:], platformTags(targetPlatform)...)
+
// 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
@@ -281,7 +281,7 @@
}
// writeGoMod writes go.mod file at $WORK/src when Go modules are used.
-func writeGoMod(targetOS string, targetArch string) error {
+func writeGoMod(dir, targetPlatform, targetArch string) error {
m, err := areGoModulesUsed()
if err != nil {
return err
@@ -291,8 +291,8 @@
return nil
}
- return writeFile(filepath.Join(tmpdir, "src", "go.mod"), func(w io.Writer) error {
- f, err := getModuleVersions(targetOS, targetArch, ".")
+ return writeFile(filepath.Join(dir, "src", "go.mod"), func(w io.Writer) error {
+ f, err := getModuleVersions(targetPlatform, targetArch, ".")
if err != nil {
return err
}
diff --git a/cmd/gomobile/bind_androidapp.go b/cmd/gomobile/bind_androidapp.go
index 9eb7ce6..8ae9d4d 100644
--- a/cmd/gomobile/bind_androidapp.go
+++ b/cmd/gomobile/bind_androidapp.go
@@ -18,7 +18,7 @@
"golang.org/x/tools/go/packages"
)
-func goAndroidBind(gobind string, pkgs []*packages.Package, androidArchs []string) error {
+func goAndroidBind(gobind string, pkgs []*packages.Package, targets []targetInfo) error {
if sdkDir := os.Getenv("ANDROID_HOME"); sdkDir == "" {
return fmt.Errorf("this command requires ANDROID_HOME environment variable (path to the Android SDK)")
}
@@ -58,12 +58,12 @@
}
// Generate binding code and java source code only when processing the first package.
- for _, arch := range androidArchs {
- if err := writeGoMod("android", arch); err != nil {
+ for _, t := range targets {
+ if err := writeGoMod(tmpdir, "android", t.arch); err != nil {
return err
}
- env := androidEnv[arch]
+ env := androidEnv[t.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)
@@ -76,7 +76,7 @@
}
}
- toolchain := ndk.Toolchain(arch)
+ toolchain := ndk.Toolchain(t.arch)
err := goBuildAt(
filepath.Join(tmpdir, "src"),
"./gobind",
@@ -90,7 +90,7 @@
}
jsrc := filepath.Join(tmpdir, "java")
- if err := buildAAR(jsrc, androidDir, pkgs, androidArchs); err != nil {
+ if err := buildAAR(jsrc, androidDir, pkgs, targets); err != nil {
return err
}
return buildSrcJar(jsrc)
@@ -133,7 +133,7 @@
// aidl (optional, not relevant)
//
// javac and jar commands are needed to build classes.jar.
-func buildAAR(srcDir, androidDir string, pkgs []*packages.Package, androidArchs []string) (err error) {
+func buildAAR(srcDir, androidDir string, pkgs []*packages.Package, targets []targetInfo) (err error) {
var out io.Writer = ioutil.Discard
if buildO == "" {
buildO = pkgs[0].Name + ".aar"
@@ -235,8 +235,8 @@
}
}
- for _, arch := range androidArchs {
- toolchain := ndk.Toolchain(arch)
+ for _, t := range targets {
+ toolchain := ndk.Toolchain(t.arch)
lib := toolchain.abi + "/libgojni.so"
w, err = aarwcreate("jni/" + lib)
if err != nil {
diff --git a/cmd/gomobile/bind_iosapp.go b/cmd/gomobile/bind_iosapp.go
index e9615e8..bf0f37d 100644
--- a/cmd/gomobile/bind_iosapp.go
+++ b/cmd/gomobile/bind_iosapp.go
@@ -5,184 +5,236 @@
package main
import (
+ "errors"
"fmt"
"io"
"os/exec"
"path/filepath"
+ "strconv"
"strings"
"text/template"
"golang.org/x/tools/go/packages"
)
-func goIOSBind(gobind string, pkgs []*packages.Package, archs []string) error {
- // Run gobind to generate the bindings
- cmd := exec.Command(
- gobind,
- "-lang=go,objc",
- "-outdir="+tmpdir,
- )
- cmd.Env = append(cmd.Env, "GOOS=darwin")
- cmd.Env = append(cmd.Env, "CGO_ENABLED=1")
- tags := append(buildTags, "ios")
- 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
- }
-
- srcDir := filepath.Join(tmpdir, "src", "gobind")
-
+func goAppleBind(gobind string, pkgs []*packages.Package, targets []targetInfo) error {
var name string
var title string
+
if buildO == "" {
name = pkgs[0].Name
title = strings.Title(name)
- buildO = title + ".framework"
+ buildO = title + ".xcframework"
} else {
- if !strings.HasSuffix(buildO, ".framework") {
- return fmt.Errorf("static framework name %q missing .framework suffix", buildO)
+ if !strings.HasSuffix(buildO, ".xcframework") {
+ return fmt.Errorf("static framework name %q missing .xcframework suffix", buildO)
}
base := filepath.Base(buildO)
- name = base[:len(base)-len(".framework")]
+ name = base[:len(base)-len(".xcframework")]
title = strings.Title(name)
}
- fileBases := make([]string, len(pkgs)+1)
- for i, pkg := range pkgs {
- fileBases[i] = bindPrefix + strings.Title(pkg.Name)
+ if err := removeAll(buildO); err != nil {
+ return err
}
- fileBases[len(fileBases)-1] = "Universe"
-
- cmd = exec.Command("xcrun", "lipo", "-create")
modulesUsed, err := areGoModulesUsed()
if err != nil {
return err
}
- for _, arch := range archs {
- if err := writeGoMod("ios", arch); err != nil {
+ 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)
+ 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 := iosEnv[arch]
+ env := appleEnv[t.String()][:]
+ sdk := getenv(env, "DARWIN_SDK")
+
+ frameworkDir := filepath.Join(tmpdir, t.platform, sdk, title+".framework")
+ frameworkDirs = append(frameworkDirs, frameworkDir)
+ frameworkArchCount[frameworkDir] = frameworkArchCount[frameworkDir] + 1
+
+ fileBases := make([]string, len(pkgs)+1)
+ for i, pkg := range pkgs {
+ fileBases[i] = bindPrefix + strings.Title(pkg.Name)
+ }
+ fileBases[len(fileBases)-1] = "Universe"
+
// Add the generated packages to GOPATH for reverse bindings.
- gopath := fmt.Sprintf("GOPATH=%s%c%s", tmpdir, filepath.ListSeparator, goEnv("GOPATH"))
+ gopath := fmt.Sprintf("GOPATH=%s%c%s", outDir, filepath.ListSeparator, goEnv("GOPATH"))
env = append(env, gopath)
+ if err := writeGoMod(outDir, t.platform, t.arch); err != nil {
+ return err
+ }
+
// Run `go mod tidy` to force to create go.sum.
// Without go.sum, `go build` fails as of Go 1.16.
if modulesUsed {
- if err := goModTidyAt(filepath.Join(tmpdir, "src"), env); err != nil {
+ if err := goModTidyAt(outSrcDir, env); err != nil {
return err
}
}
- path, err := goIOSBindArchive(name, env, filepath.Join(tmpdir, "src"))
+ path, err := goAppleBindArchive(name+"-"+t.platform+"-"+t.arch, env, outSrcDir)
if err != nil {
- return fmt.Errorf("ios-%s: %v", arch, err)
+ return fmt.Errorf("%s/%s: %v", t.platform, t.arch, err)
}
- cmd.Args = append(cmd.Args, "-arch", archClang(arch), path)
- }
- // Build static framework output directory.
- if err := removeAll(buildO); err != nil {
- return err
- }
- headers := buildO + "/Versions/A/Headers"
- if err := mkdir(headers); err != nil {
- return err
- }
- if err := symlink("A", buildO+"/Versions/Current"); err != nil {
- return err
- }
- if err := symlink("Versions/Current/Headers", buildO+"/Headers"); err != nil {
- return err
- }
- if err := symlink("Versions/Current/"+title, buildO+"/"+title); err != nil {
- return err
- }
+ versionsDir := filepath.Join(frameworkDir, "Versions")
+ versionsADir := filepath.Join(versionsDir, "A")
+ titlePath := filepath.Join(versionsADir, title)
+ if frameworkArchCount[frameworkDir] > 1 {
+ // Not the first static lib, attach to a fat library and skip create headers
+ fatCmd := exec.Command(
+ "xcrun",
+ "lipo", path, titlePath, "-create", "-output", titlePath,
+ )
+ if err := runCmd(fatCmd); err != nil {
+ return err
+ }
+ continue
+ }
- cmd.Args = append(cmd.Args, "-o", buildO+"/Versions/A/"+title)
- if err := runCmd(cmd); err != nil {
- return err
- }
-
- // Copy header file next to output archive.
- headerFiles := make([]string, len(fileBases))
- if len(fileBases) == 1 {
- headerFiles[0] = title + ".h"
- err := copyFile(
- headers+"/"+title+".h",
- srcDir+"/"+bindPrefix+title+".objc.h",
- )
- if err != nil {
+ versionsAHeadersDir := filepath.Join(versionsADir, "Headers")
+ if err := mkdir(versionsAHeadersDir); err != nil {
return err
}
- } else {
- for i, fileBase := range fileBases {
- headerFiles[i] = fileBase + ".objc.h"
+ if err := symlink("A", filepath.Join(versionsDir, "Current")); err != nil {
+ return err
+ }
+ if err := symlink("Versions/Current/Headers", filepath.Join(frameworkDir, "Headers")); err != nil {
+ return err
+ }
+ if err := symlink(filepath.Join("Versions/Current", title), filepath.Join(frameworkDir, title)); err != nil {
+ return err
+ }
+
+ lipoCmd := exec.Command(
+ "xcrun",
+ "lipo", path, "-create", "-o", titlePath,
+ )
+ if err := runCmd(lipoCmd); err != nil {
+ return err
+ }
+
+ // Copy header file next to output archive.
+ var headerFiles []string
+ if len(fileBases) == 1 {
+ headerFiles = append(headerFiles, title+".h")
err := copyFile(
- headers+"/"+fileBase+".objc.h",
- srcDir+"/"+fileBase+".objc.h")
+ filepath.Join(versionsAHeadersDir, title+".h"),
+ filepath.Join(gobindDir, bindPrefix+title+".objc.h"),
+ )
+ if err != nil {
+ return err
+ }
+ } else {
+ for _, fileBase := range fileBases {
+ headerFiles = append(headerFiles, fileBase+".objc.h")
+ err := copyFile(
+ filepath.Join(versionsAHeadersDir, fileBase+".objc.h"),
+ filepath.Join(gobindDir, fileBase+".objc.h"),
+ )
+ if err != nil {
+ return err
+ }
+ }
+ err := copyFile(
+ filepath.Join(versionsAHeadersDir, "ref.h"),
+ filepath.Join(gobindDir, "ref.h"),
+ )
+ if err != nil {
+ return err
+ }
+ headerFiles = append(headerFiles, title+".h")
+ err = writeFile(filepath.Join(versionsAHeadersDir, title+".h"), func(w io.Writer) error {
+ return appleBindHeaderTmpl.Execute(w, map[string]interface{}{
+ "pkgs": pkgs, "title": title, "bases": fileBases,
+ })
+ })
if err != nil {
return err
}
}
- err := copyFile(
- headers+"/ref.h",
- srcDir+"/ref.h")
- if err != nil {
+
+ if err := mkdir(filepath.Join(versionsADir, "Resources")); err != nil {
return err
}
- headerFiles = append(headerFiles, title+".h")
- err = writeFile(headers+"/"+title+".h", func(w io.Writer) error {
- return iosBindHeaderTmpl.Execute(w, map[string]interface{}{
- "pkgs": pkgs, "title": title, "bases": fileBases,
- })
+ if err := symlink("Versions/Current/Resources", filepath.Join(frameworkDir, "Resources")); err != nil {
+ return err
+ }
+ err = writeFile(filepath.Join(frameworkDir, "Resources", "Info.plist"), func(w io.Writer) error {
+ _, err := w.Write([]byte(appleBindInfoPlist))
+ return err
})
if err != nil {
return err
}
+
+ var mmVals = struct {
+ Module string
+ Headers []string
+ }{
+ Module: title,
+ Headers: headerFiles,
+ }
+ err = writeFile(filepath.Join(versionsADir, "Modules", "module.modulemap"), func(w io.Writer) error {
+ return appleModuleMapTmpl.Execute(w, mmVals)
+ })
+ if err != nil {
+ return err
+ }
+ err = symlink(filepath.Join("Versions/Current/Modules"), filepath.Join(frameworkDir, "Modules"))
+ if err != nil {
+ return err
+ }
+
}
- resources := buildO + "/Versions/A/Resources"
- if err := mkdir(resources); err != nil {
- return err
- }
- if err := symlink("Versions/Current/Resources", buildO+"/Resources"); err != nil {
- return err
- }
- if err := writeFile(buildO+"/Resources/Info.plist", func(w io.Writer) error {
- _, err := w.Write([]byte(iosBindInfoPlist))
- return err
- }); err != nil {
- return err
+ // Finally combine all frameworks to an XCFramework
+ xcframeworkArgs := []string{"-create-xcframework"}
+
+ for _, dir := range frameworkDirs {
+ xcframeworkArgs = append(xcframeworkArgs, "-framework", dir)
}
- var mmVals = struct {
- Module string
- Headers []string
- }{
- Module: title,
- Headers: headerFiles,
- }
- err = writeFile(buildO+"/Versions/A/Modules/module.modulemap", func(w io.Writer) error {
- return iosModuleMapTmpl.Execute(w, mmVals)
- })
- if err != nil {
- return err
- }
- return symlink("Versions/Current/Modules", buildO+"/Modules")
+ xcframeworkArgs = append(xcframeworkArgs, "-output", buildO)
+ cmd := exec.Command("xcodebuild", xcframeworkArgs...)
+ err = runCmd(cmd)
+ return err
}
-const iosBindInfoPlist = `<?xml version="1.0" encoding="UTF-8"?>
+const appleBindInfoPlist = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
@@ -190,16 +242,15 @@
</plist>
`
-var iosModuleMapTmpl = template.Must(template.New("iosmmap").Parse(`framework module "{{.Module}}" {
+var appleModuleMapTmpl = template.Must(template.New("iosmmap").Parse(`framework module "{{.Module}}" {
header "ref.h"
{{range .Headers}} header "{{.}}"
{{end}}
export *
}`))
-func goIOSBindArchive(name string, env []string, gosrc string) (string, error) {
- arch := getenv(env, "GOARCH")
- archive := filepath.Join(tmpdir, name+"-"+arch+".a")
+func goAppleBindArchive(name string, env []string, gosrc string) (string, error) {
+ archive := filepath.Join(tmpdir, name+".a")
err := goBuildAt(gosrc, "./gobind", env, "-buildmode=c-archive", "-o", archive)
if err != nil {
return "", err
@@ -207,7 +258,7 @@
return archive, nil
}
-var iosBindHeaderTmpl = template.Must(template.New("ios.h").Parse(`
+var appleBindHeaderTmpl = template.Must(template.New("apple.h").Parse(`
// Objective-C API for talking to the following Go packages
//
{{range .pkgs}}// {{.PkgPath}}
diff --git a/cmd/gomobile/bind_test.go b/cmd/gomobile/bind_test.go
index ee8d35c..5970c04 100644
--- a/cmd/gomobile/bind_test.go
+++ b/cmd/gomobile/bind_test.go
@@ -98,7 +98,7 @@
}
}
-func TestBindIOS(t *testing.T) {
+func TestBindApple(t *testing.T) {
if !xcodeAvailable() {
t.Skip("Xcode is missing")
}
@@ -112,7 +112,7 @@
}()
buildN = true
buildX = true
- buildO = "Asset.framework"
+ buildO = "Asset.xcframework"
buildTarget = "ios/arm64"
tests := []struct {
@@ -126,7 +126,7 @@
prefix: "Foo",
},
{
- out: "Abcde.framework",
+ out: "Abcde.xcframework",
},
}
for _, tc := range tests {
@@ -159,12 +159,12 @@
Prefix string
}{
outputData: output,
- Output: buildO[:len(buildO)-len(".framework")],
+ Output: buildO[:len(buildO)-len(".xcframework")],
Prefix: tc.prefix,
}
wantBuf := new(bytes.Buffer)
- if err := bindIOSTmpl.Execute(wantBuf, data); err != nil {
+ if err := bindAppleTmpl.Execute(wantBuf, data); err != nil {
t.Errorf("%+v: computing diff failed: %v", tc, err)
continue
}
@@ -190,33 +190,34 @@
jar c -C $WORK/javac-output .
`))
-var bindIOSTmpl = template.Must(template.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile
+var bindAppleTmpl = template.Must(template.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile
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=ios GOARCH=arm64 CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 -fembed-bitcode -arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 -fembed-bitcode -arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 -fembed-bitcode -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 -fembed-bitcode -arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 -fembed-bitcode -arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 -fembed-bitcode -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
-ln -s Versions/Current/Headers {{.Output}}.framework/Headers
-ln -s Versions/Current/{{.Output}} {{.Output}}.framework/{{.Output}}
-xcrun lipo -create -arch arm64 $WORK/{{.Output}}-arm64.a -o {{.Output}}.framework/Versions/A/{{.Output}}
-cp $WORK/src/gobind/{{.Prefix}}Asset.objc.h {{.Output}}.framework/Versions/A/Headers/{{.Prefix}}Asset.objc.h
-mkdir -p {{.Output}}.framework/Versions/A/Headers
-cp $WORK/src/gobind/Universe.objc.h {{.Output}}.framework/Versions/A/Headers/Universe.objc.h
-mkdir -p {{.Output}}.framework/Versions/A/Headers
-cp $WORK/src/gobind/ref.h {{.Output}}.framework/Versions/A/Headers/ref.h
-mkdir -p {{.Output}}.framework/Versions/A/Headers
-mkdir -p {{.Output}}.framework/Versions/A/Headers
-mkdir -p {{.Output}}.framework/Versions/A/Resources
-ln -s Versions/Current/Resources {{.Output}}.framework/Resources
-mkdir -p {{.Output}}.framework/Resources
-mkdir -p {{.Output}}.framework/Versions/A/Modules
-ln -s Versions/Current/Modules {{.Output}}.framework/Modules
+rm -r -f "{{.Output}}.xcframework"
+GOOS=ios CGO_ENABLED=1 gobind -lang=go,objc -outdir=$WORK/ios -tags=ios{{if .Prefix}} -prefix={{.Prefix}}{{end}} golang.org/x/mobile/asset
+mkdir -p $WORK/ios/src
+PWD=$WORK/ios/src GOOS=ios GOARCH=arm64 GOFLAGS=-tags=ios CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_CXXFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_LDFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_ENABLED=1 DARWIN_SDK=iphoneos GOPATH=$WORK/ios:$GOPATH go mod tidy
+PWD=$WORK/ios/src GOOS=ios GOARCH=arm64 GOFLAGS=-tags=ios CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_CXXFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_LDFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_ENABLED=1 DARWIN_SDK=iphoneos GOPATH=$WORK/ios:$GOPATH go build -x -buildmode=c-archive -o $WORK/{{.Output}}-ios-arm64.a ./gobind
+mkdir -p $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Headers
+ln -s A $WORK/ios/iphoneos/{{.Output}}.framework/Versions/Current
+ln -s Versions/Current/Headers $WORK/ios/iphoneos/{{.Output}}.framework/Headers
+ln -s Versions/Current/{{.Output}} $WORK/ios/iphoneos/{{.Output}}.framework/{{.Output}}
+xcrun lipo $WORK/{{.Output}}-ios-arm64.a -create -o $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/{{.Output}}
+cp $WORK/ios/src/gobind/{{.Prefix}}Asset.objc.h $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Headers/{{.Prefix}}Asset.objc.h
+mkdir -p $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Headers
+cp $WORK/ios/src/gobind/Universe.objc.h $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Headers/Universe.objc.h
+mkdir -p $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Headers
+cp $WORK/ios/src/gobind/ref.h $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Headers/ref.h
+mkdir -p $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Headers
+mkdir -p $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Headers
+mkdir -p $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Resources
+ln -s Versions/Current/Resources $WORK/ios/iphoneos/{{.Output}}.framework/Resources
+mkdir -p $WORK/ios/iphoneos/{{.Output}}.framework/Resources
+mkdir -p $WORK/ios/iphoneos/{{.Output}}.framework/Versions/A/Modules
+ln -s Versions/Current/Modules $WORK/ios/iphoneos/{{.Output}}.framework/Modules
+xcodebuild -create-xcframework -framework $WORK/ios/iphoneos/{{.Output}}.framework -output {{.Output}}.xcframework
`))
-func TestBindIOSAll(t *testing.T) {
+func TestBindAppleAll(t *testing.T) {
if !xcodeAvailable() {
t.Skip("Xcode is missing")
}
@@ -230,7 +231,7 @@
}()
buildN = true
buildX = true
- buildO = "Asset.framework"
+ buildO = "Asset.xcframework"
buildTarget = "ios"
buf := new(bytes.Buffer)
@@ -290,7 +291,7 @@
case "android":
out = filepath.Join(dir, "cgopkg.aar")
case "ios":
- out = filepath.Join(dir, "Cgopkg.framework")
+ out = filepath.Join(dir, "Cgopkg.xcframework")
}
tests := []struct {
diff --git a/cmd/gomobile/build.go b/cmd/gomobile/build.go
index 79705ad..bd65f1c 100644
--- a/cmd/gomobile/build.go
+++ b/cmd/gomobile/build.go
@@ -8,11 +8,13 @@
import (
"bufio"
+ "errors"
"fmt"
"io"
"os"
"os/exec"
"regexp"
+ "strconv"
"strings"
"golang.org/x/tools/go/packages"
@@ -23,15 +25,15 @@
var cmdBuild = &command{
run: runBuild,
Name: "build",
- Usage: "[-target android|ios] [-o output] [-bundleid bundleID] [build flags] [package]",
+ Usage: "[-target android|" + strings.Join(applePlatforms, "|") + "] [-o output] [-bundleid bundleID] [build flags] [package]",
Short: "compile android APK and iOS app",
Long: `
Build compiles and encodes the app named by the import path.
The named package must define a main function.
-The -target flag takes a target system name, either android (the
-default) or ios.
+The -target flag takes either android (the default), or one or more
+comma-delimited Apple platforms (` + strings.Join(applePlatforms, ", ") + `).
For -target android, if an AndroidManifest.xml is defined in the
package directory, it is added to the APK output. Otherwise, a default
@@ -40,14 +42,22 @@
be selected by specifying target type with the architecture name. E.g.
-target=android/arm,android/386.
-For -target ios, gomobile must be run on an OS X machine with Xcode
-installed.
+For Apple -target platforms, gomobile must be run on an OS X machine with
+Xcode installed.
+
+By default, -target ios will generate an XCFramework for both ios
+and iossimulator. Multiple Apple targets can be specified, creating a "fat"
+XCFramework with each slice. To generate a fat XCFramework that supports
+iOS, macOS, and macCatalyst for all supportec architectures (amd64 and arm64),
+specify -target ios,macos,maccatalyst. A subset of instruction sets can be
+selectged by specifying the platform with an architecture name. E.g.
+-target=ios/arm64,maccatalyst/arm64.
If the package directory contains an assets subdirectory, its contents
are copied into the output.
Flag -iosversion sets the minimal version of the iOS SDK to compile against.
-The default version is 7.0.
+The default version is 13.0.
Flag -androidapi sets the Android API version to compile against.
The default and minimum is 15.
@@ -81,7 +91,7 @@
args := cmd.flag.Args()
- targetOS, targetArchs, err := parseBuildTarget(buildTarget)
+ targets, err := parseBuildTarget(buildTarget)
if err != nil {
return nil, fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
}
@@ -96,10 +106,14 @@
cmd.usage()
os.Exit(1)
}
- pkgs, err := packages.Load(packagesConfig(targetOS), buildPath)
+
+ // TODO(ydnar): this should work, unless build tags affect loading a single package.
+ // Should we try to import packages with different build tags per platform?
+ pkgs, err := packages.Load(packagesConfig(targets[0]), buildPath)
if err != nil {
return nil, err
}
+
// len(pkgs) can be more than 1 e.g., when the specified path includes `...`.
if len(pkgs) != 1 {
cmd.usage()
@@ -113,27 +127,32 @@
}
var nmpkgs map[string]bool
- switch targetOS {
- case "android":
+ switch {
+ case isAndroidPlatform(targets[0].platform):
if pkg.Name != "main" {
- for _, arch := range targetArchs {
- if err := goBuild(pkg.PkgPath, androidEnv[arch]); err != nil {
+ for _, t := range targets {
+ if err := goBuild(pkg.PkgPath, androidEnv[t.arch]); err != nil {
return nil, err
}
}
return pkg, nil
}
- nmpkgs, err = goAndroidBuild(pkg, targetArchs)
+ nmpkgs, err = goAndroidBuild(pkg, targets)
if err != nil {
return nil, err
}
- case "ios":
+ case isApplePlatform(targets[0].platform):
if !xcodeAvailable() {
- return nil, fmt.Errorf("-target=ios requires XCode")
+ return nil, fmt.Errorf("-target=%s requires XCode", buildTarget)
}
if pkg.Name != "main" {
- for _, arch := range targetArchs {
- if err := goBuild(pkg.PkgPath, iosEnv[arch]); err != nil {
+ for _, t := range targets {
+ // Catalyst support requires iOS 13+
+ v, _ := strconv.ParseFloat(buildIOSVersion, 64)
+ if t.platform == "maccatalyst" && v < 13.0 {
+ return nil, errors.New("catalyst requires -iosversion=13 or higher")
+ }
+ if err := goBuild(pkg.PkgPath, appleEnv[t.String()]); err != nil {
return nil, err
}
}
@@ -142,7 +161,7 @@
if buildBundleID == "" {
return nil, fmt.Errorf("-target=ios requires -bundleid set")
}
- nmpkgs, err = goIOSBuild(pkg, buildBundleID, targetArchs)
+ nmpkgs, err = goAppleBuild(pkg, buildBundleID, targets)
if err != nil {
return nil, err
}
@@ -236,7 +255,7 @@
cmd.flag.StringVar(&buildLdflags, "ldflags", "", "")
cmd.flag.StringVar(&buildTarget, "target", "android", "")
cmd.flag.StringVar(&buildBundleID, "bundleid", "", "")
- cmd.flag.StringVar(&buildIOSVersion, "iosversion", "7.0", "")
+ cmd.flag.StringVar(&buildIOSVersion, "iosversion", "13.0", "")
cmd.flag.IntVar(&buildAndroidAPI, "androidapi", minAndroidAPI, "")
cmd.flag.BoolVar(&buildA, "a", false, "")
@@ -292,7 +311,7 @@
cmd := exec.Command("go", subcmd)
tags := buildTags
if len(tags) > 0 {
- cmd.Args = append(cmd.Args, "-tags", strings.Join(tags, " "))
+ cmd.Args = append(cmd.Args, "-tags", strings.Join(tags, ","))
}
if buildV {
cmd.Args = append(cmd.Args, "-v")
@@ -332,60 +351,77 @@
return runCmd(cmd)
}
-func parseBuildTarget(buildTarget string) (os string, archs []string, _ error) {
+// parseBuildTarget parses buildTarget into 1 or more platforms and architectures.
+// Returns an error if buildTarget contains invalid input.
+// Example valid target strings:
+// android
+// android/arm64,android/386,android/amd64
+// ios,iossimulator,maccatalyst
+// macos/amd64
+func parseBuildTarget(buildTarget string) ([]targetInfo, error) {
if buildTarget == "" {
- return "", nil, fmt.Errorf(`invalid target ""`)
+ return nil, fmt.Errorf(`invalid target ""`)
}
- all := false
- archNames := []string{}
- for i, p := range strings.Split(buildTarget, ",") {
- osarch := strings.SplitN(p, "/", 2) // len(osarch) > 0
- if osarch[0] != "android" && osarch[0] != "ios" {
- return "", nil, fmt.Errorf(`unsupported os`)
- }
+ targets := []targetInfo{}
+ targetsAdded := make(map[targetInfo]bool)
- if i == 0 {
- os = osarch[0]
+ addTarget := func(platform, arch string) {
+ t := targetInfo{platform, arch}
+ if targetsAdded[t] {
+ return
}
+ targets = append(targets, t)
+ targetsAdded[t] = true
+ }
- if os != osarch[0] {
- return "", nil, fmt.Errorf(`cannot target different OSes`)
+ addPlatform := func(platform string) {
+ for _, arch := range platformArchs(platform) {
+ addTarget(platform, arch)
}
+ }
- if len(osarch) == 1 {
- all = true
+ var isAndroid, isApple bool
+ for _, target := range strings.Split(buildTarget, ",") {
+ tuple := strings.SplitN(target, "/", 2)
+ platform := tuple[0]
+ hasArch := len(tuple) == 2
+
+ if isAndroidPlatform(platform) {
+ isAndroid = true
+ } else if isApplePlatform(platform) {
+ isApple = true
} else {
- archNames = append(archNames, osarch[1])
+ return nil, fmt.Errorf("unsupported platform: %q", platform)
}
- }
+ if isAndroid && isApple {
+ return nil, fmt.Errorf(`cannot mix android and Apple platforms`)
+ }
- // verify all archs are supported one while deduping.
- isSupported := func(os, arch string) bool {
- for _, a := range allArchs(os) {
- if a == arch {
- return true
+ if hasArch {
+ arch := tuple[1]
+ if !isSupportedArch(platform, arch) {
+ return nil, fmt.Errorf(`unsupported platform/arch: %q`, target)
}
+ addTarget(platform, arch)
+ } else {
+ addPlatform(platform)
}
- return false
}
- targetOS := os
- seen := map[string]bool{}
- for _, arch := range archNames {
- if _, ok := seen[arch]; ok {
- continue
- }
- if !isSupported(os, arch) {
- return "", nil, fmt.Errorf(`unsupported arch: %q`, arch)
- }
-
- seen[arch] = true
- archs = append(archs, arch)
+ // Special case to build iossimulator if -target=ios
+ if buildTarget == "ios" {
+ addPlatform("iossimulator")
}
- if all {
- return targetOS, allArchs(os), nil
- }
- return targetOS, archs, nil
+ return targets, nil
+}
+
+type targetInfo struct {
+ platform string
+ arch string
+}
+
+func (t targetInfo) String() string {
+ return t.platform + "/" + t.arch
}
diff --git a/cmd/gomobile/build_androidapp.go b/cmd/gomobile/build_androidapp.go
index b97e945..b06ea29 100644
--- a/cmd/gomobile/build_androidapp.go
+++ b/cmd/gomobile/build_androidapp.go
@@ -24,7 +24,7 @@
"golang.org/x/tools/go/packages"
)
-func goAndroidBuild(pkg *packages.Package, androidArchs []string) (map[string]bool, error) {
+func goAndroidBuild(pkg *packages.Package, targets []targetInfo) (map[string]bool, error) {
ndkRoot, err := ndkRoot()
if err != nil {
return nil, err
@@ -68,8 +68,8 @@
libFiles := []string{}
nmpkgs := make(map[string]map[string]bool) // map: arch -> extractPkgs' output
- for _, arch := range androidArchs {
- toolchain := ndk.Toolchain(arch)
+ for _, t := range targets {
+ toolchain := ndk.Toolchain(t.arch)
libPath := "lib/" + toolchain.abi + "/lib" + libName + ".so"
libAbsPath := filepath.Join(tmpdir, libPath)
if err := mkdir(filepath.Dir(libAbsPath)); err != nil {
@@ -77,14 +77,14 @@
}
err = goBuild(
pkg.PkgPath,
- androidEnv[arch],
+ androidEnv[t.arch],
"-buildmode=c-shared",
"-o", libAbsPath,
)
if err != nil {
return nil, err
}
- nmpkgs[arch], err = extractPkgs(toolchain.Path(ndkRoot, "nm"), libAbsPath)
+ nmpkgs[t.arch], err = extractPkgs(toolchain.Path(ndkRoot, "nm"), libAbsPath)
if err != nil {
return nil, err
}
@@ -169,9 +169,9 @@
}
}
- for _, arch := range androidArchs {
- toolchain := ndk.Toolchain(arch)
- if nmpkgs[arch]["golang.org/x/mobile/exp/audio/al"] {
+ for _, t := range targets {
+ toolchain := ndk.Toolchain(t.arch)
+ if nmpkgs[t.arch]["golang.org/x/mobile/exp/audio/al"] {
dst := "lib/" + toolchain.abi + "/libopenal.so"
src := filepath.Join(gomobilepath, dst)
if _, err := os.Stat(src); err != nil {
@@ -282,7 +282,7 @@
}
// TODO: return nmpkgs
- return nmpkgs[androidArchs[0]], nil
+ return nmpkgs[targets[0].arch], nil
}
// androidPkgName sanitizes the go package name to be acceptable as a android
diff --git a/cmd/gomobile/build_iosapp.go b/cmd/gomobile/build_apple.go
similarity index 95%
rename from cmd/gomobile/build_iosapp.go
rename to cmd/gomobile/build_apple.go
index 0e9e063..2adaf3d 100644
--- a/cmd/gomobile/build_iosapp.go
+++ b/cmd/gomobile/build_apple.go
@@ -20,7 +20,7 @@
"golang.org/x/tools/go/packages"
)
-func goIOSBuild(pkg *packages.Package, bundleID string, archs []string) (map[string]bool, error) {
+func goAppleBuild(pkg *packages.Package, bundleID string, targets []targetInfo) (map[string]bool, error) {
src := pkg.PkgPath
if buildO != "" && !strings.HasSuffix(buildO, ".app") {
return nil, fmt.Errorf("-o must have an .app for -target=ios")
@@ -69,21 +69,32 @@
"-o", filepath.Join(tmpdir, "main/main"),
"-create",
)
+
var nmpkgs map[string]bool
- for _, arch := range archs {
- path := filepath.Join(tmpdir, arch)
+ builtArch := map[string]bool{}
+ for _, t := range targets {
+ // Only one binary per arch allowed
+ // e.g. ios/arm64 + iossimulator/amd64
+ if builtArch[t.arch] {
+ continue
+ }
+ builtArch[t.arch] = true
+
+ path := filepath.Join(tmpdir, t.platform, t.arch)
+
// Disable DWARF; see golang.org/issues/25148.
- if err := goBuild(src, iosEnv[arch], "-ldflags=-w", "-o="+path); err != nil {
+ if err := goBuild(src, appleEnv[t.String()], "-ldflags=-w", "-o="+path); err != nil {
return nil, err
}
if nmpkgs == nil {
var err error
- nmpkgs, err = extractPkgs(iosArmNM, path)
+ nmpkgs, err = extractPkgs(appleNM, path)
if err != nil {
return nil, err
}
}
cmd.Args = append(cmd.Args, path)
+
}
if err := runCmd(cmd); err != nil {
@@ -91,7 +102,7 @@
}
// TODO(jbd): Set the launcher icon.
- if err := iosCopyAssets(pkg, tmpdir); err != nil {
+ if err := appleCopyAssets(pkg, tmpdir); err != nil {
return nil, err
}
@@ -145,7 +156,7 @@
}
func detectTeamID() (string, error) {
- // Grabs the certificate for "Apple Development"; will not work if there
+ // Grabs the first certificate for "Apple Development"; will not work if there
// are multiple certificates and the first is not desired.
cmd := exec.Command(
"security", "find-certificate",
@@ -170,14 +181,14 @@
}
if len(cert.Subject.OrganizationalUnit) == 0 {
- err = fmt.Errorf("the signing certificate has no organizational unit (team ID).")
+ err = fmt.Errorf("the signing certificate has no organizational unit (team ID)")
return "", err
}
return cert.Subject.OrganizationalUnit[0], nil
}
-func iosCopyAssets(pkg *packages.Package, xcodeProjDir string) error {
+func appleCopyAssets(pkg *packages.Package, xcodeProjDir string) error {
dstAssets := xcodeProjDir + "/main/assets"
if err := mkdir(dstAssets); err != nil {
return err
@@ -424,7 +435,6 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/cmd/gomobile/build_darwin_test.go b/cmd/gomobile/build_darwin_test.go
index 12d9a4b..2fac27c 100644
--- a/cmd/gomobile/build_darwin_test.go
+++ b/cmd/gomobile/build_darwin_test.go
@@ -12,7 +12,7 @@
"text/template"
)
-func TestIOSBuild(t *testing.T) {
+func TestAppleBuild(t *testing.T) {
if !xcodeAvailable() {
t.Skip("Xcode is missing")
}
@@ -41,10 +41,13 @@
for _, test := range tests {
buf := new(bytes.Buffer)
xout = buf
+ var tmpl *template.Template
if test.main {
buildO = "basic.app"
+ tmpl = appleMainBuildTmpl
} else {
buildO = ""
+ tmpl = appleOtherBuildTmpl
}
cmdBuild.flag.Parse([]string{test.pkg})
err := runBuild(cmdBuild)
@@ -68,18 +71,20 @@
TeamID string
Pkg string
Main bool
+ BuildO string
}{
outputData: output,
TeamID: teamID,
Pkg: test.pkg,
Main: test.main,
+ BuildO: buildO,
}
got := filepath.ToSlash(buf.String())
wantBuf := new(bytes.Buffer)
- if err := iosBuildTmpl.Execute(wantBuf, data); err != nil {
+ if err := tmpl.Execute(wantBuf, data); err != nil {
t.Fatalf("computing diff failed: %v", err)
}
@@ -94,18 +99,25 @@
}
}
-var iosBuildTmpl = template.Must(infoplistTmpl.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile
-WORK=$WORK{{if .Main}}
+var appleMainBuildTmpl = template.Must(infoplistTmpl.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile
+WORK=$WORK
mkdir -p $WORK/main.xcodeproj
echo "{{.Xproj}}" > $WORK/main.xcodeproj/project.pbxproj
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}}
-GOOS=ios GOARCH=arm64 CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 -fembed-bitcode -arch arm64 CGO_CXXFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 -fembed-bitcode -arch arm64 CGO_LDFLAGS=-isysroot=iphoneos -miphoneos-version-min=7.0 -fembed-bitcode -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 -fembed-bitcode -arch x86_64 CGO_CXXFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 -fembed-bitcode -arch x86_64 CGO_LDFLAGS=-isysroot=iphonesimulator -mios-simulator-version-min=7.0 -fembed-bitcode -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
+echo "{{.Xcontents}}" > $WORK/main/Images.xcassets/AppIcon.appiconset/Contents.json
+GOOS=ios GOARCH=arm64 GOFLAGS=-tags=ios CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_CXXFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_LDFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_ENABLED=1 DARWIN_SDK=iphoneos go build -tags tag1 -x -ldflags=-w -o=$WORK/ios/arm64 {{.Pkg}}
+GOOS=ios GOARCH=amd64 GOFLAGS=-tags=ios CC=iphonesimulator-clang CXX=iphonesimulator-clang++ CGO_CFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch x86_64 CGO_CXXFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch x86_64 CGO_LDFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch x86_64 CGO_ENABLED=1 DARWIN_SDK=iphonesimulator go build -tags tag1 -x -ldflags=-w -o=$WORK/iossimulator/amd64 {{.Pkg}}
+xcrun lipo -o $WORK/main/main -create $WORK/ios/arm64 $WORK/iossimulator/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}}
+mv $WORK/build/Release-iphoneos/main.app {{.BuildO}}
+`))
+
+var appleOtherBuildTmpl = template.Must(infoplistTmpl.New("output").Parse(`GOMOBILE={{.GOPATH}}/pkg/gomobile
+WORK=$WORK
+GOOS=ios GOARCH=arm64 GOFLAGS=-tags=ios CC=iphoneos-clang CXX=iphoneos-clang++ CGO_CFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_CXXFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_LDFLAGS=-isysroot iphoneos -miphoneos-version-min=13.0 -fembed-bitcode -arch arm64 CGO_ENABLED=1 DARWIN_SDK=iphoneos go build -tags tag1 -x {{.Pkg}}
+GOOS=ios GOARCH=arm64 GOFLAGS=-tags=ios CC=iphonesimulator-clang CXX=iphonesimulator-clang++ CGO_CFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch arm64 CGO_CXXFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch arm64 CGO_LDFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch arm64 CGO_ENABLED=1 DARWIN_SDK=iphonesimulator go build -tags tag1 -x {{.Pkg}}
+GOOS=ios GOARCH=amd64 GOFLAGS=-tags=ios CC=iphonesimulator-clang CXX=iphonesimulator-clang++ CGO_CFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch x86_64 CGO_CXXFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch x86_64 CGO_LDFLAGS=-isysroot iphonesimulator -mios-simulator-version-min=13.0 -fembed-bitcode -arch x86_64 CGO_ENABLED=1 DARWIN_SDK=iphonesimulator go build -tags tag1 -x {{.Pkg}}
`))
diff --git a/cmd/gomobile/build_test.go b/cmd/gomobile/build_test.go
index f7eab6c..ff21f87 100644
--- a/cmd/gomobile/build_test.go
+++ b/cmd/gomobile/build_test.go
@@ -114,46 +114,63 @@
GOOS=android GOARCH=arm CC=$NDK_PATH/toolchains/llvm/prebuilt/{{.NDKARCH}}/bin/armv7a-linux-androideabi16-clang CXX=$NDK_PATH/toolchains/llvm/prebuilt/{{.NDKARCH}}/bin/armv7a-linux-androideabi16-clang++ CGO_ENABLED=1 GOARM=7 go build -tags tag1 -x -buildmode=c-shared -o $WORK/lib/armeabi-v7a/libbasic.so golang.org/x/mobile/example/basic
`))
-func TestParseBuildTargetFlag(t *testing.T) {
- androidArchs := strings.Join(allArchs("android"), ",")
- iosArchs := strings.Join(allArchs("ios"), ",")
+func TestParseBuildTarget(t *testing.T) {
+ wantAndroid := "android/" + strings.Join(platformArchs("android"), ",android/")
tests := []struct {
- in string
- wantErr bool
- wantOS string
- wantArchs string
+ in string
+ wantErr bool
+ want string
}{
- {"android", false, "android", androidArchs},
- {"android,android/arm", false, "android", androidArchs},
- {"android/arm", false, "android", "arm"},
+ {"android", false, wantAndroid},
+ {"android,android/arm", false, wantAndroid},
+ {"android/arm", false, "android/arm"},
- {"ios", false, "ios", iosArchs},
- {"ios,ios/arm64", false, "ios", iosArchs},
- {"ios/arm64", false, "ios", "arm64"},
- {"ios/amd64", false, "ios", "amd64"},
+ {"ios", false, "ios/arm64,iossimulator/arm64,iossimulator/amd64"},
+ {"ios,ios/arm64", false, "ios/arm64"},
+ {"ios/arm64", false, "ios/arm64"},
- {"", true, "", ""},
- {"linux", true, "", ""},
- {"android/x86", true, "", ""},
- {"android/arm5", true, "", ""},
- {"ios/mips", true, "", ""},
- {"android,ios", true, "", ""},
- {"ios,android", true, "", ""},
+ {"iossimulator", false, "iossimulator/arm64,iossimulator/amd64"},
+ {"iossimulator/amd64", false, "iossimulator/amd64"},
+
+ {"macos", false, "macos/arm64,macos/amd64"},
+ {"macos,ios/arm64", false, "macos/arm64,macos/amd64,ios/arm64"},
+ {"macos/arm64", false, "macos/arm64"},
+ {"macos/amd64", false, "macos/amd64"},
+
+ {"maccatalyst", false, "maccatalyst/arm64,maccatalyst/amd64"},
+ {"maccatalyst,ios/arm64", false, "maccatalyst/arm64,maccatalyst/amd64,ios/arm64"},
+ {"maccatalyst/arm64", false, "maccatalyst/arm64"},
+ {"maccatalyst/amd64", false, "maccatalyst/amd64"},
+
+ {"", true, ""},
+ {"linux", true, ""},
+ {"android/x86", true, ""},
+ {"android/arm5", true, ""},
+ {"ios/mips", true, ""},
+ {"android,ios", true, ""},
+ {"ios,android", true, ""},
+ {"ios/amd64", true, ""},
}
for _, tc := range tests {
- gotOS, gotArchs, err := parseBuildTarget(tc.in)
- if tc.wantErr {
- if err == nil {
- t.Errorf("-target=%q; want error, got (%q, %q, nil)", tc.in, gotOS, gotArchs)
+ t.Run(tc.in, func(t *testing.T) {
+ targets, err := parseBuildTarget(tc.in)
+ var s []string
+ for _, t := range targets {
+ s = append(s, t.String())
}
- continue
- }
- if err != nil || gotOS != tc.wantOS || strings.Join(gotArchs, ",") != tc.wantArchs {
- t.Errorf("-target=%q; want (%v, [%v], nil), got (%q, %q, %v)",
- tc.in, tc.wantOS, tc.wantArchs, gotOS, gotArchs, err)
- }
+ got := strings.Join(s, ",")
+ if tc.wantErr {
+ if err == nil {
+ t.Errorf("-target=%q; want error, got (%q, nil)", tc.in, got)
+ }
+ return
+ }
+ if err != nil || got != tc.want {
+ t.Errorf("-target=%q; want (%q, nil), got (%q, %v)", tc.in, tc.want, got, err)
+ }
+ })
}
}
diff --git a/cmd/gomobile/doc.go b/cmd/gomobile/doc.go
index aeff5f6..8522dd6 100644
--- a/cmd/gomobile/doc.go
+++ b/cmd/gomobile/doc.go
@@ -35,13 +35,13 @@
Usage:
- gomobile bind [-target android|ios] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]
+ gomobile bind [-target android|ios|iossimulator|macos|maccatalyst] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]
Bind generates language bindings for the package named by the import
path, and compiles a library for the named target system.
-The -target flag takes a target system name, either android (the
-default) or ios.
+The -target flag takes either android (the default), or one or more
+comma-delimited Apple platforms (ios, iossimulator, macos, maccatalyst).
For -target android, the bind command produces an AAR (Android ARchive)
file that archives the precompiled Java API stub classes, the compiled
@@ -63,9 +63,9 @@
can be selected by specifying target type with the architecture name. E.g.,
-target=android/arm,android/386.
-For -target ios, gomobile must be run on an OS X machine with Xcode
-installed. The generated Objective-C types can be prefixed with the -prefix
-flag.
+For Apple -target platforms, gomobile must be run on an OS X machine with
+Xcode installed. The generated Objective-C types can be prefixed with the
+-prefix flag.
For -target android, the -bootclasspath and -classpath flags are used to
control the bootstrap classpath and the classpath for Go wrappers to Java
@@ -81,14 +81,14 @@
Usage:
- gomobile build [-target android|ios] [-o output] [-bundleid bundleID] [build flags] [package]
+ gomobile build [-target android|ios|iossimulator|macos|maccatalyst] [-o output] [-bundleid bundleID] [build flags] [package]
Build compiles and encodes the app named by the import path.
The named package must define a main function.
-The -target flag takes a target system name, either android (the
-default) or ios.
+The -target flag takes either android (the default), or one or more
+comma-delimited Apple platforms (ios, iossimulator, macos, maccatalyst).
For -target android, if an AndroidManifest.xml is defined in the
package directory, it is added to the APK output. Otherwise, a default
@@ -97,14 +97,22 @@
be selected by specifying target type with the architecture name. E.g.
-target=android/arm,android/386.
-For -target ios, gomobile must be run on an OS X machine with Xcode
-installed.
+For Apple -target platforms, gomobile must be run on an OS X machine with
+Xcode installed.
+
+By default, -target ios will generate an XCFramework for both ios
+and iossimulator. Multiple Apple targets can be specified, creating a "fat"
+XCFramework with each slice. To generate a fat XCFramework that supports
+iOS, macOS, and macCatalyst for all supportec architectures (amd64 and arm64),
+specify -target ios,macos,maccatalyst. A subset of instruction sets can be
+selectged by specifying the platform with an architecture name. E.g.
+-target=ios/arm64,maccatalyst/arm64.
If the package directory contains an assets subdirectory, its contents
are copied into the output.
Flag -iosversion sets the minimal version of the iOS SDK to compile against.
-The default version is 7.0.
+The default version is 13.0.
Flag -androidapi sets the Android API version to compile against.
The default and minimum is 15.
diff --git a/cmd/gomobile/env.go b/cmd/gomobile/env.go
index a178489..69bb710 100644
--- a/cmd/gomobile/env.go
+++ b/cmd/gomobile/env.go
@@ -17,23 +17,95 @@
androidEnv map[string][]string // android arch -> []string
- iosEnv map[string][]string
+ appleEnv map[string][]string
androidArmNM string
- iosArmNM string
+ appleNM string
)
-func allArchs(targetOS string) []string {
- switch targetOS {
+func isAndroidPlatform(platform string) bool {
+ return platform == "android"
+}
+
+func isApplePlatform(platform string) bool {
+ return contains(applePlatforms, platform)
+}
+
+var applePlatforms = []string{"ios", "iossimulator", "macos", "maccatalyst"}
+
+func platformArchs(platform string) []string {
+ switch platform {
case "ios":
+ return []string{"arm64"}
+ case "iossimulator":
+ return []string{"arm64", "amd64"}
+ case "macos", "maccatalyst":
return []string{"arm64", "amd64"}
case "android":
return []string{"arm", "arm64", "386", "amd64"}
default:
- panic(fmt.Sprintf("unexpected target OS: %s", targetOS))
+ panic(fmt.Sprintf("unexpected platform: %s", platform))
}
}
+func isSupportedArch(platform, arch string) bool {
+ return contains(platformArchs(platform), arch)
+}
+
+// platformOS returns the correct GOOS value for platform.
+func platformOS(platform string) string {
+ switch platform {
+ case "android":
+ return "android"
+ case "ios", "iossimulator":
+ return "ios"
+ case "macos", "maccatalyst":
+ // For "maccatalyst", Go packages should be built with GOOS=darwin,
+ // not GOOS=ios, since the underlying OS (and kernel, runtime) is macOS.
+ // We also apply a "macos" or "maccatalyst" build tag, respectively.
+ // See below for additional context.
+ return "darwin"
+ default:
+ panic(fmt.Sprintf("unexpected platform: %s", platform))
+ }
+}
+
+func platformTags(platform string) []string {
+ switch platform {
+ case "android":
+ return []string{"android"}
+ case "ios", "iossimulator":
+ return []string{"ios"}
+ case "macos":
+ return []string{"macos"}
+ case "maccatalyst":
+ // Mac Catalyst is a subset of iOS APIs made available on macOS
+ // designed to ease porting apps developed for iPad to macOS.
+ // See https://developer.apple.com/mac-catalyst/.
+ // Because of this, when building a Go package targeting maccatalyst,
+ // GOOS=darwin (not ios). To bridge the gap and enable maccatalyst
+ // packages to be compiled, we also specify the "ios" build tag.
+ // To help discriminate between darwin, ios, macos, and maccatalyst
+ // targets, there is also a "maccatalyst" tag.
+ // Some additional context on this can be found here:
+ // https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets/49560690#49560690
+ // TODO(ydnar): remove tag "ios" when cgo supports Catalyst
+ // See golang.org/issues/47228
+ return []string{"ios", "macos", "maccatalyst"}
+ default:
+ panic(fmt.Sprintf("unexpected platform: %s", platform))
+ }
+}
+
+func contains(haystack []string, needle string) bool {
+ for _, v := range haystack {
+ if v == needle {
+ return true
+ }
+ }
+ return false
+}
+
func buildEnvInit() (cleanup func(), err error) {
// Find gomobilepath.
gopath := goEnv("GOPATH")
@@ -123,37 +195,85 @@
return nil
}
- iosArmNM = "nm"
- iosEnv = make(map[string][]string)
- for _, arch := range allArchs("ios") {
- var env []string
- var err error
- var clang, cflags string
- switch arch {
- case "arm64":
- clang, cflags, err = envClang("iphoneos")
- cflags += " -miphoneos-version-min=" + buildIOSVersion
- case "amd64":
- clang, cflags, err = envClang("iphonesimulator")
- cflags += " -mios-simulator-version-min=" + buildIOSVersion
- default:
- panic(fmt.Errorf("unknown GOARCH: %q", arch))
+ appleNM = "nm"
+ appleEnv = make(map[string][]string)
+ for _, platform := range applePlatforms {
+ for _, arch := range platformArchs(platform) {
+ var env []string
+ var goos, sdk, clang, cflags string
+ var err error
+ switch platform {
+ case "ios":
+ goos = "ios"
+ sdk = "iphoneos"
+ clang, cflags, err = envClang(sdk)
+ cflags += " -miphoneos-version-min=" + buildIOSVersion
+ cflags += " -fembed-bitcode"
+ case "iossimulator":
+ goos = "ios"
+ sdk = "iphonesimulator"
+ clang, cflags, err = envClang(sdk)
+ cflags += " -mios-simulator-version-min=" + buildIOSVersion
+ cflags += " -fembed-bitcode"
+ case "maccatalyst":
+ // Mac Catalyst is a subset of iOS APIs made available on macOS
+ // designed to ease porting apps developed for iPad to macOS.
+ // See https://developer.apple.com/mac-catalyst/.
+ // Because of this, when building a Go package targeting maccatalyst,
+ // GOOS=darwin (not ios). To bridge the gap and enable maccatalyst
+ // packages to be compiled, we also specify the "ios" build tag.
+ // To help discriminate between darwin, ios, macos, and maccatalyst
+ // targets, there is also a "maccatalyst" tag.
+ // Some additional context on this can be found here:
+ // https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets/49560690#49560690
+ goos = "darwin"
+ sdk = "macosx"
+ clang, cflags, err = envClang(sdk)
+ // TODO(ydnar): the following 3 lines MAY be needed to compile
+ // packages or apps for maccatalyst. Commenting them out now in case
+ // it turns out they are necessary. Currently none of the example
+ // apps will build for macos or maccatalyst because they have a
+ // GLKit dependency, which is deprecated on all Apple platforms, and
+ // broken on maccatalyst (GLKView isn’t available).
+ // sysroot := strings.SplitN(cflags, " ", 2)[1]
+ // cflags += " -isystem " + sysroot + "/System/iOSSupport/usr/include"
+ // cflags += " -iframework " + sysroot + "/System/iOSSupport/System/Library/Frameworks"
+ switch arch {
+ case "amd64":
+ cflags += " -target x86_64-apple-ios" + buildIOSVersion + "-macabi"
+ case "arm64":
+ cflags += " -target arm64-apple-ios" + buildIOSVersion + "-macabi"
+ cflags += " -fembed-bitcode"
+ }
+ case "macos":
+ goos = "darwin"
+ sdk = "macosx" // Note: the SDK is called "macosx", not "macos"
+ clang, cflags, err = envClang(sdk)
+ if arch == "arm64" {
+ cflags += " -fembed-bitcode"
+ }
+ default:
+ panic(fmt.Errorf("unknown Apple target: %s/%s", platform, arch))
+ }
+
+ if err != nil {
+ return err
+ }
+
+ env = append(env,
+ "GOOS="+goos,
+ "GOARCH="+arch,
+ "GOFLAGS="+"-tags="+strings.Join(platformTags(platform), ","),
+ "CC="+clang,
+ "CXX="+clang+"++",
+ "CGO_CFLAGS="+cflags+" -arch "+archClang(arch),
+ "CGO_CXXFLAGS="+cflags+" -arch "+archClang(arch),
+ "CGO_LDFLAGS="+cflags+" -arch "+archClang(arch),
+ "CGO_ENABLED=1",
+ "DARWIN_SDK="+sdk,
+ )
+ appleEnv[platform+"/"+arch] = env
}
- if err != nil {
- return err
- }
- cflags += " -fembed-bitcode"
- env = append(env,
- "GOOS=ios",
- "GOARCH="+arch,
- "CC="+clang,
- "CXX="+clang+"++",
- "CGO_CFLAGS="+cflags+" -arch "+archClang(arch),
- "CGO_CXXFLAGS="+cflags+" -arch "+archClang(arch),
- "CGO_LDFLAGS="+cflags+" -arch "+archClang(arch),
- "CGO_ENABLED=1",
- )
- iosEnv[arch] = env
}
return nil
@@ -186,7 +306,7 @@
func envClang(sdkName string) (clang, cflags string, err error) {
if buildN {
- return sdkName + "-clang", "-isysroot=" + sdkName, nil
+ return sdkName + "-clang", "-isysroot " + sdkName, nil
}
cmd := exec.Command("xcrun", "--sdk", sdkName, "--find", "clang")
out, err := cmd.CombinedOutput()
diff --git a/cmd/gomobile/init.go b/cmd/gomobile/init.go
index 00b9a56..172d015 100644
--- a/cmd/gomobile/init.go
+++ b/cmd/gomobile/init.go
@@ -167,7 +167,7 @@
}
}
- for _, arch := range allArchs("android") {
+ for _, arch := range platformArchs("android") {
t := ndk[arch]
abi := t.arch
if abi == "arm" {
diff --git a/cmd/gomobile/version.go b/cmd/gomobile/version.go
index 8c09a44..b791556 100644
--- a/cmd/gomobile/version.go
+++ b/cmd/gomobile/version.go
@@ -53,7 +53,7 @@
// Supported platforms
platforms := "android"
if xcodeAvailable() {
- platforms = "android,ios"
+ platforms += "," + strings.Join(applePlatforms, ",")
}
// ANDROID_HOME, sdk build tool version
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.
2 comments:
Patchset:
Another sad news is that there is no plan to have a macOS builder for this repo.
What’s the context there? It’s pretty obvious this repo would benefit from macOS tests.
My guess is it’s unorthodox, but would a macOS test suite running on GitHub Actions be accepted?
Patchset:
Thanks for merging!
To view, visit change 334689. To unsubscribe, or for help writing mail filters, visit settings.