in cmd/gobind/main.go [47:161]
func run() {
var langs []string
if *lang != "" {
langs = strings.Split(*lang, ",")
} else {
langs = []string{"go", "java", "objc"}
}
// We need to give appropriate environment variables like CC or CXX so that the returned packages no longer have errors.
// However, getting such environment variables is difficult or impossible so far.
// Gomobile can obtain such environment variables in env.go, but this logic assumes some condiitons gobind doesn't assume.
cfg := &packages.Config{
Mode: packages.NeedName | packages.NeedFiles |
packages.NeedImports | packages.NeedDeps |
packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo,
BuildFlags: []string{"-tags", strings.Join(strings.Split(*tags, ","), " ")},
}
// Call Load twice to warm the cache. There is a known issue that the result of Load
// depends on build cache state. See golang/go#33687.
packages.Load(cfg, flag.Args()...)
allPkg, err := packages.Load(cfg, flag.Args()...)
if err != nil {
log.Fatal(err)
}
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)
}
}
if len(classes) > 0 || len(otypes) > 0 {
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 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)
}
}
// Add a new directory to GOPATH where the file for reverse bindings exist, and recreate allPkg.
// It is because the current allPkg did not solve imports for reverse bindings.
var gopath string
if out, err := exec.Command("go", "env", "GOPATH").Output(); err != nil {
log.Fatal(err)
} else {
gopath = string(bytes.TrimSpace(out))
}
if gopath != "" {
gopath = string(filepath.ListSeparator) + gopath
}
gopath = srcDir + gopath
cfg.Env = append(os.Environ(), "GOPATH="+gopath)
allPkg, err = packages.Load(cfg, flag.Args()...)
if err != nil {
log.Fatal(err)
}
}
typePkgs := make([]*types.Package, len(allPkg))
astPkgs := make([][]*ast.File, len(allPkg))
for i, pkg := range allPkg {
// Ignore pkg.Errors. pkg.Errors can exist when Cgo is used, but this should not affect the result.
// See the discussion at golang/go#36547.
typePkgs[i] = pkg.Types
astPkgs[i] = pkg.Syntax
}
for _, l := range langs {
for i, pkg := range typePkgs {
genPkg(l, pkg, astPkgs[i], typePkgs, classes, otypes)
}
// Generate the error package and support files
genPkg(l, nil, nil, typePkgs, classes, otypes)
}
}