2
0
mirror of synced 2025-02-24 07:18:15 +00:00

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>
This commit is contained in:
Hajime Hoshi 2019-11-12 21:44:24 +09:00
parent 6a1b097663
commit f0c40035f2
4 changed files with 47 additions and 39 deletions

View File

@ -7,16 +7,18 @@ package main
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 @@ func runBind(cmd *command) error {
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 @@ func runBind(cmd *command) error {
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 @@ func runBind(cmd *command) error {
// 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 runBind(cmd *command) error {
}
}
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 @@ func writeFile(filename string, generate func(io.Writer) error) error {
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
}

View File

@ -7,7 +7,6 @@ package main
import (
"archive/zip"
"fmt"
"go/build"
"io"
"io/ioutil"
"os"
@ -15,9 +14,11 @@ import (
"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 @@ func goAndroidBind(gobind string, pkgs []*build.Package, androidArchs []string)
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 @@ func buildSrcJar(src string) error {
// 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 @@ func buildAAR(srcDir, androidDir string, pkgs []*build.Package, androidArchs []s
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 @@ func buildAAR(srcDir, androidDir string, pkgs []*build.Package, androidArchs []s
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

View File

@ -6,15 +6,16 @@ package main
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 @@ func goIOSBind(gobind string, pkgs []*build.Package, archs []string) error {
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 @@ func goIOSBindArchive(name string, env []string) (string, error) {
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__

View File

@ -20,13 +20,13 @@ func TestImportPackagesPathCleaning(t *testing.T) {
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 @@ func TestBindIOS(t *testing.T) {
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)
}