gendex.go 3.3 KB

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