cmd/gomobile: replace go/build with go/packages in gomobile-build
This is a preparation to use Go modules at gomobile command.
Updates golang/go#27234
Change-Id: I8ee47cb53f5b748592a0c8c9f383abab27a7fdad
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/208059
Run-TryBot: Hajime Hoshi <hajimehoshi@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Daniel Martà <mvdan@mvdan.cc>
diff --git a/cmd/gomobile/bind.go b/cmd/gomobile/bind.go
index 54eb6f1..2910d8d 100644
--- a/cmd/gomobile/bind.go
+++ b/cmd/gomobile/bind.go
@@ -116,7 +116,7 @@
var pkgs []*packages.Package
switch len(args) {
case 0:
- pkgs, err = packages.Load(packagesConfig(targetOS), cwd)
+ pkgs, err = packages.Load(packagesConfig(targetOS), ".")
default:
pkgs, err = importPackages(args, targetOS)
}
diff --git a/cmd/gomobile/build.go b/cmd/gomobile/build.go
index 449dc9f..59aa286 100644
--- a/cmd/gomobile/build.go
+++ b/cmd/gomobile/build.go
@@ -13,8 +13,11 @@
"io"
"os"
"os/exec"
+ "path"
"regexp"
"strings"
+
+ "golang.org/x/tools/go/packages"
)
var ctx = build.Default
@@ -72,7 +75,7 @@
// runBuildImpl builds a package for mobiles based on the given commands.
// runBuildImpl returns a built package information and an error if exists.
-func runBuildImpl(cmd *command) (*build.Package, error) {
+func runBuildImpl(cmd *command) (*packages.Package, error) {
cleanup, err := buildEnvInit()
if err != nil {
return nil, err
@@ -86,30 +89,37 @@
return nil, fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
}
+ // TODO(hajimehoshi): ctx is now used only for recording build tags in build. Remove this.
oldCtx := ctx
defer func() {
ctx = oldCtx
}()
- ctx.GOARCH = targetArchs[0]
- ctx.GOOS = targetOS
- if ctx.GOOS == "darwin" {
+ if targetOS == "darwin" {
ctx.BuildTags = append(ctx.BuildTags, "ios")
}
- var pkg *build.Package
+ var buildPath string
switch len(args) {
case 0:
- pkg, err = ctx.ImportDir(cwd, build.ImportComment)
+ buildPath = "."
case 1:
- pkg, err = ctx.Import(args[0], cwd, build.ImportComment)
+ buildPath = path.Clean(args[0])
default:
cmd.usage()
os.Exit(1)
}
+ pkgs, err := packages.Load(packagesConfig(targetOS), buildPath)
if err != nil {
return nil, err
}
+ // len(pkgs) can be more than 1 e.g., when the specified path includes `...`.
+ if len(pkgs) != 1 {
+ cmd.usage()
+ os.Exit(1)
+ }
+
+ pkg := pkgs[0]
if pkg.Name != "main" && buildO != "" {
return nil, fmt.Errorf("cannot set -o when building non-main package")
@@ -121,7 +131,7 @@
if pkg.Name != "main" {
for _, arch := range targetArchs {
env := androidEnv[arch]
- if err := goBuild(pkg.ImportPath, env); err != nil {
+ if err := goBuild(pkg.PkgPath, env); err != nil {
return nil, err
}
}
@@ -138,7 +148,7 @@
if pkg.Name != "main" {
for _, arch := range targetArchs {
env := darwinEnv[arch]
- if err := goBuild(pkg.ImportPath, env); err != nil {
+ if err := goBuild(pkg.PkgPath, env); err != nil {
return nil, err
}
}
@@ -154,7 +164,7 @@
}
if !nmpkgs["golang.org/x/mobile/app"] {
- return nil, fmt.Errorf(`%s does not import "golang.org/x/mobile/app"`, pkg.ImportPath)
+ return nil, fmt.Errorf(`%s does not import "golang.org/x/mobile/app"`, pkg.PkgPath)
}
return pkg, nil
diff --git a/cmd/gomobile/build_androidapp.go b/cmd/gomobile/build_androidapp.go
index 7b5e06f..1df9891 100644
--- a/cmd/gomobile/build_androidapp.go
+++ b/cmd/gomobile/build_androidapp.go
@@ -12,7 +12,6 @@
"encoding/xml"
"errors"
"fmt"
- "go/build"
"io"
"io/ioutil"
"log"
@@ -22,16 +21,22 @@
"strings"
"golang.org/x/mobile/internal/binres"
+ "golang.org/x/tools/go/packages"
)
-func goAndroidBuild(pkg *build.Package, androidArchs []string) (map[string]bool, error) {
+func goAndroidBuild(pkg *packages.Package, androidArchs []string) (map[string]bool, error) {
ndkRoot, err := ndkRoot()
if err != nil {
return nil, err
}
- appName := path.Base(pkg.ImportPath)
+ appName := path.Base(pkg.PkgPath)
libName := androidPkgName(appName)
- manifestPath := filepath.Join(pkg.Dir, "AndroidManifest.xml")
+
+ // 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.
+ dir := filepath.Dir(pkg.GoFiles[0])
+
+ manifestPath := filepath.Join(dir, "AndroidManifest.xml")
manifestData, err := ioutil.ReadFile(manifestPath)
if err != nil {
if !os.IsNotExist(err) {
@@ -72,7 +77,7 @@
return nil, err
}
err = goBuild(
- pkg.ImportPath,
+ pkg.PkgPath,
env,
"-buildmode=c-shared",
"-o", libAbsPath,
@@ -97,7 +102,7 @@
}
if buildO == "" {
- buildO = androidPkgName(filepath.Base(pkg.Dir)) + ".apk"
+ buildO = androidPkgName(path.Base(pkg.PkgPath)) + ".apk"
}
if !strings.HasSuffix(buildO, ".apk") {
return nil, fmt.Errorf("output file name %q does not end in '.apk'", buildO)
@@ -183,7 +188,7 @@
var arsc struct {
iconPath string
}
- assetsDir := filepath.Join(pkg.Dir, "assets")
+ assetsDir := filepath.Join(dir, "assets")
assetsDirExists := true
fi, err := os.Stat(assetsDir)
if err != nil {
diff --git a/cmd/gomobile/build_iosapp.go b/cmd/gomobile/build_iosapp.go
index 9cc22ab..a0103de 100644
--- a/cmd/gomobile/build_iosapp.go
+++ b/cmd/gomobile/build_iosapp.go
@@ -9,7 +9,6 @@
"crypto/x509"
"encoding/pem"
"fmt"
- "go/build"
"io/ioutil"
"os"
"os/exec"
@@ -17,15 +16,17 @@
"path/filepath"
"strings"
"text/template"
+
+ "golang.org/x/tools/go/packages"
)
-func goIOSBuild(pkg *build.Package, bundleID string, archs []string) (map[string]bool, error) {
- src := pkg.ImportPath
+func goIOSBuild(pkg *packages.Package, bundleID string, archs []string) (map[string]bool, error) {
+ src := pkg.PkgPath
if buildO != "" && !strings.HasSuffix(buildO, ".app") {
return nil, fmt.Errorf("-o must have an .app for -target=ios")
}
- productName := rfc1034Label(path.Base(pkg.ImportPath))
+ productName := rfc1034Label(path.Base(pkg.PkgPath))
if productName == "" {
productName = "ProductName" // like xcode.
}
@@ -34,7 +35,7 @@
if err := infoplistTmpl.Execute(infoplist, infoplistTmplData{
// TODO: better bundle id.
BundleID: bundleID + "." + productName,
- Name: strings.Title(path.Base(pkg.ImportPath)),
+ Name: strings.Title(path.Base(pkg.PkgPath)),
}); err != nil {
return nil, err
}
@@ -116,7 +117,7 @@
// TODO(jbd): Fallback to copying if renaming fails.
if buildO == "" {
- n := pkg.ImportPath
+ n := pkg.PkgPath
if n == "." {
// use cwd name
cwd, err := os.Getwd()
@@ -176,13 +177,15 @@
return cert.Subject.OrganizationalUnit[0], nil
}
-func iosCopyAssets(pkg *build.Package, xcodeProjDir string) error {
+func iosCopyAssets(pkg *packages.Package, xcodeProjDir string) error {
dstAssets := xcodeProjDir + "/main/assets"
if err := mkdir(dstAssets); err != nil {
return err
}
- srcAssets := 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.
+ srcAssets := filepath.Join(filepath.Dir(pkg.GoFiles[0]), "assets")
fi, err := os.Stat(srcAssets)
if err != nil {
if os.IsNotExist(err) {
diff --git a/cmd/gomobile/env.go b/cmd/gomobile/env.go
index cb42d1c..d36a418 100644
--- a/cmd/gomobile/env.go
+++ b/cmd/gomobile/env.go
@@ -13,7 +13,6 @@
// General mobile build environment. Initialized by envInit.
var (
- cwd string
gomobilepath string // $GOPATH/pkg/gomobile
androidEnv map[string][]string // android arch -> []string
@@ -74,12 +73,6 @@
}
func envInit() (err error) {
- // TODO(crawshaw): cwd only used by ctx.Import, which can take "."
- cwd, err = os.Getwd()
- if err != nil {
- return err
- }
-
// Setup the cross-compiler environments.
if ndkRoot, err := ndkRoot(); err == nil {
androidEnv = make(map[string][]string)
diff --git a/cmd/gomobile/install.go b/cmd/gomobile/install.go
index 05ff14b..beb7e52 100644
--- a/cmd/gomobile/install.go
+++ b/cmd/gomobile/install.go
@@ -8,7 +8,7 @@
"fmt"
"os"
"os/exec"
- "path/filepath"
+ "path"
"strings"
)
@@ -43,7 +43,7 @@
`adb`,
`install`,
`-r`,
- androidPkgName(filepath.Base(pkg.Dir))+`.apk`,
+ androidPkgName(path.Base(pkg.PkgPath))+`.apk`,
)
c.Stdout = os.Stdout
c.Stderr = os.Stderr