gendex.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build ignore
  5. // +build ignore
  6. // Gendex generates a dex file used by Go apps created with gomobile.
  7. //
  8. // The dex is a thin extension of NativeActivity, providing access to
  9. // a few platform features (not the SDK UI) not easily accessible from
  10. // NDK headers. Long term these could be made part of the standard NDK,
  11. // however that would limit gomobile to working with newer versions of
  12. // the Android OS, so we do this while we wait.
  13. //
  14. // Respects ANDROID_HOME to set the path of the Android SDK.
  15. // javac must be on the PATH.
  16. package main
  17. import (
  18. "bytes"
  19. "encoding/base64"
  20. "errors"
  21. "flag"
  22. "fmt"
  23. "go/format"
  24. "io/ioutil"
  25. "log"
  26. "os"
  27. "os/exec"
  28. "path/filepath"
  29. "golang.org/x/mobile/internal/sdkpath"
  30. )
  31. var outfile = flag.String("o", "", "result will be written file")
  32. var tmpdir string
  33. func main() {
  34. flag.Parse()
  35. var err error
  36. tmpdir, err = ioutil.TempDir("", "gendex-")
  37. if err != nil {
  38. log.Fatal(err)
  39. }
  40. err = gendex()
  41. os.RemoveAll(tmpdir)
  42. if err != nil {
  43. log.Fatal(err)
  44. }
  45. }
  46. func gendex() error {
  47. androidHome, err := sdkpath.AndroidHome()
  48. if err != nil {
  49. return fmt.Errorf("couldn't find Android SDK: %w", err)
  50. }
  51. if err := os.MkdirAll(tmpdir+"/work/org/golang/app", 0775); err != nil {
  52. return err
  53. }
  54. javaFiles, err := filepath.Glob("../../app/*.java")
  55. if err != nil {
  56. return err
  57. }
  58. if len(javaFiles) == 0 {
  59. return errors.New("could not find ../../app/*.java files")
  60. }
  61. platform, err := findLast(androidHome + "/platforms")
  62. if err != nil {
  63. return err
  64. }
  65. cmd := exec.Command(
  66. "javac",
  67. "-source", "1.7",
  68. "-target", "1.7",
  69. "-bootclasspath", platform+"/android.jar",
  70. "-d", tmpdir+"/work",
  71. )
  72. cmd.Args = append(cmd.Args, javaFiles...)
  73. if out, err := cmd.CombinedOutput(); err != nil {
  74. fmt.Println(cmd.Args)
  75. os.Stderr.Write(out)
  76. return err
  77. }
  78. buildTools, err := findLast(androidHome + "/build-tools")
  79. if err != nil {
  80. return err
  81. }
  82. cmd = exec.Command(
  83. buildTools+"/dx",
  84. "--dex",
  85. "--output="+tmpdir+"/classes.dex",
  86. tmpdir+"/work",
  87. )
  88. if out, err := cmd.CombinedOutput(); err != nil {
  89. os.Stderr.Write(out)
  90. return err
  91. }
  92. src, err := ioutil.ReadFile(tmpdir + "/classes.dex")
  93. if err != nil {
  94. return err
  95. }
  96. data := base64.StdEncoding.EncodeToString(src)
  97. buf := new(bytes.Buffer)
  98. fmt.Fprint(buf, header)
  99. var piece string
  100. for len(data) > 0 {
  101. l := 70
  102. if l > len(data) {
  103. l = len(data)
  104. }
  105. piece, data = data[:l], data[l:]
  106. fmt.Fprintf(buf, "\t`%s` + \n", piece)
  107. }
  108. fmt.Fprintf(buf, "\t``")
  109. out, err := format.Source(buf.Bytes())
  110. if err != nil {
  111. buf.WriteTo(os.Stderr)
  112. return err
  113. }
  114. w, err := os.Create(*outfile)
  115. if err != nil {
  116. return err
  117. }
  118. if _, err := w.Write(out); err != nil {
  119. return err
  120. }
  121. if err := w.Close(); err != nil {
  122. return err
  123. }
  124. return nil
  125. }
  126. func findLast(path string) (string, error) {
  127. dir, err := os.Open(path)
  128. if err != nil {
  129. return "", err
  130. }
  131. children, err := dir.Readdirnames(-1)
  132. if err != nil {
  133. return "", err
  134. }
  135. return path + "/" + children[len(children)-1], nil
  136. }
  137. var header = `// Copyright 2015 The Go Authors. All rights reserved.
  138. // Use of this source code is governed by a BSD-style
  139. // license that can be found in the LICENSE file.
  140. // Code generated by gendex.go. DO NOT EDIT.
  141. package main
  142. var dexStr = `