什么是去构建构建? (去构建与去安装)

新的 Go 程序员通常不知道或者搞不清基本的 Go build 命令是做什么的。

go buildgo install命令到底构建了什么,它们将结果/输出放在哪里?

106995 次浏览

go命令的作用取决于我们是为“普通”包还是为特殊的 "main"包运行它。

包裹

  • go build  构建您的包,然后 丢弃结果
  • 然后,go install$GOPATH/pkg目录中构建 安装包。

用于命令(包 main)

  • go build  构建命令并将结果保留在 目前的工作目录中。
  • go install在一个临时目录中构建命令,然后将其移动到 $GOPATH/bin

传什么给 go build

您可以将 包裹传递给 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也会自动安装程序所依赖的包(公开可用的“ go gettable”包)。

首先,请阅读官方的 < strong > How to Write Go Code 页面。

关于 go工具的更多信息: 命令行动

您还可以通过运行以下命令获得更多帮助:

go help build

同样值得注意的是,从 Go 1.5 go install开始,也会删除由 go build(来源)创建的可执行文件:

如果“ go install”(没有参数,表示工作目录) 如果成功,删除由‘ go build’编写的可执行文件(如果存在)。这样可以避免留下陈旧的二进制文件..。

为了完成列表,go run将应用程序编译到一个临时文件夹中,并启动该可执行二进制文件。当应用程序退出时,它会正确地清除临时文件。

问题的灵感来自 Dave Cheney 的 建造什么?

套餐:

构建你的软件包,然后 弃牌的结果

多亏了 CL 68116CL 75473,在 Go 1.10(2018年第一季度)之后就不会这样了。参见我在这里引用的 这根线

go buildgo install命令究竟是如何构建的

无论 Go 工具何时安装一个包或二进制文件,它也会安装它所具有的任何依赖项,所以运行 go 安装也会自动安装程序所依赖的包(公开可用的“ go gettable”包)。

实际上... go install也会随着新缓存的 Go 1.10和 此外而改变:

go install”命令 不再安装命名包的依赖项(CL 75850)。

如果你运行“ go install foo”,唯一安装的是 foo

如果依赖项过时,“ go install”也会安装任何依赖项。
在“ go install”期间隐式安装依赖项给用户带来了很多困惑和麻烦,但是以前需要启用增量构建。
不再是了。
我们认为新的“ install what I said”语义将更容易理解,特别是从 bug 报告中可以清楚地看出,许多用户已经预料到了这一点。
要在“ 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