Go语言编译和工具链

​ Go 语言的工具链非常丰富,从获取源码、编译、文档、测试、性能分析,到源码格式化、源码提示、重构工具等应有尽有。

​ 在 Go 语言中可以使用测试框架编写单元测试,使用统一的命令行即可测试及输出测试报告的工作。基准测试提供可自定义的计时器和一套基准测试算法,能方便快速地分析一段代码可能存在的 CPU 耗用和内存分配问题。性能分析工具可以将程序的 CPU 耗用、内存分配、竞态问题以图形化方式展现出来。

一.go build命令

​ Go语言的编译速度非常快。Go 1.9 版本后默认利用Go语言的并发特性进行函数粒度的并发编译。

​ Go语言的程序编写基本以源码方式,无论是自己的代码还是第三方代码,并且以 GOPATH 作为工作目录和一套完整的工程目录规则。因此Go语言中日常编译时无须像 C++ 一样配置各种包含路径、链接库地址等。

​ Go语言中使用 go build 命令主要用于编译代码。在包的编译过程中,若有必要,会同时编译与之相关联的包。

​ go build 有很多种编译方法,如无参数编译、文件列表编译、指定包编译等,使用这些方法都可以输出可执行文件。

2.go build+文件列表

编译同目录的多个源码文件时,可以在 go build 的后面提供多个文件名,go build 会编译这些源码,输出可执行文件,“go build+文件列表”的格式如下:

1
go build file1.go file2.go……

提示

使用“go build+文件列表”方式编译时,可执行文件默认选择文件列表中第一个源码文件作为可执行文件名输出。

如果需要指定输出可执行文件名,可以使用-o参数

1
go build -o myexec main.go lib.go

注意

使用“go build+文件列表”编译方式编译时,文件列表中的每个文件必须是同一个包的 Go 源码。也就是说,不能像 C++ 一样将所有工程的 Go 源码使用文件列表方式进行编译。编译复杂工程时需要用“指定包编译”的方式。

“go build+文件列表”方式更适合使用Go语言编写的只有少量文件的工具。

3.go build+包

1
go build -o main 项目目录或者mian文件位置

4.go build 编译时的附加参数

go build 还有一些附加参数,可以显示更多的编译信息和更多的操作,详见下表所示。

附加参数 备 注
-v 编译时显示包名
-p n 开启并发编译,默认情况下该值为 CPU 逻辑核数
-a 强制重新构建
-n 打印编译时会用到的所有命令,但不真正执行
-x 打印编译时会用到的所有命令
-race 开启竞态检测

5.go build时指定系统及环境

1
2
3
GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} go build -o ${BUILD_NAME} ${APP_MAIN}
1
2
3
4
[root@dy-workspace /workspace/gocode-gin]# go env GOOS
linux
[root@dy-workspace /workspace/gocode-gin]# go env GOARCH
amd64

6.go build时使用ldflags

1
go build -ldflags "-w -s -X main.Version=${VERSION} -X main.Build=${BUILD}"

解释:

1
2
3
-w 去掉DWARF调试信息,得到的程序就不能用gdb调试了。
-s 去掉符号表,panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果,
-X 设置包中的变量值

二.go clean命令——清除编译文件

1.go clean

Go语言中

1
go clean

命令可以移除当前源码包和关联源码包里面编译生成的文件,这些文件包括以下几种:

  • 执行go build命令时在当前目录下生成的与包名或者 Go 源码文件同名的可执行文件。在 Windows 下,则是与包名或者 Go 源码文件同名且带有“.exe”后缀的文件。
  • 执行go test命令并加入-c标记时在当前目录下生成的以包名加“.test”后缀为名的文件。在 Windows 下,则是以包名加“.test.exe”后缀的文件。
  • 执行go install命令安装当前代码包时产生的结果文件。如果当前代码包中只包含库源码文件,则结果文件指的就是在工作区 pkg 目录下相应的归档文件。如果当前代码包中只包含一个命令源码文件,则结果文件指的就是在工作区 bin 目录下的可执行文件。
  • 在编译 Go 或 C 源码文件时遗留在相应目录中的文件或目录 。包括:“_obj”和“_test”目录,名称为“_testmain.go”、“test.out”、“build.out”或“a.out”的文件,名称以“.5”、“.6”、“.8”、“.a”、“.o”或“.so”为后缀的文件。这些目录和文件是在执行go build命令时生成在临时目录中的。

2.go clean -i -n

go clean命令就像 Java 中的maven clean命令一样,会清除掉编译过程中产生的一些文件。在 Java 中通常是 .class 文件,而在Go语言中通常是上面我们所列举的那些文件。

1
go clean -i -n

命令还可以指定一些参数。对应的参数的含义如下所示:

  • -i 清除关联的安装的包和可运行文件,也就是通过go install安装的文件;
  • -n 把需要执行的清除命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的;
  • -r 循环的清除在 import 中引入的包;
  • -x 打印出来执行的详细命令,其实就是 -n 打印的执行版本;
  • -cache 删除所有go build命令的缓存
  • -testcache 删除当前包所有的测试结果

实际开发中go clean命令使用的可能不是很多,一般都是利用go clean命令清除编译文件,然后再将源码递交到 github 上,方便对于源码的管理。

3.演示

下面我们以本地的一个项目为例,演示一下go clean命令:

1
2
3
go clean -n
cd D:\code
rm -f code code.exe code.test code.test.exe main main.exe

在命令中使用-n标记可以将命令的执行过程打印出来,但不会正真执行。如果既要打印命令的执行过程同时又执行命令的话可以使用-x标记,如下所示:

1
2
3
go clean -x
cd D:\code
rm -f code code.exe code.test code.test.exe main main.exe

三.参考文献

Go语言编译和工具链