英文:
What is the difference between go get and go install?
问题
在使用go
工具一段时间后,看起来go get
命令的作用是:
- (可选)下载
- 编译
- 安装
一段软件,而go install
命令只是简单地:
- 编译
- 安装
它。在这种情况下,既然go get
命令已经取代了go install
,为什么还需要go install
命令呢?
英文:
After playing with the go
tool for a while, it looks like go get
:
- (optionally) downloads,
- compiles,
- and installs
a piece of software, while go install
simply
- compiles
- and installs
it. In this case, why does the go install
command exist, since go get
supersedes it?
答案1
得分: 137
go install
是在本地工作流程中的一部分。假设你想使用一个库,但由于某种原因需要进行更改。你可以按照以下步骤进行操作:
go get -d library
,这只是下载库;- 对下载的包进行更改;
go install library
来安装本地版本。
据我所知,go get
没有标志来指示它不应下载,因此它无法替代这里的go install
。
当你从头开始开发一个新的包时,也可以使用相同的工作流程。
编辑:六年后,Go 1.16更新并澄清了go install
和go get
的用法:https://tip.golang.org/doc/go1.16#modules
go install
,带或不带版本后缀(如上所述),现在是在模块模式下构建和安装包的推荐方式。应该使用go get
与-d
标志一起来调整当前模块的依赖关系而不构建包,使用go get
来构建和安装包已被弃用。在将来的版本中,-d
标志将始终被启用。
英文:
go install
is part of the workflow when working locally. Say you want to use a library, but for some reason a change is required. You would do:
go get -d library
, which only downloads it;- make the change on the downloaded package;
go install library
to install the local version.
As far as I know go get
has no flags to indicate it should not download, so it can't replace go install
here.
The same workflow is used when you develop a new package from scratch.
EDIT: six years later, Go 1.16 has updated and clarified the usage of go install
and go get
: https://tip.golang.org/doc/go1.16#modules
> go install
, with or without a version suffix (as described above), is now the recommended way to build and install packages in module mode. go get
should be used with the -d
flag to adjust the current module's dependencies without building packages, and use of go get
to build and install packages is deprecated. In a future release, the -d
flag will always be enabled.
答案2
得分: 60
go get
按照以下顺序执行两个主要操作:
-
下载并保存在
$GOPATH/src/<import-path>
中指定的导入路径的包(源代码),以及它们的依赖项,然后 -
执行
go install
-d
标志(go get -d
)指示go get
在下载包后停止;也就是说,它指示go get
不执行go install
。
区别:
go get
// 验证是否需要下载包,如果需要则下载并编译
go install
// 跳过下载包的部分,只进行编译(如果有任何缺少的包,将会报错)
关于GOPATH
环境变量
GOPATH
环境变量被Go工具使用。为了能够get
、build
和install
包,必须设置它,并且它指定了你的工作区的位置。在开发Go代码时,它可能是你唯一需要设置的环境变量。
再次强调,GOPATH
不应该指向Go安装目录,而应该指向你的工作区。
例如,在Windows上,如果你决定将工作区设置为c:\gowork\
,你需要将GOPATH
的值设置为c:\gowork
。
你的源代码应该位于c:\gowork\src\<some project folder>\
,在命令提示符下从c:\gowork\src\<some project folder>\
运行go get
后,你将看到c:\gowork\bin\
和c:\gowork\pkg\
被创建。
英文:
go get
does two main things in this order:
-
downloads and saves in
$GOPATH/src/<import-path>
the packages (source code) named in the import paths, along with their dependencies, then -
executes a
go install
The -d
flag (go get -d
) instructs go get
to stop after downloading the packages; that is, it instructs go get
not to do go install
<hr>
the difference:
go get
// verify if packages need to be downloaded, download if needed then compile
go install
// skip the part with packages download, just compile (this will throw an error if any packages are missing)
<hr>
about GOPATH
environment variable
The GOPATH
environment variable is used by the Go tools. It must be set in order to be able to get
, build
and install
packages, and it specifies the location of your workspace. It is likely the only environment variable you'll need to set when developing Go code.
Again, the GOPATH
should not point to the Go installation, but rather to your workspace.
For example, on Windows, if you decide that your workspace is at c:\gowork\
, you will need to set GOPATH
value as c:\gowork
Your source code should be at c:\gowork\src\<some project folder>\
and after you run go get
at command prompt from within c:\gowork\src\<some project folder>\
you will see the c:\gowork\bin\
and c:\gowork\pkg\
being created.
答案3
得分: 23
请注意,go 1.16 (2021年第一季度)将使这种差异更加明显,它是作为问题40276的一部分,通过CL 266360实现的:
go install
现在接受带有版本后缀的参数(例如,go install example.com/cmd@v1.0.0
)。
这将导致go install
以模块感知模式构建和安装包,忽略当前目录或任何父目录中的go.mod
文件。
这对于安装可执行文件而不影响主模块的依赖关系非常有用。
现在,**建议使用带或不带版本后缀的
go install
**的方式来构建和安装模块模式下的包。
应该使用
go get
命令与-d
标志来调整当前模块的依赖关系而不构建包,并且使用go get
构建和安装包已被弃用。
在将来的版本中,-d
标志将始终启用。
在2022年6月(1.19之前的Go 1.18),Chris Siebenmann详细介绍了“关于go install
可以安装的限制”。
它涉及一个带有replace
指令的模块:
如果你克隆了存储库并在其中运行
go install
,一切都正常,你会在$HOME/go/bin
中得到一个gospy
二进制文件。然而,正如我们在这里看到的,
go install ...@latest
的工作方式与此不同,replace
指令会导致此错误。
这触发了错误消息:
go: github.com/monsterxx03/gospy@latest (in github.com/monsterxx03/gospy@v0.5.0):
The go.mod file for the module providing named packages contains one or
more replace directives. It must not contain directives that would cause
it to be interpreted differently than if it were the main module.
关于此模式,go install
的帮助文档明确说明:
没有模块被视为“
main
”模块。如果包含在命令行上命名的包的模块有一个
go.mod
文件,它不能包含指令(replace
和exclude
),否则它将被解释为与主模块不同。
该模块不能要求更高版本的自身。
参见:
- 问题44840:
cmd/go
:当带有replace
指令的main
包模块时,go install cmd@version
会出错 - 问题40276:
cmd/go
:go install
应在模块模式下安装可执行文件在模块之外 - 问题45099:
x/tools/gopls
:无法安装gopls
v0.6.8(说明了此问题)
建议:
切换到使用**Go工作区**进行本地开发,并完全删除
go.mod
中的replace
指令。
正如Beth Brown在“熟悉工作区”中提到的:
以前,要在一个模块中添加一个功能并在另一个模块中使用它,你需要将更改发布到第一个模块,或者在依赖模块的
go.mod
文件中使用replace
指令编辑本地未发布的模块更改。为了无错误地发布,你必须在将第一个模块的本地更改发布后,从依赖模块的
go.mod
文件中删除replace
指令。使用Go工作区,你可以使用工作区目录根目录中的go.work文件来控制所有依赖关系。
go.work
文件具有use
和replace
指令,覆盖了各个go.mod
文件,因此无需逐个编辑每个go.mod
文件。
英文:
Note that go 1.16 (Q1 2021) will make that difference clearer, implemented with CL 266360 as part of issue 40276:
> go install
now accepts arguments with version suffixes (for example, go install example.com/cmd@v1.0.0
).
This causes go install
to build and install packages in module-aware mode, ignoring the go.mod
file in the current directory or any parent directory, if there is one.
This is useful for installing executables without affecting the dependencies of the main module.
>
> go install
, with or without a version suffix (as described above), is now the recommended way to build and install packages in module mode.
>
> go get
should be used with the -d
flag to adjust the current module's dependencies without building packages, and use of go get
to build and install packages is deprecated.
In a future release, the -d
flag will always be enabled.
In June 2022 (Go 1.18 right before 1.19), Chris Siebenmann details "a limitation on what 'go install
' can install".
It involves a module with a replace
directive:
> If you clone the repository and run 'go install
' inside it, everything works and you wind up with a gospy
binary in your $HOME/go/bin
.
>
> However, as we see here 'go install ...@latest
' works differently enough that the replace directive causes this error.
That triggers the error message:
go: github.com/monsterxx03/gospy@latest (in github.com/monsterxx03/gospy@v0.5.0):
The go.mod file for the module providing named packages contains one or
more replace directives. It must not contain directives that would cause
it to be interpreted differently than if it were the main module.
The help for 'go install' explicitly says about this mode:
> No module is considered the "main
" module.
>
> If the module containing packages named on the command line has a go.mod
file, it must not contain directives (replace
and exclude
) that would cause it to be interpreted differently than if it were the main module.
The module must not require a higher version of itself.
See:
- issue 44840:
cmd/go
:go install cmd@version
errors out when module withmain
package hasreplace
directive - issue 40276:
cmd/go
:go install
should install executables in module mode outside a module - issue 45099:
x/tools/gopls
: cannot installgopls
v0.6.8 (illustrates the issue)
Recommendation:
> switch to using Go workspaces for local development and drop the go.mod
replace
directives entirely.
As mentioned in "Get familiar with workspaces" by Beth Brown:
> Previously, to add a feature to one module and use it in another module, you needed to either publish the changes to the first module, or edit the go.mod
file of the dependent module with a replace
directive for your local, unpublished module changes.
>
> In order to publish without errors, you had to remove the replace
directive from the dependent module’s go.mod
file after you published the local changes to the first module.
>
> With Go workspaces, you control all your dependencies using a go.work file in the root of your workspace directory.
The go.work
file has use
and replace
directives that override the individual go.mod
files, so there is no need to edit each go.mod
file individually.
答案4
得分: 4
从文档中:
> 从Go 1.17开始,使用go get安装可执行文件已被弃用。可以使用go install代替。
>
> 在Go 1.18中,go get将不再构建包;它只用于在go.mod中添加、更新或删除依赖项。具体来说,go get将始终像启用了-d标志一样运行。
英文:
from doc:
> Starting in Go 1.17, installing executables with go get is deprecated. go install may be used instead.
>
> In Go 1.18, go get will no longer build packages; it will only be used to add, update, or remove dependencies in go.mod. Specifically, go get will always act as if the -d flag were enabled.
答案5
得分: 1
请参考以下内容:
请参考这个链接 - https://go.dev/doc/go-get-install-deprecation
引用内容如下:
从 Go 1.17 开始,使用 go get 安装可执行文件已被弃用。可以使用 go install 替代。
在 Go 1.18 中,go get 将不再构建包;它只会用于在 go.mod 中添加、更新或删除依赖项。具体来说,go get 将始终像启用了 -d 标志一样运行。
英文:
Please refer to this -
https://go.dev/doc/go-get-install-deprecation
Referencing -
Starting in Go 1.17, installing executables with go get is deprecated. go install may be used instead.
In Go 1.18, go get will no longer build packages; it will only be used to add, update, or remove dependencies in go.mod. Specifically, go get will always act as if the -d flag were enabled.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论