什么去构建构建?(进行构建与进行安装)


Answers:


125

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”软件包)。

首先,请阅读官方的“ 如何编写Go代码”页面。

有关该go工具的更多信息:Command go

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

go help build

还值得注意的是,从Go 1.5开始,go install还会删除go buildsource)创建的可执行文件:

如果成功执行“ go install”(不带参数,表示当前目录),请删除“ go build”编写的可执行文件(如果存在)。这样可以避免留下过时的二进制文件...

要完成该列表,go run请将您的应用程序编译到一个临时文件夹中,然后启动该可执行二进制文件。当应用退出时,它会正确清理临时文件。

戴夫·切尼(Dave Cheney)的著作《如何建造》启发了这个问题


1
如果go install与以前安装的可执行文件相同,则go install不会更新可执行文件似乎有点奇怪...这里有什么见解吗?
Scott Stensland '17

14

对于包装:

go build:构建您的软件包,然后丢弃结果

在Go 1.10(Q1 2018)之后,这将不成立,这要感谢 CL 68116CL 75473。看到这个线程,我在这里引用。

什么做的都是go buildgo 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,做getS' 我有一个构建错误cannot find package "github.com/spf13/cobra" in any of:…。我不知道如何告诉它。我需要明确获得吗?
ctrl-alt-delor

@ ctrl-alt-delor Go的哪个版本?您的项目中是否有go.mod文件?
VonC

go version go1.11.4 linux/amd64。我不知道go.mod。我正在重新构建https://github.com/cbroglie/mustache/blob/master/cmd/mustache/main.go,这很奇怪,因为我刚刚构建了整个程序包,并以该示例为基础,并且确实创建了一个更有效的基本版本(但未使用此库)。我看不到它是不是随胡子包一起安装的。
ctrl-alt-delor

@ ctrl-alt-delor因此将cobr出售给github.com/cbroglie/mustache/tree/master/cmd/mustache/vendor/…。您的GOPATH是否设置正确?
VonC

我发现了你已经发现的东西。该软件包位于供应商子目录中:这就是为什么未安装该软件包的原因。但是我不知道为什么现在不将其安装在构建中。或如何使用供应商目录(如果我将其复制到我的目录中)。
ctrl-alt-delor
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.