github.com/cyrilou242/gomobile-java@v0.0.0-20220215185836-09daef25a210/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 // Requires ANDROID_HOME be set to the path of the Android SDK, and 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 34 var outfile = flag.String("o", "", "result will be written file") 35 36 var tmpdir string 37 38 func main() { 39 flag.Parse() 40 41 var err error 42 tmpdir, err = ioutil.TempDir("", "gendex-") 43 if err != nil { 44 log.Fatal(err) 45 } 46 47 err = gendex() 48 os.RemoveAll(tmpdir) 49 if err != nil { 50 log.Fatal(err) 51 } 52 } 53 54 func gendex() error { 55 androidHome := os.Getenv("ANDROID_HOME") 56 if androidHome == "" { 57 return errors.New("ANDROID_HOME not set") 58 } 59 if err := os.MkdirAll(tmpdir+"/work/org/golang/app", 0775); err != nil { 60 return err 61 } 62 javaFiles, err := filepath.Glob("../../app/*.java") 63 if err != nil { 64 return err 65 } 66 if len(javaFiles) == 0 { 67 return errors.New("could not find ../../app/*.java files") 68 } 69 platform, err := findLast(androidHome + "/platforms") 70 if err != nil { 71 return err 72 } 73 cmd := exec.Command( 74 "javac", 75 "-source", "1.7", 76 "-target", "1.7", 77 "-bootclasspath", platform+"/android.jar", 78 "-d", tmpdir+"/work", 79 ) 80 cmd.Args = append(cmd.Args, javaFiles...) 81 if out, err := cmd.CombinedOutput(); err != nil { 82 fmt.Println(cmd.Args) 83 os.Stderr.Write(out) 84 return err 85 } 86 buildTools, err := findLast(androidHome + "/build-tools") 87 if err != nil { 88 return err 89 } 90 cmd = exec.Command( 91 buildTools+"/dx", 92 "--dex", 93 "--output="+tmpdir+"/classes.dex", 94 tmpdir+"/work", 95 ) 96 if out, err := cmd.CombinedOutput(); err != nil { 97 os.Stderr.Write(out) 98 return err 99 } 100 src, err := ioutil.ReadFile(tmpdir + "/classes.dex") 101 if err != nil { 102 return err 103 } 104 data := base64.StdEncoding.EncodeToString(src) 105 106 buf := new(bytes.Buffer) 107 fmt.Fprint(buf, header) 108 109 var piece string 110 for len(data) > 0 { 111 l := 70 112 if l > len(data) { 113 l = len(data) 114 } 115 piece, data = data[:l], data[l:] 116 fmt.Fprintf(buf, "\t`%s` + \n", piece) 117 } 118 fmt.Fprintf(buf, "\t``") 119 out, err := format.Source(buf.Bytes()) 120 if err != nil { 121 buf.WriteTo(os.Stderr) 122 return err 123 } 124 125 w, err := os.Create(*outfile) 126 if err != nil { 127 return err 128 } 129 if _, err := w.Write(out); err != nil { 130 return err 131 } 132 if err := w.Close(); err != nil { 133 return err 134 } 135 return nil 136 } 137 138 func findLast(path string) (string, error) { 139 dir, err := os.Open(path) 140 if err != nil { 141 return "", err 142 } 143 children, err := dir.Readdirnames(-1) 144 if err != nil { 145 return "", err 146 } 147 return path + "/" + children[len(children)-1], nil 148 } 149 150 var header = `// Copyright 2015 The Go Authors. All rights reserved. 151 // Use of this source code is governed by a BSD-style 152 // license that can be found in the LICENSE file. 153 154 // Code generated by gendex.go. DO NOT EDIT. 155 156 package main 157 158 var dexStr = `