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