diff --git a/cmd/gomobile/build.go b/cmd/gomobile/build.go index 8c53b38..495edc2 100644 --- a/cmd/gomobile/build.go +++ b/cmd/gomobile/build.go @@ -9,7 +9,6 @@ import ( "crypto/x509" "encoding/pem" "errors" - "flag" "fmt" "go/build" "io" @@ -42,14 +41,12 @@ are copied into the APK file. These build flags are shared by the build, install, and test commands. For documentation, see 'go help build': -TODO: -a -tags 'tag list' `, } // TODO: -n -// TODO: -v // TODO: -x // TODO: -mobile @@ -58,12 +55,13 @@ func runBuild(cmd *command) error { if err != nil { panic(err) } + args := cmd.flag.Args() - switch len(flag.Args()) { - case 1: + switch len(args) { + case 0: pkg, err = ctx.ImportDir(cwd, build.ImportComment) - case 2: - pkg, err = ctx.Import(flag.Args()[1], cwd, build.ImportComment) + case 1: + pkg, err = ctx.Import(args[0], cwd, build.ImportComment) default: cmd.usage() os.Exit(1) @@ -133,6 +131,9 @@ func runBuild(cmd *command) error { `-i`, // TODO(crawshaw): control with a flag `-ldflags="-shared"`, `-o`, libPath) + if buildV { + gocmd.Args = append(gocmd.Args, "-v") + } gocmd.Stdout = os.Stdout gocmd.Stderr = os.Stderr gocmd.Env = []string{ @@ -228,6 +229,29 @@ func runBuild(cmd *command) error { return apkw.Close() } +// "Build flags", used by multiple commands. +var ( + buildA bool // -a + buildV bool // -v +) + +func addBuildFlags(cmd *command) { + cmd.flag.BoolVar(&buildA, "a", false, "") + cmd.flag.Var((*stringsFlag)(&ctx.BuildTags), "tags", "") +} + +func addBuildFlagsNXV(cmd *command) { + // TODO: -n, -x + cmd.flag.BoolVar(&buildV, "v", false, "") +} + +func init() { + addBuildFlags(cmdBuild) + // TODO: addBuildFlags(cmdInstall) + addBuildFlagsNXV(cmdBuild) + addBuildFlagsNXV(cmdInit) +} + // A random uninteresting private key. // Must be consistent across builds so newer app versions can be installed. const debugCert = ` diff --git a/cmd/gomobile/init.go b/cmd/gomobile/init.go index 42a1593..8c359a9 100644 --- a/cmd/gomobile/init.go +++ b/cmd/gomobile/init.go @@ -79,9 +79,14 @@ func runInit(cmd *command) error { return err } + url := "http://dl.google.com/android/ndk/" + ndkName + + if buildV { + fmt.Fprintf(os.Stderr, "fetching %s\n", url) + } + // TODO(crawshaw): The arm compiler toolchain compresses to 33 MB, less than a tenth of the NDK. Provide an alternative binary download. - // TODO(crawshaw): extra logging with -v - resp, err := http.Get("http://dl.google.com/android/ndk/" + ndkName) + resp, err := http.Get(url) if err != nil { return err } @@ -102,7 +107,9 @@ func runInit(cmd *command) error { inflate.Dir = tmpdir out, err := inflate.CombinedOutput() if err != nil { - os.Stderr.Write(out) // TODO(crawshaw): only in verbose mode? + if buildV { + os.Stderr.Write(out) + } return err } srcSysroot := filepath.Join(tmpdir, "android-ndk-r10d", "platforms", "android-15", "arch-arm", "usr") @@ -145,8 +152,11 @@ func runInit(cmd *command) error { if v := goEnv("GOROOT_BOOTSTRAP"); v != "" { make.Env = append(make.Env, `GOROOT_BOOTSTRAP=`+v) } - make.Stdout = os.Stdout - make.Stderr = os.Stderr + if buildV { + fmt.Fprintf(os.Stderr, "building android/arm cross compiler\n") + make.Stdout = os.Stdout + make.Stderr = os.Stderr + } if err := make.Run(); err != nil { return err } diff --git a/cmd/gomobile/main.go b/cmd/gomobile/main.go index 495135e..1867c26 100644 --- a/cmd/gomobile/main.go +++ b/cmd/gomobile/main.go @@ -50,6 +50,8 @@ func main() { for _, cmd := range commands { if cmd.Name == args[0] { + cmd.flag.Usage = cmd.usage + cmd.flag.Parse(args[1:]) if err := cmd.run(cmd); err != nil { msg := err.Error() if msg != "" { @@ -95,6 +97,7 @@ var commands = []*command{ type command struct { run func(*command) error + flag flag.FlagSet Name string Usage string Short string diff --git a/cmd/gomobile/strings_flag.go b/cmd/gomobile/strings_flag.go new file mode 100644 index 0000000..330833e --- /dev/null +++ b/cmd/gomobile/strings_flag.go @@ -0,0 +1,62 @@ +// 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 "fmt" + +type stringsFlag []string + +func (v *stringsFlag) Set(s string) error { + var err error + *v, err = splitQuotedFields(s) + if *v == nil { + *v = []string{} + } + return err +} + +func isSpaceByte(c byte) bool { + return c == ' ' || c == '\t' || c == '\n' || c == '\r' +} + +func splitQuotedFields(s string) ([]string, error) { + // Split fields allowing '' or "" around elements. + // Quotes further inside the string do not count. + var f []string + for len(s) > 0 { + for len(s) > 0 && isSpaceByte(s[0]) { + s = s[1:] + } + if len(s) == 0 { + break + } + // Accepted quoted string. No unescaping inside. + if s[0] == '"' || s[0] == '\'' { + quote := s[0] + s = s[1:] + i := 0 + for i < len(s) && s[i] != quote { + i++ + } + if i >= len(s) { + return nil, fmt.Errorf("unterminated %c string", quote) + } + f = append(f, s[:i]) + s = s[i+1:] + continue + } + i := 0 + for i < len(s) && !isSpaceByte(s[i]) { + i++ + } + f = append(f, s[:i]) + s = s[i:] + } + return f, nil +} + +func (v *stringsFlag) String() string { + return "" +}