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