This change permits gomobile to build iOS applications by properly set GOOS=ios in the build process. The change is locally tested on darwin/arm64, and golang.org/x/mobile/example/basic can be build using the following commands: gomobile build -target=android -o=basic.apk \ golang.org/x/mobile/example/basic gomobile build -target=ios -bundleid=org.golang.gomobiletest \ -o=basic.app golang.org/x/mobile/example/basic The built binaries are also tested on iOS 15 beta7 and Android 12 API31. Updates golang/go#47952 Fixes golang/go#47238 Change-Id: Ibf40a77933ac957640c78d0dbc1af043477e4b3a Reviewed-on: https://go-review.googlesource.com/c/mobile/+/346150 Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Hajime Hoshi <hajimehoshi@gmail.com> Trust: Dmitri Shuralyov <dmitshur@golang.org> Trust: Bryan C. Mills <bcmills@google.com> Run-TryBot: Hajime Hoshi <hajimehoshi@gmail.com> TryBot-Result: Go Bot <gobot@golang.org>
205 lines
4.2 KiB
Go
205 lines
4.2 KiB
Go
// 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
|
|
|
|
//go:generate gomobile help documentation doc.go
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"html/template"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
)
|
|
|
|
var (
|
|
gomobileName = "gomobile"
|
|
goVersionOut = []byte(nil)
|
|
)
|
|
|
|
func printUsage(w io.Writer) {
|
|
bufw := bufio.NewWriter(w)
|
|
if err := usageTmpl.Execute(bufw, commands); err != nil {
|
|
panic(err)
|
|
}
|
|
bufw.Flush()
|
|
}
|
|
|
|
func main() {
|
|
gomobileName = os.Args[0]
|
|
flag.Usage = func() {
|
|
printUsage(os.Stderr)
|
|
os.Exit(2)
|
|
}
|
|
flag.Parse()
|
|
log.SetFlags(0)
|
|
|
|
args := flag.Args()
|
|
if len(args) < 1 {
|
|
flag.Usage()
|
|
}
|
|
|
|
if args[0] == "help" {
|
|
if len(args) == 3 && args[1] == "documentation" {
|
|
helpDocumentation(args[2])
|
|
return
|
|
}
|
|
help(args[1:])
|
|
return
|
|
}
|
|
|
|
if err := determineGoVersion(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "%s: %v\n", gomobileName, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
for _, cmd := range commands {
|
|
if cmd.Name == args[0] {
|
|
cmd.flag.Usage = func() {
|
|
cmd.usage()
|
|
os.Exit(1)
|
|
}
|
|
cmd.flag.Parse(args[1:])
|
|
if err := cmd.run(cmd); err != nil {
|
|
msg := err.Error()
|
|
if msg != "" {
|
|
fmt.Fprintf(os.Stderr, "%s: %v\n", os.Args[0], err)
|
|
}
|
|
os.Exit(1)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
fmt.Fprintf(os.Stderr, "%s: unknown subcommand %q\nRun 'gomobile help' for usage.\n", os.Args[0], args[0])
|
|
os.Exit(2)
|
|
}
|
|
|
|
func determineGoVersion() error {
|
|
goVersionOut, err := exec.Command("go", "version").CombinedOutput()
|
|
if err != nil {
|
|
return fmt.Errorf("'go version' failed: %v, %s", err, goVersionOut)
|
|
}
|
|
var minor int
|
|
if _, err := fmt.Sscanf(string(goVersionOut), "go version go1.%d", &minor); err != nil {
|
|
// Ignore unknown versions; it's probably a devel version.
|
|
return nil
|
|
}
|
|
if minor < 16 {
|
|
return errors.New("Go 1.16 or newer is required")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func help(args []string) {
|
|
if len(args) == 0 {
|
|
printUsage(os.Stdout)
|
|
return // succeeded at helping
|
|
}
|
|
if len(args) != 1 {
|
|
fmt.Fprintf(os.Stderr, "usage: %s help command\n\nToo many arguments given.\n", gomobileName)
|
|
os.Exit(2) // failed to help
|
|
}
|
|
|
|
arg := args[0]
|
|
for _, cmd := range commands {
|
|
if cmd.Name == arg {
|
|
cmd.usage()
|
|
return // succeeded at helping
|
|
}
|
|
}
|
|
|
|
fmt.Fprintf(os.Stderr, "Unknown help topic %#q. Run '%s help'.\n", arg, gomobileName)
|
|
os.Exit(2)
|
|
}
|
|
|
|
const documentationHeader = `// 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.
|
|
|
|
// Code generated by 'gomobile help documentation doc.go'. DO NOT EDIT.
|
|
`
|
|
|
|
func helpDocumentation(path string) {
|
|
w := new(bytes.Buffer)
|
|
w.WriteString(documentationHeader)
|
|
w.WriteString("\n/*\n")
|
|
if err := usageTmpl.Execute(w, commands); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
for _, cmd := range commands {
|
|
r, rlen := utf8.DecodeRuneInString(cmd.Short)
|
|
w.WriteString("\n\n")
|
|
w.WriteRune(unicode.ToUpper(r))
|
|
w.WriteString(cmd.Short[rlen:])
|
|
w.WriteString("\n\nUsage:\n\n\tgomobile " + cmd.Name)
|
|
if cmd.Usage != "" {
|
|
w.WriteRune(' ')
|
|
w.WriteString(cmd.Usage)
|
|
}
|
|
w.WriteRune('\n')
|
|
w.WriteString(cmd.Long)
|
|
}
|
|
|
|
w.WriteString("*/\npackage main // import \"golang.org/x/mobile/cmd/gomobile\"\n")
|
|
|
|
if err := ioutil.WriteFile(path, w.Bytes(), 0666); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
var commands = []*command{
|
|
// TODO(crawshaw): cmdRun
|
|
cmdBind,
|
|
cmdBuild,
|
|
cmdClean,
|
|
cmdInit,
|
|
cmdInstall,
|
|
cmdVersion,
|
|
}
|
|
|
|
type command struct {
|
|
run func(*command) error
|
|
flag flag.FlagSet
|
|
Name string
|
|
Usage string
|
|
Short string
|
|
Long string
|
|
}
|
|
|
|
func (cmd *command) usage() {
|
|
fmt.Fprintf(os.Stdout, "usage: %s %s %s\n%s", gomobileName, cmd.Name, cmd.Usage, cmd.Long)
|
|
}
|
|
|
|
var usageTmpl = template.Must(template.New("usage").Parse(
|
|
`Gomobile is a tool for building and running mobile apps written in Go.
|
|
|
|
To install:
|
|
|
|
$ go install golang.org/x/mobile/cmd/gomobile@latest
|
|
$ gomobile init
|
|
|
|
At least Go 1.16 is required.
|
|
For detailed instructions, see https://golang.org/wiki/Mobile.
|
|
|
|
Usage:
|
|
|
|
gomobile command [arguments]
|
|
|
|
Commands:
|
|
{{range .}}
|
|
{{.Name | printf "%-11s"}} {{.Short}}{{end}}
|
|
|
|
Use 'gomobile help [command]' for more information about that command.
|
|
`))
|