cmd/gomobile: replace go/build with go/packages in bind
This is a preparation to use Go modules at gomobile-bind.
Updates golang/go#27234
Change-Id: I33684888b4181cc1ebd4d3c8872a6b2e62950855
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/206777
Run-TryBot: Hajime Hoshi <hajimehoshi@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go
index ed1874a..54eb6f1 100644
--- a/cmd/gomobile/bind.go
+++ b/cmd/gomobile/bind.go
@@ -7,16 +7,18 @@
import (
"errors"
"fmt"
- "go/build"
"io"
"io/ioutil"
"os"
"os/exec"
"path"
"path/filepath"
+ "strings"
+
+ "golang.org/x/tools/go/packages"
)
-// ctx, pkg, tmpdir in build.go
+// ctx in build.go
var cmdBind = &command{
run: runBind,
@@ -79,27 +81,25 @@
return fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
}
+ // TODO(hajimehoshi): ctx is now used only for recording build tags in bind. Remove this.
oldCtx := ctx
defer func() {
ctx = oldCtx
}()
- ctx.GOARCH = "arm"
- ctx.GOOS = targetOS
- if bindJavaPkg != "" && ctx.GOOS != "android" {
+ if bindJavaPkg != "" && targetOS != "android" {
return fmt.Errorf("-javapkg is supported only for android target")
}
- if bindPrefix != "" && ctx.GOOS != "darwin" {
+ if bindPrefix != "" && targetOS != "darwin" {
return fmt.Errorf("-prefix is supported only for ios target")
}
- if ctx.GOOS == "android" {
+ if targetOS == "android" {
if _, err := ndkRoot(); err != nil {
return err
}
}
-
- if ctx.GOOS == "darwin" {
+ if targetOS == "darwin" {
ctx.BuildTags = append(ctx.BuildTags, "ios")
}
@@ -113,13 +113,12 @@
gobind = "gobind"
}
- var pkgs []*build.Package
+ var pkgs []*packages.Package
switch len(args) {
case 0:
- pkgs = make([]*build.Package, 1)
- pkgs[0], err = ctx.ImportDir(cwd, build.ImportComment)
+ pkgs, err = packages.Load(packagesConfig(targetOS), cwd)
default:
- pkgs, err = importPackages(args)
+ pkgs, err = importPackages(args, targetOS)
}
if err != nil {
return err
@@ -128,7 +127,7 @@
// check if any of the package is main
for _, pkg := range pkgs {
if pkg.Name == "main" {
- return fmt.Errorf("binding 'main' package (%s) is not supported", pkg.ImportComment)
+ return fmt.Errorf("binding 'main' package (%s) is not supported", pkg.PkgPath)
}
}
@@ -145,16 +144,13 @@
}
}
-func importPackages(args []string) ([]*build.Package, error) {
- pkgs := make([]*build.Package, len(args))
- for i, a := range args {
- a = path.Clean(a)
- var err error
- if pkgs[i], err = ctx.Import(a, cwd, build.ImportComment); err != nil {
- return nil, fmt.Errorf("package %q: %v", a, err)
- }
+func importPackages(args []string, targetOS string) ([]*packages.Package, error) {
+ config := packagesConfig(targetOS)
+ var cleaned []string
+ for _, a := range args {
+ cleaned = append(cleaned, path.Clean(a))
}
- return pkgs, nil
+ return packages.Load(config, cleaned...)
}
var (
@@ -232,3 +228,12 @@
return generate(f)
}
+
+func packagesConfig(targetOS string) *packages.Config {
+ config := &packages.Config{}
+ config.Env = append(os.Environ(), "GOARCH=arm", "GOOS="+targetOS)
+ if len(ctx.BuildTags) > 0 {
+ config.BuildFlags = []string{"-tags=" + strings.Join(ctx.BuildTags, ",")}
+ }
+ return config
+}
diff --git a/cmd/gomobile/bind_androidapp.go b/cmd/gomobile/bind_androidapp.go
index 719e376..8bba0da 100644
--- a/cmd/gomobile/bind_androidapp.go
+++ b/cmd/gomobile/bind_androidapp.go
@@ -7,7 +7,6 @@
import (
"archive/zip"
"fmt"
- "go/build"
"io"
"io/ioutil"
"os"
@@ -15,9 +14,11 @@
"path/filepath"
"strconv"
"strings"
+
+ "golang.org/x/tools/go/packages"
)
-func goAndroidBind(gobind string, pkgs []*build.Package, androidArchs []string) error {
+func goAndroidBind(gobind string, pkgs []*packages.Package, androidArchs []string) error {
if sdkDir := os.Getenv("ANDROID_HOME"); sdkDir == "" {
return fmt.Errorf("this command requires ANDROID_HOME environment variable (path to the Android SDK)")
}
@@ -43,7 +44,7 @@
cmd.Args = append(cmd.Args, "-bootclasspath="+bindBootClasspath)
}
for _, p := range pkgs {
- cmd.Args = append(cmd.Args, p.ImportPath)
+ cmd.Args = append(cmd.Args, p.PkgPath)
}
if err := runCmd(cmd); err != nil {
return err
@@ -114,7 +115,7 @@
// aidl (optional, not relevant)
//
// javac and jar commands are needed to build classes.jar.
-func buildAAR(srcDir, androidDir string, pkgs []*build.Package, androidArchs []string) (err error) {
+func buildAAR(srcDir, androidDir string, pkgs []*packages.Package, androidArchs []string) (err error) {
var out io.Writer = ioutil.Discard
if buildO == "" {
buildO = pkgs[0].Name + ".aar"
@@ -173,7 +174,9 @@
files := map[string]string{}
for _, pkg := range pkgs {
- assetsDir := filepath.Join(pkg.Dir, "assets")
+ // TODO(hajimehoshi): This works only with Go tools that assume all source files are in one directory.
+ // Fix this to work with other Go tools.
+ assetsDir := filepath.Join(filepath.Dir(pkg.GoFiles[0]), "assets")
assetsDirExists := false
if fi, err := os.Stat(assetsDir); err == nil {
assetsDirExists = fi.IsDir()
@@ -198,9 +201,9 @@
name := "assets/" + path[len(assetsDir)+1:]
if orig, exists := files[name]; exists {
return fmt.Errorf("package %s asset name conflict: %s already added from package %s",
- pkg.ImportPath, name, orig)
+ pkg.PkgPath, name, orig)
}
- files[name] = pkg.ImportPath
+ files[name] = pkg.PkgPath
w, err := aarwcreate(name)
if err != nil {
return nil
diff --git a/cmd/gomobile/bind_iosapp.go b/cmd/gomobile/bind_iosapp.go
index 2c129b0..69a1636 100644
--- a/cmd/gomobile/bind_iosapp.go
+++ b/cmd/gomobile/bind_iosapp.go
@@ -6,15 +6,16 @@
import (
"fmt"
- "go/build"
"io"
"os/exec"
"path/filepath"
"strings"
"text/template"
+
+ "golang.org/x/tools/go/packages"
)
-func goIOSBind(gobind string, pkgs []*build.Package, archs []string) error {
+func goIOSBind(gobind string, pkgs []*packages.Package, archs []string) error {
// Run gobind to generate the bindings
cmd := exec.Command(
gobind,
@@ -30,7 +31,7 @@
cmd.Args = append(cmd.Args, "-prefix="+bindPrefix)
}
for _, p := range pkgs {
- cmd.Args = append(cmd.Args, p.ImportPath)
+ cmd.Args = append(cmd.Args, p.PkgPath)
}
if err := runCmd(cmd); err != nil {
return err
@@ -188,7 +189,7 @@
var iosBindHeaderTmpl = template.Must(template.New("ios.h").Parse(`
// Objective-C API for talking to the following Go packages
//
-{{range .pkgs}}// {{.ImportPath}}
+{{range .pkgs}}// {{.PkgPath}}
{{end}}//
// File is generated by gomobile bind. Do not edit.
#ifndef __{{.title}}_FRAMEWORK_H__
diff --git a/cmd/gomobile/bind_test.go b/cmd/gomobile/bind_test.go
index 72ab352..bb3e20c 100644
--- a/cmd/gomobile/bind_test.go
+++ b/cmd/gomobile/bind_test.go
@@ -20,13 +20,13 @@
t.Skip("not available on Android")
}
slashPath := "golang.org/x/mobile/example/bind/hello/"
- pkgs, err := importPackages([]string{slashPath})
+ pkgs, err := importPackages([]string{slashPath}, runtime.GOOS)
if err != nil {
t.Fatal(err)
}
p := pkgs[0]
- if c := path.Clean(slashPath); p.ImportPath != c {
- t.Errorf("expected %s; got %s", c, p.ImportPath)
+ if c := path.Clean(slashPath); p.PkgPath != c {
+ t.Errorf("expected %s; got %s", c, p.PkgPath)
}
}
@@ -145,8 +145,7 @@
os.Setenv("HOMEDRIVE", "C:")
}
cmdBind.flag.Parse([]string{"golang.org/x/mobile/asset"})
- err := runBind(cmdBind)
- if err != nil {
+ if err := runBind(cmdBind); err != nil {
t.Log(buf.String())
t.Fatal(err)
}