`cmd/go: go install` 命令在没有安装目标的情况下应该发出警告或错误,

7gs2gvoe  于 5个月前  发布在  Go
关注(0)|答案(6)|浏览(43)

(我在 go version go1.19.5 linux/amd64 上)
go test 如果没有可执行文件会报告警告:

$ go test -run test_that_doesn't_exist
testing: warning: no tests to run

如果给定目录中没有 Go 文件,go testgo rungo buildgo install 命令也会发出警告。

$ go test
no Go files in /directory

(在 go run 的情况下,警告是 go: no go files listed)
然而,与 go testgo run 不同,当当前目录中有 Go 文件但没有生成二进制文件时,go buildgo install 不会发出警告。
例如,在一个包含文件 helloWorld.go 的目录中,其内容如下:

package hello

import "fmt"

func talk() {
    fmt.Println("Hello World!")
}

go run 会发出警告

$ go run helloWorld.go 
package command-line-arguments is not a main package

go test 会发出警告

$ go test
?   	/helloWorldDir	[no test files]
$ go test helloWorld.go 
?   	command-line-arguments	[no test files]

但是 go installgo build 报告什么都没有。

$ go install helloWorld.go
$
$ go build helloWorld.go
$

仅执行 go installgo build 也报告什么都没有。

$ go install
$
$ go build
$

我本应看到与 go run 相同的警告

$ go install
package is not a main package
$ go build
package is not a main package
pb3skfrl

pb3skfrl1#

当你运行 "go build helloWorld.go" 时,Go命令不会打印任何内容,这并不意味着什么都没发生,只是表示在构建操作结束时没有报告任何内容。尝试运行 "go build -x" 以查看发生了什么。

此外,开发者一直在非主包上运行 "go build",没有任何期望会产生二进制文件——他们只是想看看源代码更改后代码是否仍然可以编译。

人们还运行非主包的构建以收集更多信息。例如,在你的 hello 包中,你可能想要使用 "-gcflags=-m" 进行构建,以查看编译器在内联或逃逸分析方面做出了哪些决策。

z0qdvdin

z0qdvdin2#

或许应该独立考虑 go install。没有 func main() 的包上 go install 有什么用?

hfsqlsce

hfsqlsce3#

当使用GOPATH模式时,go install将在$GOPATH/src中安装一个非主包.a文件。此外,在1.20之前,go install将标准库包安装在$GOROOT/src中。也就是说,现在确实很少有人使用GOPATH模式了,人们可能开始使用1.20版本。go install对于非主包的警告现在可能是有意义的。
CC @bcmills

wbgh16ku

wbgh16ku4#

尽管 go install cmd 模式匹配了主包和非主包的混合,但它仍然很有用。我认为其他模式也是如此。
另一方面,我认为如果 go install 实际上没有任何要安装的内容(而不仅仅是警告!),那么它完全出错是合理的(而不仅仅是警告!)——也就是说:如果参数与任何 main 包都不匹配,且剩余参数没有 (GOPATHGODEBUG=installgoroot=all) 安装目标。

e1xvtsh3

e1xvtsh35#

bcmills,你认为这是一份适合初次投稿的好杂志吗?

dfty9e19

dfty9e196#

@anthoturc,我说实话不确定。😅
但是如果你想看一下,go install命令的入口点是src/cmd/go/internal/work/build.go中的函数runInstall

相关问题