正常情况下我们应该从go语言的 tutorial 开始,先写个 hello world 再接触 go modules ,最好了解一下 go 的交叉编译。但在实际工作中当然是在做的过程中去现学,而不是等你什么都会了再干活。
我们今天以github上的一个项目为例,尝试手动去编译这个项目。测试对象的项目地址为:
https://github.com/sakeven/httpproxy.git
我们先使用 git 将代码取到本地:
$ git clone https://github.com/sakeven/httpproxy.git
Cloning into 'httpproxy'...
remote: Enumerating objects: 320, done.
remote: Total 320 (delta 0), reused 0 (delta 0), pack-reused 320
Receiving objects: 100% (320/320), 185.78 KiB | 518.00 KiB/s, done.
Resolving deltas: 100% (153/153), done.
观察一下项目代码,发现里面没有Makefile,有一个入口程序 main.go
在项目目录中没有 go.mod 和 go.sum 模块文件,但有一个 Godeps 和 vendor 目录。这两个目录下一步再讲是做什么的,其它目录都是代码目录。
此时如果直接使用 go build 编译会报错:
$ go build main.go
main.go:7:2: no required module provides package github.com/sakeven/httpproxy/proxy:
go.mod file not found in current directory or any parent directory;
see 'go help modules'
单文件的go代码可以直接编译,当代码中有依赖时就需要使用 go modules 来组织。
执行 go mod init 来初始化项目依赖:
$ go mod init
go: creating new go.mod: module github.com/sakeven/httpproxy
go: copying requirements from Godeps/Godeps.json
go: to add module requirements and sums:
go mod tidy
从命令输出可以了解到 go 从 Godeps 中获取了项目的依赖。Godeps 是由 godep 工具创建的,在原始项目中这个目录是自带的,应该是项目作者自己本机安装了 godep 并用 godep 生成了项目依赖。
此时项目目录中已经有了 go.mod 文件:
此时执行 go build 会报错,提示要更新 vendor 目录:
按照提示执行 go mod vendor,再次报错,从报错信息了解到缺 go.sum,我们通过 go mod tidy 添加 go.sum 文件。
$ go mod vendor
github.com/sakeven/httpproxy/cache/redis imports
github.com/garyburd/redigo/redis: missing go.sum entry for module providing package github.com/garyburd/redigo/redis (imported by github.com/sakeven/httpproxy/cache/redis); to add:
go get github.com/sakeven/httpproxy/cache/redis
github.com/sakeven/httpproxy/proxy imports
github.com/op/go-logging: missing go.sum entry for module providing package github.com/op/go-logging (imported by github.com/sakeven/httpproxy/proxy); to add:
go get github.com/sakeven/httpproxy/proxy
添加完 go.sum 后再执行 go mo vendor 不再报错。
查看 go.mod 和 go.sum 里面都是工具自动生成的依赖信息。
此时再执行 go build 已经可以正常编译了。
默认编译的是 windows 版本的可执行文件,如果需要编译 linux 版本的可执行文件,可以执行如下命令,通过更改环境变量进行交叉编译。
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main_linux_amd64
查看编译后的文件类型,可以看到交叉编译已经完成。
最后总结一下,当单文件时可以使用 go build 进行编译,当有模块依赖时需要使用 go mod 命令生成 go.mod、go.sum、vendor 等辅助依赖文件。项目依赖可以使用 godep 命令自动生成 Godeps 目录。go mod init 会从 Godeps 目录获取依赖信息。
Godeps 目录中的 json 配置文件是通过 godep 命令生成的,godep 的使用可以查阅 godep 在线文档。godep安装和使用的简单的例子为:
$ go install github.com/tools/godep@latest
go: downloading github.com/tools/godep v0.0.0-20180126220526-ce0bfadeb516
go: finding module for package golang.org/x/tools/go/vcs
go: finding module for package github.com/kr/pretty
go: finding module for package github.com/pmezard/go-difflib/difflib
go: finding module for package github.com/kr/fs
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading github.com/kr/fs v0.1.0
go: downloading golang.org/x/tools v0.1.12
go: downloading github.com/kr/pretty v0.3.0
go: found github.com/kr/fs in github.com/kr/fs v0.1.0
go: found github.com/kr/pretty in github.com/kr/pretty v0.3.0
go: found github.com/pmezard/go-difflib/difflib in github.com/pmezard/go-difflib v1.0.0
go: found golang.org/x/tools/go/vcs in golang.org/x/tools v0.1.12
go: downloading github.com/kr/text v0.2.0
go: downloading github.com/rogpeppe/go-internal v1.6.1
go: downloading golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
$ godep --help
Godep is a tool for managing Go package dependencies.
Usage:
godep command [arguments]
The commands are:
save list and copy dependencies into Godeps
go run the go tool with saved dependencies
get download and install packages with specified dependencies
path print GOPATH for dependency code
restore check out listed dependency versions in GOPATH
update update selected packages or the go version
diff shows the diff between current and previously saved set of dependencies
version show version info
Use "godep help [command]" for more information about a command.
$ godep save
godep: [WARNING]: godep should only be used inside a valid go package directory and
godep: [WARNING]: may not function correctly. You are probably outside of your $GOPATH.
godep: [WARNING]: Current Directory: D:\gitRepo\github\httpproxy
godep: [WARNING]: $GOPATH: C:\Users\Administrator\go
godep: WARNING: Recorded major go version (go1.8) and in-use major go version (go1.18) differ.
godep: To record current major go version run `godep update -goversion`.
godep: Unable to find SrcRoot for package .
更多关于 golang 的入门的文章为:
全文完。
如果转发本文,文末务必注明:“转自微信公众号:生有可恋”。