Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: third_party/go/src/golang.org/x/mobile/cmd/gomobile/bind.go

Issue 1275153002: Remove third_party/golang.org/x/mobile as it is no longer used with Go 1.5. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Remove golang.org/x/mobile Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 package main
6
7 import (
8 "errors"
9 "fmt"
10 "go/ast"
11 "go/build"
12 "go/parser"
13 "go/scanner"
14 "go/token"
15 "io"
16 "io/ioutil"
17 "os"
18 "path/filepath"
19 "text/template"
20 "unicode"
21 "unicode/utf8"
22
23 "golang.org/x/mobile/bind"
24 "golang.org/x/tools/go/loader"
25 "golang.org/x/tools/go/types"
26 )
27
28 // ctx, pkg, ndkccpath, tmpdir in build.go
29
30 var cmdBind = &command{
31 run: runBind,
32 Name: "bind",
33 Usage: "[package]",
34 Short: "build a shared library for android APK and/or iOS app",
35 Long: `
36 Bind generates language bindings like gobind (golang.org/x/mobile/cmd/gobind)
37 for a package and builds a shared library for each platform from the go binding
38 code.
39
40 The -outdir flag specifies the output directory and is required.
41
42 For Android, the bind command will place the generated Java API stubs and the
43 compiled shared libraries in the android subdirectory of the following layout.
44
45 <outdir>/android
46 libs/
47 armeabi-v7a/libgojni.so
48 ...
49 src/main/java/go/
50 Seq.java
51 Go.java
52 mypackage/Mypackage.java
53
54 The -v flag provides verbose output, including the list of packages built.
55
56 These build flags are shared by the build command.
57 For documentation, see 'go help build':
58 -a
59 -i
60 -n
61 -x
62 -tags 'tag list'
63 `,
64 }
65
66 // TODO: -mobile
67
68 var bindOutdir *string // -outdir
69 func init() {
70 bindOutdir = cmdBind.flag.String("outdir", "", "output directory. Defaul t is the current directory.")
71 }
72
73 func runBind(cmd *command) error {
74 cwd, err := os.Getwd()
75 if err != nil {
76 panic(err)
77 }
78 args := cmd.flag.Args()
79
80 var bindPkg *build.Package
81 switch len(args) {
82 case 0:
83 bindPkg, err = ctx.ImportDir(cwd, build.ImportComment)
84 case 1:
85 bindPkg, err = ctx.Import(args[0], cwd, build.ImportComment)
86 default:
87 cmd.usage()
88 os.Exit(1)
89 }
90 if err != nil {
91 return err
92 }
93
94 if *bindOutdir == "" {
95 return fmt.Errorf("-outdir is required")
96 }
97
98 if !buildN {
99 sentinel := filepath.Join(*bindOutdir, "gomobile-bind-sentinel")
100 if err := ioutil.WriteFile(sentinel, []byte("write test"), 0644) ; err != nil {
101 return fmt.Errorf("output directory %q not writable", *b indOutdir)
102 }
103 os.Remove(sentinel)
104 }
105
106 if buildN {
107 tmpdir = "$WORK"
108 } else {
109 tmpdir, err = ioutil.TempDir("", "gomobile-bind-work-")
110 if err != nil {
111 return err
112 }
113 }
114 defer removeAll(tmpdir)
115 if buildX {
116 fmt.Fprintln(os.Stderr, "WORK="+tmpdir)
117 }
118
119 binder, err := newBinder(bindPkg)
120 if err != nil {
121 return err
122 }
123
124 if err := binder.GenGo(tmpdir); err != nil {
125 return err
126 }
127
128 pathJoin := func(a, b string) string {
129 return filepath.Join(a, filepath.FromSlash(b))
130 }
131
132 mainFile := pathJoin(tmpdir, "androidlib/main.go")
133 err = writeFile(mainFile, func(w io.Writer) error {
134 return androidMainTmpl.Execute(w, "../go_"+binder.pkg.Name())
135 })
136 if err != nil {
137 return fmt.Errorf("failed to create the main package for android : %v", err)
138 }
139
140 androidOutdir := pathJoin(*bindOutdir, "android")
141
142 err = gobuild(mainFile, pathJoin(androidOutdir, "libs/armeabi-v7a/libgoj ni.so"))
143 if err != nil {
144 return err
145 }
146 p, err := ctx.Import("golang.org/x/mobile/app", cwd, build.ImportComment )
147 if err != nil {
148 return fmt.Errorf(`"golang.org/x/mobile/app" is not found; run g o get golang.org/x/mobile/app`)
149 }
150 repo := filepath.Clean(filepath.Join(p.Dir, "..")) // golang.org/x/mobil e directory.
151
152 // TODO(crawshaw): use a better package path derived from the go package .
153 if err := binder.GenJava(pathJoin(androidOutdir, "src/main/java/go/"+bin der.pkg.Name())); err != nil {
154 return err
155 }
156
157 src := pathJoin(repo, "app/Go.java")
158 dst := pathJoin(androidOutdir, "src/main/java/go/Go.java")
159 rm(dst)
160 if err := symlink(src, dst); err != nil {
161 return err
162 }
163
164 src = pathJoin(repo, "bind/java/Seq.java")
165 dst = pathJoin(androidOutdir, "src/main/java/go/Seq.java")
166 rm(dst)
167 if err := symlink(src, dst); err != nil {
168 return err
169 }
170
171 return nil
172 }
173
174 type binder struct {
175 files []*ast.File
176 fset *token.FileSet
177 pkg *types.Package
178 }
179
180 func (b *binder) GenJava(outdir string) error {
181 firstRune, size := utf8.DecodeRuneInString(b.pkg.Name())
182 className := string(unicode.ToUpper(firstRune)) + b.pkg.Name()[size:]
183 javaFile := filepath.Join(outdir, className+".java")
184
185 if buildX {
186 printcmd("gobind -lang=java %s > %s", b.pkg.Path(), javaFile)
187 }
188
189 generate := func(w io.Writer) error {
190 return bind.GenJava(w, b.fset, b.pkg)
191 }
192 if err := writeFile(javaFile, generate); err != nil {
193 return err
194 }
195 return nil
196 }
197
198 func (b *binder) GenGo(outdir string) error {
199 pkgName := "go_" + b.pkg.Name()
200 goFile := filepath.Join(outdir, pkgName, pkgName+".go")
201
202 if buildX {
203 printcmd("gobind -lang=go %s > %s", b.pkg.Path(), goFile)
204 }
205
206 generate := func(w io.Writer) error {
207 return bind.GenGo(w, b.fset, b.pkg)
208 }
209 if err := writeFile(goFile, generate); err != nil {
210 return err
211 }
212 return nil
213 }
214
215 func writeFile(filename string, generate func(io.Writer) error) error {
216 if buildV {
217 fmt.Fprintf(os.Stderr, "write %s\n", filename)
218 }
219
220 err := mkdir(filepath.Dir(filename))
221 if err != nil {
222 return err
223 }
224
225 if buildN {
226 return generate(ioutil.Discard)
227 }
228
229 f, err := os.Create(filename)
230 if err != nil {
231 return err
232 }
233 defer func() {
234 if cerr := f.Close(); err == nil {
235 err = cerr
236 }
237 }()
238
239 return generate(f)
240 }
241
242 func newBinder(bindPkg *build.Package) (*binder, error) {
243 if bindPkg.Name == "main" {
244 return nil, fmt.Errorf("package %q: can only bind a library pack age", bindPkg.Name)
245 }
246
247 if len(bindPkg.CgoFiles) > 0 {
248 return nil, fmt.Errorf("cannot use cgo-dependent package as serv ice definition: %s", bindPkg.CgoFiles[0])
249 }
250
251 fset := token.NewFileSet()
252
253 hasErr := false
254 var files []*ast.File
255 for _, filename := range bindPkg.GoFiles {
256 p := filepath.Join(bindPkg.Dir, filename)
257 file, err := parser.ParseFile(fset, p, nil, parser.AllErrors)
258 if err != nil {
259 hasErr = true
260 if list, _ := err.(scanner.ErrorList); len(list) > 0 {
261 for _, err := range list {
262 fmt.Fprintln(os.Stderr, err)
263 }
264 } else {
265 fmt.Fprintln(os.Stderr, err)
266 }
267 }
268 files = append(files, file)
269 }
270
271 if hasErr {
272 return nil, errors.New("package parsing failed.")
273 }
274
275 conf := loader.Config{
276 Fset: fset,
277 }
278 conf.TypeChecker.Error = func(err error) {
279 fmt.Fprintln(os.Stderr, err)
280 }
281
282 conf.CreateFromFiles(bindPkg.ImportPath, files...)
283 program, err := conf.Load()
284 if err != nil {
285 return nil, err
286 }
287 b := &binder{
288 files: files,
289 fset: fset,
290 pkg: program.Created[0].Pkg,
291 }
292 return b, nil
293 }
294
295 var androidMainTmpl = template.Must(template.New("android.go").Parse(`
296 package main
297
298 import (
299 "golang.org/x/mobile/app"
300 "golang.org/x/mobile/bind/java"
301
302 _ "{{.}}"
303 )
304
305 func main() {
306 app.Run(app.Callbacks{Start: java.Init})
307 }
308 `))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698