Change-Id: Iea30db321c53b37b41a2b18689c5f724938a1593 Reviewed-on: https://go-review.googlesource.com/108135 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
164 lines
4.0 KiB
Go
164 lines
4.0 KiB
Go
// Copyright 2014 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"go/build"
|
|
"go/importer"
|
|
"go/types"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"golang.org/x/mobile/internal/importers"
|
|
"golang.org/x/mobile/internal/importers/java"
|
|
"golang.org/x/mobile/internal/importers/objc"
|
|
)
|
|
|
|
var (
|
|
lang = flag.String("lang", "", "target languages for bindings, either java, go, or objc. If empty, all languages are generated.")
|
|
outdir = flag.String("outdir", "", "result will be written to the directory instead of stdout.")
|
|
javaPkg = flag.String("javapkg", "", "custom Java package path prefix. Valid only with -lang=java.")
|
|
prefix = flag.String("prefix", "", "custom Objective-C name prefix. Valid only with -lang=objc.")
|
|
bootclasspath = flag.String("bootclasspath", "", "Java bootstrap classpath.")
|
|
classpath = flag.String("classpath", "", "Java classpath.")
|
|
tags = flag.String("tags", "", "build tags.")
|
|
)
|
|
|
|
var usage = `The Gobind tool generates Java language bindings for Go.
|
|
|
|
For usage details, see doc.go.`
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
run()
|
|
os.Exit(exitStatus)
|
|
}
|
|
|
|
func run() {
|
|
var langs []string
|
|
if *lang != "" {
|
|
langs = strings.Split(*lang, ",")
|
|
} else {
|
|
langs = []string{"go", "java", "objc"}
|
|
}
|
|
ctx := build.Default
|
|
if *tags != "" {
|
|
ctx.BuildTags = append(ctx.BuildTags, strings.Split(*tags, ",")...)
|
|
}
|
|
var allPkg []*build.Package
|
|
for _, path := range flag.Args() {
|
|
pkg, err := ctx.Import(path, ".", build.ImportComment)
|
|
if err != nil {
|
|
log.Fatalf("package %q: %v", path, err)
|
|
}
|
|
allPkg = append(allPkg, pkg)
|
|
}
|
|
jrefs, err := importers.AnalyzePackages(allPkg, "Java/")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
orefs, err := importers.AnalyzePackages(allPkg, "ObjC/")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
var classes []*java.Class
|
|
if len(jrefs.Refs) > 0 {
|
|
jimp := &java.Importer{
|
|
Bootclasspath: *bootclasspath,
|
|
Classpath: *classpath,
|
|
JavaPkg: *javaPkg,
|
|
}
|
|
classes, err = jimp.Import(jrefs)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
var otypes []*objc.Named
|
|
if len(orefs.Refs) > 0 {
|
|
otypes, err = objc.Import(orefs)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
// Determine GOPATH from go env GOPATH in case the default $HOME/go GOPATH
|
|
// is in effect.
|
|
if out, err := exec.Command("go", "env", "GOPATH").Output(); err != nil {
|
|
log.Fatal(err)
|
|
} else {
|
|
ctx.GOPATH = string(bytes.TrimSpace(out))
|
|
}
|
|
if len(classes) > 0 || len(otypes) > 0 {
|
|
// After generation, reverse bindings needs to be in the GOPATH
|
|
// for user packages to build.
|
|
srcDir := *outdir
|
|
if srcDir == "" {
|
|
srcDir, err = ioutil.TempDir(os.TempDir(), "gobind-")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer os.RemoveAll(srcDir)
|
|
} else {
|
|
srcDir, err = filepath.Abs(srcDir)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
if ctx.GOPATH != "" {
|
|
ctx.GOPATH = string(filepath.ListSeparator) + ctx.GOPATH
|
|
}
|
|
ctx.GOPATH = srcDir + ctx.GOPATH
|
|
if len(classes) > 0 {
|
|
if err := genJavaPackages(srcDir, classes, jrefs.Embedders); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
if len(otypes) > 0 {
|
|
if err := genObjcPackages(srcDir, otypes, orefs.Embedders); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
typePkgs := make([]*types.Package, len(allPkg))
|
|
// The "source" go/importer package implicitly uses build.Default.
|
|
oldCtx := build.Default
|
|
build.Default = ctx
|
|
defer func() {
|
|
build.Default = oldCtx
|
|
}()
|
|
imp := importer.For("source", nil)
|
|
for i, pkg := range allPkg {
|
|
var err error
|
|
typePkgs[i], err = imp.Import(pkg.ImportPath)
|
|
if err != nil {
|
|
errorf("%v\n", err)
|
|
return
|
|
}
|
|
}
|
|
for _, l := range langs {
|
|
for _, pkg := range typePkgs {
|
|
genPkg(l, pkg, typePkgs, classes, otypes)
|
|
}
|
|
// Generate the error package and support files
|
|
genPkg(l, nil, typePkgs, classes, otypes)
|
|
}
|
|
}
|
|
|
|
var exitStatus = 0
|
|
|
|
func errorf(format string, args ...interface{}) {
|
|
fmt.Fprintf(os.Stderr, format, args...)
|
|
fmt.Fprintln(os.Stderr)
|
|
exitStatus = 1
|
|
}
|