【发布时间】:2015-08-17 05:18:44
【问题描述】:
新的 Go 程序员通常不知道或对基本的 go build 命令的作用感到困惑。
go build 和 go install 命令的具体作用是什么?它们将结果/输出放在哪里?
【问题讨论】:
标签: go build compilation
新的 Go 程序员通常不知道或对基本的 go build 命令的作用感到困惑。
go build 和 go install 命令的具体作用是什么?它们将结果/输出放在哪里?
【问题讨论】:
标签: go build compilation
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 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,有gets吗?我有一个构建错误cannot find package "github.com/spf13/cobra" in any of:…。我不知道如何告诉它得到它。我需要明确得到吗?
go.mod 文件?
go version go1.11.4 linux/amd64。我不知道 go.mod。我正在重新构建https://github.com/cbroglie/mustache/blob/master/cmd/mustache/main.go,这很奇怪,因为我刚刚构建了整个包,并使用这个示例作为基础,并且我确实创建了一个更基本的版本(但不使用这个库)。我看不出它是如何与 mustache 包一起安装的。