| Index: third_party/go/src/golang.org/x/mobile/cmd/gomobile/init.go
|
| diff --git a/third_party/go/src/golang.org/x/mobile/cmd/gomobile/init.go b/third_party/go/src/golang.org/x/mobile/cmd/gomobile/init.go
|
| deleted file mode 100644
|
| index b634cc575c37bb3df2a74ea139377b23911c07eb..0000000000000000000000000000000000000000
|
| --- a/third_party/go/src/golang.org/x/mobile/cmd/gomobile/init.go
|
| +++ /dev/null
|
| @@ -1,550 +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
|
| -
|
| -// TODO(crawshaw): build darwin/arm cross compiler on darwin/{386,amd64}
|
| -// TODO(crawshaw): android/{386,arm64}
|
| -
|
| -import (
|
| - "archive/tar"
|
| - "bytes"
|
| - "compress/gzip"
|
| - "fmt"
|
| - "io"
|
| - "io/ioutil"
|
| - "net/http"
|
| - "os"
|
| - "os/exec"
|
| - "path/filepath"
|
| - "runtime"
|
| - "strings"
|
| -)
|
| -
|
| -// useStrippedNDK determines whether the init subcommand fetches the GCC
|
| -// toolchain from the original Android NDK, or from the stripped-down NDK
|
| -// hosted specifically for the gomobile tool.
|
| -//
|
| -// There is a significant size different (400MB compared to 30MB).
|
| -var useStrippedNDK = goos == "linux" || goos == "darwin"
|
| -
|
| -const ndkVersion = "ndk-r10d"
|
| -
|
| -var (
|
| - goos = runtime.GOOS
|
| - goarch = runtime.GOARCH
|
| - ndkarch string
|
| -)
|
| -
|
| -func init() {
|
| - if runtime.GOARCH == "amd64" {
|
| - ndkarch = "x86_64"
|
| - } else {
|
| - ndkarch = runtime.GOARCH
|
| - }
|
| -}
|
| -
|
| -var cmdInit = &command{
|
| - run: runInit,
|
| - Name: "init",
|
| - Short: "install android compiler toolchain",
|
| - Long: `
|
| -Init downloads and installs the Android C++ compiler toolchain.
|
| -
|
| -The toolchain is installed in $GOPATH/pkg/gomobile.
|
| -If the Android C++ compiler toolchain already exists in the path,
|
| -it skips download and uses the existing toolchain.
|
| -
|
| -The -u option forces download and installation of the new toolchain
|
| -even when the toolchain exists.
|
| -`,
|
| -}
|
| -
|
| -var initU bool // -u
|
| -
|
| -func init() {
|
| - cmdInit.flag.BoolVar(&initU, "u", false, "force toolchain download")
|
| -}
|
| -
|
| -func runInit(cmd *command) error {
|
| - version, err := goVersion()
|
| - if err != nil {
|
| - return err
|
| - }
|
| -
|
| - gopaths := filepath.SplitList(goEnv("GOPATH"))
|
| - if len(gopaths) == 0 {
|
| - return fmt.Errorf("GOPATH is not set")
|
| - }
|
| - ndkccpath = filepath.Join(gopaths[0], "pkg", "gomobile", "android-"+ndkVersion)
|
| - ndkccdl := filepath.Join(ndkccpath, "downloaded")
|
| - verpath := filepath.Join(gopaths[0], "pkg", "gomobile", "version")
|
| - if buildX {
|
| - fmt.Fprintln(xout, "NDKCCPATH="+ndkccpath)
|
| - }
|
| -
|
| - needNDK := initU
|
| - if !needNDK {
|
| - if _, err := os.Stat(ndkccdl); err != nil {
|
| - needNDK = true
|
| - }
|
| - }
|
| -
|
| - if needNDK {
|
| - if err := removeAll(ndkccpath); err != nil && !os.IsExist(err) {
|
| - return err
|
| - }
|
| - if err := mkdir(ndkccpath); err != nil {
|
| - return err
|
| - }
|
| - }
|
| -
|
| - if buildN {
|
| - tmpdir = filepath.Join(ndkccpath, "work")
|
| - } else {
|
| - var err error
|
| - tmpdir, err = ioutil.TempDir(ndkccpath, "gomobile-init-")
|
| - if err != nil {
|
| - return err
|
| - }
|
| - }
|
| - if buildX {
|
| - fmt.Fprintln(xout, "WORK="+tmpdir)
|
| - }
|
| - defer removeAll(tmpdir)
|
| -
|
| - goroot := goEnv("GOROOT")
|
| - tmpGoroot := filepath.Join(tmpdir, "go")
|
| - if err := copyGoroot(tmpGoroot, goroot); err != nil {
|
| - return err
|
| - }
|
| -
|
| - if needNDK {
|
| - if err := fetchNDK(); err != nil {
|
| - return err
|
| - }
|
| -
|
| - if !buildN {
|
| - if err := ioutil.WriteFile(ndkccdl, []byte("done"), 0644); err != nil {
|
| - return err
|
| - }
|
| - }
|
| - }
|
| -
|
| - dst := filepath.Join(ndkccpath, "arm")
|
| -
|
| - // TODO(crawshaw): make.bat on windows
|
| - ndkccbin := filepath.Join(dst, "bin")
|
| - envpath := os.Getenv("PATH")
|
| - if buildN {
|
| - envpath = "$PATH"
|
| - }
|
| - make := exec.Command(filepath.Join(tmpGoroot, "src", "make.bash"), "--no-clean")
|
| - make.Dir = filepath.Join(tmpGoroot, "src")
|
| - make.Env = []string{
|
| - `PATH=` + envpath,
|
| - `TMPDIR=` + tmpdir,
|
| - `HOME=` + os.Getenv("HOME"), // for default the go1.4 bootstrap
|
| - `GOOS=android`,
|
| - `GOARCH=arm`,
|
| - `GOARM=7`,
|
| - `CGO_ENABLED=1`,
|
| - `CC_FOR_TARGET=` + filepath.Join(ndkccbin, "arm-linux-androideabi-gcc"),
|
| - `CXX_FOR_TARGET=` + filepath.Join(ndkccbin, "arm-linux-androideabi-g++"),
|
| - }
|
| - if v := goEnv("GOROOT_BOOTSTRAP"); v != "" {
|
| - make.Env = append(make.Env, `GOROOT_BOOTSTRAP=`+v)
|
| - }
|
| - if buildV {
|
| - fmt.Fprintf(os.Stderr, "building android/arm cross compiler\n")
|
| - make.Stdout = os.Stdout
|
| - make.Stderr = os.Stderr
|
| - }
|
| - if buildX {
|
| - printcmd("%s", strings.Join(make.Env, " ")+" "+strings.Join(make.Args, " "))
|
| - }
|
| - if !buildN {
|
| - if err := make.Run(); err != nil {
|
| - return err
|
| - }
|
| - }
|
| -
|
| - // Move the Go cross compiler toolchain into GOPATH.
|
| - gotoolsrc := filepath.Join(tmpGoroot, "pkg", "tool", goos+"_"+goarch)
|
| - if err := move(ndkccbin, gotoolsrc, "5a", "5l", "5g", "cgo", "nm", "pack", "link"); err != nil {
|
| - return err
|
| - }
|
| -
|
| - // Build toolexec command.
|
| - toolexecSrc := filepath.Join(tmpdir, "toolexec.go")
|
| - if !buildN {
|
| - if err := ioutil.WriteFile(toolexecSrc, []byte(toolexec), 0644); err != nil {
|
| - return err
|
| - }
|
| - }
|
| - make = exec.Command("go", "build", "-o", filepath.Join(ndkccbin, "toolexec"), toolexecSrc)
|
| - if buildV {
|
| - fmt.Fprintf(os.Stderr, "building gomobile toolexec\n")
|
| - make.Stdout = os.Stdout
|
| - make.Stderr = os.Stderr
|
| - }
|
| - if buildX {
|
| - printcmd("%s", strings.Join(make.Args, " "))
|
| - }
|
| - if !buildN {
|
| - if err := make.Run(); err != nil {
|
| - return err
|
| - }
|
| - }
|
| -
|
| - // Move pre-compiled stdlib for android into GOROOT. This is
|
| - // the only time we modify the user's GOROOT.
|
| - cannotRemove := false
|
| - if err := removeAll(filepath.Join(goroot, "pkg", "android_arm")); err != nil {
|
| - cannotRemove = true
|
| - }
|
| - if err := move(filepath.Join(goroot, "pkg"), filepath.Join(tmpGoroot, "pkg"), "android_arm"); err != nil {
|
| - // Move android_arm into a temp directory that outlives
|
| - // this process and give the user installation instructions.
|
| - dir, err := ioutil.TempDir("", "gomobile-")
|
| - if err != nil {
|
| - return err
|
| - }
|
| - if err := move(dir, filepath.Join(tmpGoroot, "pkg"), "android_arm"); err != nil {
|
| - return err
|
| - }
|
| - // TODO: modify instructions for windows.
|
| - remove := ""
|
| - if cannotRemove {
|
| - remove = "\trm -r -f %s/pkg/android_arm\n"
|
| - }
|
| - return fmt.Errorf(
|
| - `Cannot install android/arm in GOROOT.
|
| -Make GOROOT writable (possibly by becoming the super user, using sudo) and run:
|
| -%s mv %s %s`,
|
| - remove,
|
| - filepath.Join(dir, "android_arm"),
|
| - filepath.Join(goroot, "pkg"),
|
| - )
|
| - }
|
| -
|
| - if buildX {
|
| - printcmd("go version > %s", verpath)
|
| - }
|
| - if !buildN {
|
| - if err := ioutil.WriteFile(verpath, version, 0644); err != nil {
|
| - return err
|
| - }
|
| - }
|
| -
|
| - return nil
|
| -}
|
| -
|
| -// toolexec is the source of a small program designed to be passed to
|
| -// the -toolexec flag of go build.
|
| -const toolexec = `package main
|
| -
|
| -import (
|
| - "fmt"
|
| - "os"
|
| - "os/exec"
|
| - "path/filepath"
|
| -)
|
| -
|
| -func main() {
|
| - args := append([]string{}, os.Args[1:]...)
|
| - args[0] = filepath.Join(os.Getenv("GOMOBILEPATH"), filepath.Base(args[0]))
|
| - cmd := exec.Command(args[0], args[1:]...)
|
| - cmd.Stdout = os.Stdout
|
| - cmd.Stderr = os.Stderr
|
| - if err := cmd.Run(); err != nil {
|
| - fmt.Fprintf(os.Stderr, "%v\n", err)
|
| - os.Exit(1)
|
| - }
|
| -}
|
| -`
|
| -
|
| -func move(dst, src string, names ...string) error {
|
| - for _, name := range names {
|
| - srcf := filepath.Join(src, name)
|
| - dstf := filepath.Join(dst, name)
|
| - if buildX {
|
| - printcmd("mv %s %s", srcf, dstf)
|
| - }
|
| - if buildN {
|
| - continue
|
| - }
|
| - if err := os.Rename(srcf, dstf); err != nil {
|
| - return err
|
| - }
|
| - }
|
| - return nil
|
| -}
|
| -
|
| -func mkdir(dir string) error {
|
| - if buildX {
|
| - printcmd("mkdir -p %s", dir)
|
| - }
|
| - if buildN {
|
| - return nil
|
| - }
|
| - return os.MkdirAll(dir, 0755)
|
| -}
|
| -
|
| -func symlink(src, dst string) error {
|
| - if buildX {
|
| - printcmd("ln -s %s %s", src, dst)
|
| - }
|
| - if buildN {
|
| - return nil
|
| - }
|
| - return os.Symlink(src, dst)
|
| -}
|
| -
|
| -func rm(name string) error {
|
| - if buildX {
|
| - printcmd("rm %s", name)
|
| - }
|
| - if buildN {
|
| - return nil
|
| - }
|
| - return os.Remove(name)
|
| -}
|
| -
|
| -func goVersion() ([]byte, error) {
|
| - if err := exec.Command("which", "go").Run(); err != nil {
|
| - return nil, fmt.Errorf(`no Go tool on $PATH`)
|
| - }
|
| - buildHelp, err := exec.Command("go", "help", "build").Output()
|
| - if err != nil {
|
| - return nil, fmt.Errorf("bad Go tool: %v", err)
|
| - }
|
| - if !bytes.Contains(buildHelp, []byte("-toolexec")) {
|
| - return nil, fmt.Errorf("installed Go tool does not support -toolexec")
|
| - }
|
| - return exec.Command("go", "version").Output()
|
| -}
|
| -
|
| -func fetchNDK() error {
|
| - if useStrippedNDK {
|
| - if err := fetchStrippedNDK(); err != nil {
|
| - return err
|
| - }
|
| - } else {
|
| - ndkName := "android-" + ndkVersion + "-" + goos + "-" + ndkarch + "."
|
| - if goos == "windows" {
|
| - ndkName += "exe"
|
| - } else {
|
| - ndkName += "bin"
|
| - }
|
| - url := "https://dl.google.com/android/ndk/" + ndkName
|
| - if err := fetch(filepath.Join(tmpdir, ndkName), url); err != nil {
|
| - return err
|
| - }
|
| -
|
| - inflate := exec.Command(filepath.Join(tmpdir, ndkName))
|
| - inflate.Dir = tmpdir
|
| - if buildX {
|
| - printcmd("%s", inflate.Args[0])
|
| - }
|
| - if !buildN {
|
| - out, err := inflate.CombinedOutput()
|
| - if err != nil {
|
| - if buildV {
|
| - os.Stderr.Write(out)
|
| - }
|
| - return err
|
| - }
|
| - }
|
| - }
|
| -
|
| - dst := filepath.Join(ndkccpath, "arm")
|
| - dstSysroot := filepath.Join(dst, "sysroot", "usr")
|
| - if err := mkdir(dstSysroot); err != nil {
|
| - return err
|
| - }
|
| -
|
| - srcSysroot := filepath.Join(tmpdir, "android-ndk-r10d", "platforms", "android-15", "arch-arm", "usr")
|
| - if err := move(dstSysroot, srcSysroot, "include", "lib"); err != nil {
|
| - return err
|
| - }
|
| -
|
| - ndkpath := filepath.Join(tmpdir, "android-ndk-r10d", "toolchains", "arm-linux-androideabi-4.8", "prebuilt", goos+"-"+ndkarch)
|
| - if err := move(dst, ndkpath, "bin", "lib", "libexec"); err != nil {
|
| - return err
|
| - }
|
| -
|
| - linkpath := filepath.Join(dst, "arm-linux-androideabi", "bin")
|
| - if err := mkdir(linkpath); err != nil {
|
| - return err
|
| - }
|
| - for _, name := range []string{"ld", "as", "gcc", "g++"} {
|
| - if err := symlink(filepath.Join(dst, "bin", "arm-linux-androideabi-"+name), filepath.Join(linkpath, name)); err != nil {
|
| - return err
|
| - }
|
| - }
|
| - return nil
|
| -}
|
| -
|
| -func fetchStrippedNDK() error {
|
| - name := "gomobile-ndk-r10d-" + goos + "-" + ndkarch + ".tar.gz"
|
| - url := "https://dl.google.com/go/mobile/" + name
|
| - if err := fetch(filepath.Join(tmpdir, name), url); err != nil {
|
| - return err
|
| - }
|
| - if buildX {
|
| - printcmd("tar xfz %s", name)
|
| - }
|
| - if buildN {
|
| - return nil
|
| - }
|
| -
|
| - tf, err := os.Open(filepath.Join(tmpdir, name))
|
| - if err != nil {
|
| - return err
|
| - }
|
| - defer tf.Close()
|
| - zr, err := gzip.NewReader(tf)
|
| - if err != nil {
|
| - return err
|
| - }
|
| - tr := tar.NewReader(zr)
|
| - for {
|
| - hdr, err := tr.Next()
|
| - if err == io.EOF {
|
| - break
|
| - }
|
| - if err != nil {
|
| - return err
|
| - }
|
| - dst := filepath.Join(tmpdir, hdr.Name)
|
| - if hdr.Typeflag == tar.TypeSymlink {
|
| - if err := symlink(hdr.Linkname, dst); err != nil {
|
| - return err
|
| - }
|
| - continue
|
| - }
|
| - if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
|
| - return err
|
| - }
|
| - f, err := os.OpenFile(dst, os.O_CREATE|os.O_EXCL|os.O_WRONLY, os.FileMode(hdr.Mode)&0777)
|
| - if err != nil {
|
| - return err
|
| - }
|
| - if _, err := io.Copy(f, tr); err != nil {
|
| - return err
|
| - }
|
| - if err := f.Close(); err != nil {
|
| - return err
|
| - }
|
| - }
|
| - return nil
|
| -}
|
| -
|
| -func fetch(dst, url string) error {
|
| - if buildV {
|
| - fmt.Fprintf(os.Stderr, "fetching %s\n", url)
|
| - }
|
| - if buildX {
|
| - printcmd("curl -o%s %s", dst, url)
|
| - }
|
| - if buildN {
|
| - return nil
|
| - }
|
| -
|
| - f, err := os.OpenFile(dst, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0755)
|
| - if err != nil {
|
| - return err
|
| - }
|
| -
|
| - resp, err := http.Get(url)
|
| - if err != nil {
|
| - return err
|
| - }
|
| - _, err = io.Copy(f, resp.Body)
|
| - err2 := resp.Body.Close()
|
| - err3 := f.Close()
|
| - if err != nil {
|
| - return err
|
| - }
|
| - if err2 != nil {
|
| - return err2
|
| - }
|
| - return err3
|
| -}
|
| -
|
| -// copyGoroot copies GOROOT from src to dst.
|
| -//
|
| -// It skips the pkg directory, which is not necessary for make.bash,
|
| -// and symlinks .git to avoid a 70MB copy.
|
| -func copyGoroot(dst, src string) error {
|
| - if err := mkdir(filepath.Join(dst, "pkg")); err != nil {
|
| - return err
|
| - }
|
| - for _, dir := range []string{"include", "lib", "src"} {
|
| - if err := copyAll(filepath.Join(dst, dir), filepath.Join(src, dir)); err != nil {
|
| - return err
|
| - }
|
| - }
|
| - return symlink(filepath.Join(src, ".git"), filepath.Join(dst, ".git"))
|
| -}
|
| -
|
| -func copyAll(dst, src string) error {
|
| - if buildX {
|
| - printcmd("cp -a %s %s", src, dst)
|
| - }
|
| - if buildN {
|
| - return nil
|
| - }
|
| - return filepath.Walk(src, func(path string, info os.FileInfo, errin error) (err error) {
|
| - if errin != nil {
|
| - return errin
|
| - }
|
| - prefixLen := len(src)
|
| - if len(path) > prefixLen {
|
| - prefixLen++ // file separator
|
| - }
|
| - outpath := filepath.Join(dst, path[prefixLen:])
|
| - if info.IsDir() {
|
| - return os.Mkdir(outpath, 0755)
|
| - }
|
| - in, err := os.Open(path)
|
| - if err != nil {
|
| - return err
|
| - }
|
| - defer in.Close()
|
| - out, err := os.OpenFile(outpath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, info.Mode())
|
| - if err != nil {
|
| - return err
|
| - }
|
| - defer func() {
|
| - if errc := out.Close(); err == nil {
|
| - err = errc
|
| - }
|
| - }()
|
| - _, err = io.Copy(out, in)
|
| - return err
|
| - })
|
| -}
|
| -
|
| -func removeAll(path string) error {
|
| - if buildX {
|
| - printcmd("rm -r -f %q", path)
|
| - }
|
| - if buildN {
|
| - return nil
|
| - }
|
| - return os.RemoveAll(path)
|
| -}
|
| -
|
| -func goEnv(name string) string {
|
| - if val := os.Getenv(name); val != "" {
|
| - return val
|
| - }
|
| - val, err := exec.Command("go", "env", name).Output()
|
| - if err != nil {
|
| - panic(err) // the Go tool was tested to work earlier
|
| - }
|
| - return strings.TrimSpace(string(val))
|
| -}
|
|
|