go mod模式下的go命令 2021-11-06

【golang正确安装完毕后,命令行输入go可获得go命令提示】

#go env 查看当前golang的语言环境配置

GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"     # go env 文件位置
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"      # go get 第三方module的下载位置,$GOPATH/pkg/mod
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.xxx.com+643d7a06+4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16.4"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null" # 执行go env时,如当前路径下不存在go.mod文件,GOMOD值为"/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2933218391=/tmp/go-build -gno-record-gcc-switches"

#go build vs go install vs go get

  • go build命令是compile packages and dependencies,编译生成可执行文件
    build的对象是一个package
    如果是build普通包,当你执行go build命令后,不会产生任何文件。
    如果是build main包,当只执行go build命令后,会在当前目录下生成一个可执行文件。如果需要在$GOPATH/bin下生成相应的可执行文件,需要执行go install 或者使用 go build -o 路径/a.exe

  • 执行go install命令会完成类似 go build 的功能 ,但go install 命令执行生成期间会拉取需要的其他依赖,且生成的可执行文件是在【$GOPATH/bin】目录中

[root@VM-165-116-centos ~]# go install golang.org/x/website/tour@latest
go: downloading golang.org/x/website/tour v0.0.0-20210616181959-e0d934b43647
go: downloading golang.org/x/website v0.0.0-20211025185159-22652b4484a0
go: downloading golang.org/x/tools v0.1.3-0.20210525215409-a3eb095d6aee
go: downloading github.com/yuin/goldmark v1.3.5
[root@VM-165-116-centos bin]# cd $GOPATH/bin
[root@VM-165-116-centos bin]# ls
dlv goimports go-outliner gopls tour

  • 起码,在go1.17之前,go get这个命令在内部实际上分成了两步操作:第一步是下载源码包,第二步是执行 go install

[go get] downloads the packages named by the import paths, along with their
dependencies. It then installs the named packages, like 'go install'.

see https://golang.org/ref/mod#go-get

go get accepts a list of packages, package patterns, and module paths as arguments.

  • If a package argument is specified, go get updates the module that provides the package.
  • If a package pattern is specified (for example, all or a path with a ... wildcard), go get expands the pattern to a set of packages, then updates the modules that provide the packages.
  • If an argument names a module but not a package (for example, the module golang.org/x/net has no package in its root directory), go get will update the module but will not build a package.
  • If no arguments are specified, go get acts as if . were specified (the package in the current directory); this may be used together with the -u flag to update modules that provide imported packages.

因此,
项目根目录运行go get -u命令(go get acts as if . were specified)会将项目中的包升级到最新的次要版本或者修订版本;
项目根目录运行go get -u=patch命令会将项目中的包升级到最新的修订版本;

而运行go get [包名]@[版本号]命令会下载对应包的指定版本或者将对应包升级到指定的版本。
go get [包名]@[版本号]命令中版本号可以是 x.y.z 的形式,例如 go get [email protected],也可以是 git 上的分支或 tag,例如 go get foo@master,还可以是 git 提交时的哈希值,例如 go get foo@e3702bed2

注意:
go get命令动态获取远程代码库,目前支持的代码托管平台有 BitBucket、GitHub、Google Code 和 Launchpad。在使用 go get 命令前,需要安装与远程包匹配的代码管理工具,如 Git、SVN、HG 等,下载源码包的 go 工具会自动根据不同的域名调用不同的源码工具,对应关系如下
BitBucket (Mercurial Git) GitHub (Git) Google Code Project Hosting (Git, Mercurial, Subversion) Launchpad (Bazaar)
所以为了 go get 命令能正常工作,必须确保安装了合适的源码管理工具,并同时把这些命令加入PATH 中

如何让go全量编译

2种方式:

  • build使用-aoption
go build -v -a -o bin/console app/stream.go app/web.go app/main.go app/worker.go app/robot.go app/main_test.go
  • 清理编译缓存
go clean -cache
go build -v -o bin/console app/stream.go app/web.go app/main.go app/worker.go app/robot.go app/main_test.go

查看go.mod中module为什么被依赖

go mod why

[root@VM-165-116-centos console_backend]# go mod why -m git.code.oa.com/trpc-go/trpc-go
# git.code.oa.com/trpc-go/trpc-go
console/config
git.code.oa.com/rainbow/golang-sdk/config
git.code.oa.com/trpc-go/trpc-go

Why does "go get" use HTTPS when cloning a repository?

reference:https://golang.org/doc/faq#git_https
当不设置GOPROXY的时候,从安全考虑,go get默认使用HTTPS去clone一个远程仓库

Companies often permit outgoing traffic only on the standard TCP ports 80 (HTTP) and 443 (HTTPS), blocking outgoing traffic on other ports, including TCP port 9418 (git) and TCP port 22 (SSH). When using HTTPS instead of HTTP, git enforces certificate validation by default, providing protection against man-in-the-middle, eavesdropping and tampering attacks.The go get command therefore uses HTTPS for safety.

Git can be configured to authenticate over HTTPS or to use SSH in place of HTTPS. To authenticate over HTTPS, you can add a line to the $HOME/.netrc file that git consults:

machine github.com login USERNAME password APIKEY
For GitHub accounts, the password can be a personal access token.
Git can also be configured to use SSH in place of HTTPS for URLs matching a given prefix. For example, to use SSH for all GitHub access, add these lines to your ~/.gitconfig:
[url "ssh://[email protected]/"]
insteadOf = https://github.com/

参考这里

注意

go get安装二进制的功能会在1.17的后续版本中删除,go get被设计为仅下载源码,并将依赖添加至 go.mod 的工具,不会执行go install

这样以来,go get 和 go install 各自实现的功能与名字更加契合:

  • go install 通过gomod管理器安装一个package到$GOPATH/bin,不会修改任何项目的go.mod文件
  • go get 通过gomod管理器下载package源码,修改go.mod文件,但不通过源码安装可执行文件

一个亲身案例:
为了用泛型把go从1.16升级到1.18,然后在vscode写泛型代码。结果vscode对泛型代码一片飘红报错,但是却能正常编译

编译是当前go编译器来完成的,正常编译说明 go 1.18 已经正常工作了。而vscode对泛型代码一片飘红报错,是vscode go插件起的作用,而go插件依赖的是$GOPATH/bin路径下的go binary tools,这说明原来go 1.16环境下的go工具同样需要升级到1.18

使用go version -m检查下gopls的版本,果然gopls是go 1.16环境下制品:

[root@centos bin]# echo $GOPATH
/root/go
[root@centos bin]# go version -m /root/go/bin/gopls 
/root/go/bin/gopls: go1.16.4
        path    golang.org/x/tools/gopls
        mod     golang.org/x/tools/gopls        v0.9.1  h1:SigsTL4Hpv3a6b/a7oPCLRv5QUeSM6PZNdta1oKY4B0=
        dep     github.com/google/go-cmp        v0.5.7  h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
        ......
[root@centos bin]# 

为了重新安装$GOPATH/bin/*,在go1.18+版本,我们可以先清空该目录,然后使用go get下载源码,go install 通过gomod管理器安装一个package到$GOPATH/bin

[root@centos bin]# go install github.com/haya14busa/goplay/cmd/goplay
no required module provides package github.com/haya14busa/goplay/cmd/goplay; to add it:
        go get github.com/haya14busa/goplay/cmd/goplay
[root@centos bin]#
[root@centos bin]# go get github.com/haya14busa/goplay/cmd/goplay
go: downloading github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c
go: added github.com/haya14busa/goplay v1.0.0
[root@centos bin]#
[root@centos bin]# go install github.com/haya14busa/goplay/cmd/goplay
[root@centos bin]#

你可能感兴趣的:(go mod模式下的go命令 2021-11-06)