go build 是啥意思? (去构建与去安装)
Posted
技术标签:
【中文标题】go build 是啥意思? (去构建与去安装)【英文标题】:What does go build build? (go build vs. go install)go build 是什么意思? (去构建与去安装) 【发布时间】:2015-08-17 05:18:44 【问题描述】:新的 Go 程序员通常不知道或对基本的 go build 命令的作用感到困惑。
go build
和 go install
命令的具体作用是什么?它们将结果/输出放在哪里?
【问题讨论】:
go build vs go install 【参考方案1】:go
命令的作用取决于我们是为“普通”包还是为特殊的"main"
包运行它。
对于包裹
go build
构建你的包然后丢弃结果。
go install
构建然后安装您的$GOPATH/pkg
目录中的包。
对于命令(包main
)
go build
构建命令并将结果留在当前工作目录。
go install
在临时目录中构建命令,然后将其移动到 $GOPATH/bin
。
将什么传递给go build
?
您可以将 packages 传递给 go build
,您想要构建的软件包。您还可以从单个目录传递.go
文件列表,然后将其视为指定单个包的源文件列表。
如果没有提供包(导入路径),则构建应用到当前目录。
导入路径可能包含一个或多个"..."
通配符(在这种情况下,它是一个模式)。 ...
可以匹配任何字符串,例如net/...
匹配 net
包和位于其任何子文件夹中的包。命令
go build ./...
常用于在当前文件夹中构建包,所有包递归下来。在项目根目录中发出的这个命令会构建完整的项目。
有关指定包的更多信息,请运行go help packages
。
关于模块
在 Go 1.11 中引入了对 Go 模块的初步支持,从 Go 1.13 开始,模块成为默认模块。当go
工具从包含go.mod
文件(或当前文件夹的父文件夹之一)的文件夹运行时,go
工具以模块感知 模式运行(传统模式称为 GOPATH 模式)。
在模块感知模式下,GOPATH 不再定义导入的含义 在构建期间,但它仍然存储下载的依赖项(在 GOPATH/pkg/mod 中) 并安装命令(在 GOPATH/bin 中,除非设置了 GOBIN)。
构建模块时,构建的内容由构建列表指定。构建列表最初只包含主模块(包含运行go
命令的目录的模块),并且主模块的依赖被递归地添加到构建列表中(依赖的依赖也被添加)。
如需更多信息,请运行go help modules
。
基本上,您可以使用go build
来检查是否可以构建包(连同它们的依赖项),而go install
也(永久)将结果安装在$GOPATH
的正确文件夹中。
go build
将在一切正常时静默终止,如果包无法构建/编译,则会给您错误消息。
每当go
工具安装包或二进制文件时,它也会安装它所具有的任何依赖项,因此运行go install
还将自动安装您的程序所依赖的包(公开可用,“可获取”包)。
首先,请阅读官方How to Write Go Code 页面。
有关go
工具的更多信息:Command go
您还可以通过运行以下命令获得更多帮助:
go help build
还值得注意的是,从 Go 1.5 开始 go install
也会删除由 go build
(source) 创建的可执行文件:
如果'go install'(不带参数,表示当前目录) 成功,删除由“go build”编写的可执行文件(如果存在)。这样可以避免留下陈旧的二进制文件...
为了完成列表,go run
将您的应用程序编译到一个临时文件夹中,并启动该可执行二进制文件。当应用程序退出时,它会正确清理临时文件。
问题灵感来自 Dave Cheney 的 What does go build build?
【讨论】:
看起来很奇怪,如果 go install 与以前安装的可执行文件相同,它不会更新可执行文件......这里有什么见解吗?【参考方案2】:对于包裹:
go build
:构建你的包然后丢弃结果
在 Go 1.10(2018 年第一季度)之后,这将不是真的,感谢 CL 68116 和 CL 75473。请参阅this thread,我在这里引用。
go build
和go install
命令构建的具体作用每当 go 工具安装一个包或二进制文件时,它也会安装它拥有的任何依赖项,因此运行 go install 还会自动安装您的程序所依赖的包(公开可用的“go gettable”包)。
其实...go install
也会随着 Go 1.10 的变化而改变,除了新的缓存:
“
go install
”命令不再安装指定包的依赖项 (CL 75850)。如果您运行“
go install foo
”,则安装的唯一内容是foo
。以前,它是多种多样的。如果依赖项已过期,“
go install
”也会安装任何依赖项。 在“go install
”期间隐式安装依赖项给用户带来了很多困惑和头痛,但以前需要启用增量构建。 没有了。 我们认为新的“install what I said
”语义将更容易理解,特别是因为从错误报告中可以清楚地看出许多用户已经期望它们。要在“go install
”期间强制安装依赖项,请使用新的“go install -i
”,类似于“go build -i
”和“go test -i
”。“
go install
”用于安装任何重建的依赖项这一事实最常与-a
一起导致混淆,这意味着“force rebuild of all dependencies
”。 现在,“go install -a myprog
”将强制完全重建myprog
以及myprog
本身的所有依赖项,但只会安装myprog
。 (当然,所有重建的依赖项仍将保存在构建缓存中。) 结合新的基于内容的陈旧性分析,使这个案例更易于理解尤其重要,因为它看到了比以前更频繁地重建依赖项的充分理由,这会增加“为什么要安装我的依赖项”的困惑。 例如,如果您运行“go install -gcflags=-N myprog
”,它会安装一个没有编译器优化的myprog
,但它不再重新安装myprog
使用的标准库中没有编译器优化的包。
【讨论】:
有go build
,有get
s吗?我有一个构建错误cannot find package "github.com/spf13/cobra" in any of:…
。我不知道如何告诉它得到它。我需要明确得到吗?
@ctrl-alt-delor 使用哪个版本的 Go?您的项目中是否有 go.mod
文件?
go version go1.11.4 linux/amd64
。我不知道 go.mod。我正在重新构建https://github.com/cbroglie/mustache/blob/master/cmd/mustache/main.go
,这很奇怪,因为我刚刚构建了整个包,并使用这个示例作为基础,并且我确实创建了一个更基本的版本(但不使用这个库)。我看不出它是如何与 mustache 包一起安装的。
@ctrl-alt-delor 所以 cobr 被出售给github.com/cbroglie/mustache/tree/master/cmd/mustache/vendor/…。你的 GOPATH 设置正确了吗?
我发现了你已经发现的东西。该软件包位于供应商子目录中:这就是它没有安装的原因。但是我不知道为什么它现在不安装它。或者如何使用供应商目录(如果我将它复制到我的目录)。以上是关于go build 是啥意思? (去构建与去安装)的主要内容,如果未能解决你的问题,请参考以下文章