mirror of
https://github.com/golang/go
synced 2024-09-29 22:24:33 -06:00
cmd/go: support shared libraries in 'go version' on Windows
This change modifies 'go version' to support shared windows libraries. Updates #48187 Change-Id: I2e8436b8df84fe76677106fa9ca02dcd1fb90e77 Reviewed-on: https://go-review.googlesource.com/c/go/+/391855 Reviewed-by: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Quim Muntal <quimmuntal@gmail.com> Run-TryBot: Bryan Mills <bcmills@google.com> Reviewed-by: Joedian Reid <joedian@golang.org> Auto-Submit: Bryan Mills <bcmills@google.com>
This commit is contained in:
parent
388fbf287c
commit
742e0a9720
@ -1774,10 +1774,9 @@
|
||||
//
|
||||
// go version [-m] [-v] [file ...]
|
||||
//
|
||||
// Version prints the build information for Go executables.
|
||||
// Version prints the build information for Go binary files.
|
||||
//
|
||||
// Go version reports the Go version used to build each of the named
|
||||
// executable files.
|
||||
// Go version reports the Go version used to build each of the named files.
|
||||
//
|
||||
// If no files are named on the command line, go version prints its own
|
||||
// version information.
|
||||
@ -1787,7 +1786,7 @@
|
||||
// By default, go version does not report unrecognized files found
|
||||
// during a directory scan. The -v flag causes it to report unrecognized files.
|
||||
//
|
||||
// The -m flag causes go version to print each executable's embedded
|
||||
// The -m flag causes go version to print each file's embedded
|
||||
// module version information, when available. In the output, the module
|
||||
// information consists of multiple lines following the version line, each
|
||||
// indented by a leading tab character.
|
||||
|
@ -22,10 +22,9 @@ import (
|
||||
var CmdVersion = &base.Command{
|
||||
UsageLine: "go version [-m] [-v] [file ...]",
|
||||
Short: "print Go version",
|
||||
Long: `Version prints the build information for Go executables.
|
||||
Long: `Version prints the build information for Go binary files.
|
||||
|
||||
Go version reports the Go version used to build each of the named
|
||||
executable files.
|
||||
Go version reports the Go version used to build each of the named files.
|
||||
|
||||
If no files are named on the command line, go version prints its own
|
||||
version information.
|
||||
@ -35,7 +34,7 @@ looking for recognized Go binaries and reporting their versions.
|
||||
By default, go version does not report unrecognized files found
|
||||
during a directory scan. The -v flag causes it to report unrecognized files.
|
||||
|
||||
The -m flag causes go version to print each executable's embedded
|
||||
The -m flag causes go version to print each file's embedded
|
||||
module version information, when available. In the output, the module
|
||||
information consists of multiple lines following the version line, each
|
||||
indented by a leading tab character.
|
||||
@ -92,7 +91,7 @@ func runVersion(ctx context.Context, cmd *base.Command, args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
// scanDir scans a directory for executables to run scanFile on.
|
||||
// scanDir scans a directory for binary to run scanFile on.
|
||||
func scanDir(dir string) {
|
||||
filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
|
||||
if d.Type().IsRegular() || d.Type()&fs.ModeSymlink != 0 {
|
||||
@ -109,18 +108,24 @@ func scanDir(dir string) {
|
||||
})
|
||||
}
|
||||
|
||||
// isExe reports whether the file should be considered executable.
|
||||
func isExe(file string, info fs.FileInfo) bool {
|
||||
if runtime.GOOS == "windows" {
|
||||
return strings.HasSuffix(strings.ToLower(file), ".exe")
|
||||
// isGoBinaryCandidate reports whether the file is a candidate to be a Go binary.
|
||||
func isGoBinaryCandidate(file string, info fs.FileInfo) bool {
|
||||
if info.Mode().IsRegular() && info.Mode()&0111 != 0 {
|
||||
return true
|
||||
}
|
||||
name := strings.ToLower(file)
|
||||
switch filepath.Ext(name) {
|
||||
case ".so", ".exe", ".dll":
|
||||
return true
|
||||
default:
|
||||
return strings.Contains(name, ".so.")
|
||||
}
|
||||
return info.Mode().IsRegular() && info.Mode()&0111 != 0
|
||||
}
|
||||
|
||||
// scanFile scans file to try to report the Go and module versions.
|
||||
// If mustPrint is true, scanFile will report any error reading file.
|
||||
// Otherwise (mustPrint is false, because scanFile is being called
|
||||
// by scanDir) scanFile prints nothing for non-Go executables.
|
||||
// by scanDir) scanFile prints nothing for non-Go binaries.
|
||||
func scanFile(file string, info fs.FileInfo, mustPrint bool) {
|
||||
if info.Mode()&fs.ModeSymlink != 0 {
|
||||
// Accept file symlinks only.
|
||||
@ -134,20 +139,20 @@ func scanFile(file string, info fs.FileInfo, mustPrint bool) {
|
||||
info = i
|
||||
}
|
||||
|
||||
if !isExe(file, info) {
|
||||
if mustPrint {
|
||||
fmt.Fprintf(os.Stderr, "%s: not executable file\n", file)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
bi, err := buildinfo.ReadFile(file)
|
||||
if err != nil {
|
||||
if mustPrint {
|
||||
if pathErr := (*os.PathError)(nil); errors.As(err, &pathErr) && filepath.Clean(pathErr.Path) == filepath.Clean(file) {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", file)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "%s: %v\n", file, err)
|
||||
|
||||
// Skip errors for non-Go binaries.
|
||||
// buildinfo.ReadFile errors are not fine-grained enough
|
||||
// to know if the file is a Go binary or not,
|
||||
// so try to infer it from the file mode and extension.
|
||||
if isGoBinaryCandidate(file, info) {
|
||||
fmt.Fprintf(os.Stderr, "%s: %v\n", file, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
|
20
src/cmd/go/testdata/script/version.txt
vendored
20
src/cmd/go/testdata/script/version.txt
vendored
@ -9,6 +9,19 @@ stderr 'with arguments'
|
||||
! go version -v
|
||||
stderr 'with arguments'
|
||||
|
||||
# Check that 'go version' succeed even when it does not contain Go build info.
|
||||
# It should print an error if the file has a known Go binary extension.
|
||||
#
|
||||
go version empty.txt
|
||||
! stdout .
|
||||
! stderr .
|
||||
go version empty.exe
|
||||
stderr 'could not read Go build info'
|
||||
go version empty.so
|
||||
stderr 'could not read Go build info'
|
||||
go version empty.dll
|
||||
stderr 'could not read Go build info'
|
||||
|
||||
# Neither of the two flags above should be an issue via GOFLAGS.
|
||||
env GOFLAGS='-m -v'
|
||||
go version
|
||||
@ -71,4 +84,9 @@ module m
|
||||
|
||||
-- empty.go --
|
||||
package main
|
||||
func main(){}
|
||||
func main(){}
|
||||
|
||||
-- empty.txt --
|
||||
-- empty.exe --
|
||||
-- empty.so --
|
||||
-- empty.dll --
|
||||
|
19
src/cmd/go/testdata/script/version_cshared.txt
vendored
Normal file
19
src/cmd/go/testdata/script/version_cshared.txt
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
[short] skip
|
||||
[!buildmode:c-shared] stop
|
||||
|
||||
env GO111MODULE=on
|
||||
|
||||
go get rsc.io/fortune
|
||||
go build -buildmode=c-shared -o external.so rsc.io/fortune
|
||||
go version external.so
|
||||
stdout '^external.so: .+'
|
||||
go version -m external.so
|
||||
stdout '^\tpath\trsc.io/fortune'
|
||||
stdout '^\tmod\trsc.io/fortune\tv1.0.0'
|
||||
|
||||
-- go.mod --
|
||||
module m
|
||||
|
||||
-- empty.go --
|
||||
package main
|
||||
func main(){}
|
Loading…
Reference in New Issue
Block a user