Go Build 参数详解
go build
是用于构建 Go 程序的命令。它有许多参数和选项,可以控制编译过程。以下是一些常用参数及其详解:
基本使用
1 |
|
go build
默认在当前目录中查找 main
包并生成可执行文件。
常用参数和选项
-o 输出文件名
1
go build -o outputfile
指定生成的可执行文件的名称。如果不指定,默认生成一个与所在目录或包名相同的可执行文件。
-a
1
go build -a
强制重新构建所有依赖的包,即使它们已经是最新的。
-n
1
go build -n
打印出需要执行的编译命令,但不实际执行它们(build 动作)。这对于调试编译过程非常有用。
-v
1
go build -v
显示正在构建的包的名称。
-x
1
go build -x
打印所有运行的命令。
-race
1
go build -race
启用数据竞争检测。仅适用于 64 位架构的 Linux、macOS 和 Windows 系统。
-ldflags
1
go build -ldflags="-s -w"
传递给连接器的标志。常见的标志有
-s
(省略符号表)和-w
(省略调试信息)。-tags
1
go build -tags="tag1 tag2"
设置编译标签,用于选择性地包括或排除代码。
-gcflags
1
go build -gcflags="all=-N -l"
传递给编译器的标志。例如
-N
禁用优化,-l
禁用内联。-mod
1
go build -mod=mod
指定使用哪种模块下载模式(
readonly
或vendor
)。-trimpath
1
go build --trimpath=$GOPATH
删除编译包含的固定路径信息,报错信息打印时只会包含文件的相对路径。
-modfile
1
go build --modfile=xxx.mod
指定使用的modfile文件,但go.mod文件依然是需要的,用于确认编译包的根目录,gosum依然是需要的,如传入的xx.mod, 则需要或对应生成为 xx.sum
-p
1
go build -p 8
开多少核cpu来并行编译,默认为本机CPU核数。
-work
1
go build -work=./temp
打印临时工作目录的名称,并在退出时不删除它。
部分命令详解
ldflags
-ldflags
基本语法
-ldflags
参数用于向 Go 语言的链接器传递特定的标志。这个参数可以用来控制生成的可执行文件的属性,比如嵌入版本信息、移除符号表和调试信息等。
1 |
|
常用的 -ldflags
标志
-s
和-w
-s
: 移除符号表,可以减小生成的二进制文件的大小。-w
: 移除调试信息,可以进一步减小二进制文件的大小。- 合并使用
-s -w
通常会显著减小二进制文件的大小。
1
go build -ldflags="-s -w"
-X importpath.name=value
- 用于设置包内变量的值。这通常用于设置编译时的变量,例如版本号、构建时间等。
importpath
是变量所在包的导入路径,name
是变量名,value
是要设置的值。
1
go build -ldflags="-X 'main.version=1.0.0' -X 'main.buildTime=$(date)'"
-linkmode
- 指定链接模式。常用的值有
internal
和external
。默认为internal
。 internal
: 默认的链接模式,使用 Go 自身的链接器。external
: 使用外部链接器(例如gcc
)。
1
go build -ldflags="-linkmode=external"
- 指定链接模式。常用的值有
-extld
- 指定外部链接器。如果使用
-linkmode=external
,可以使用此标志指定具体的链接器。
1
go build -ldflags="-linkmode=external -extld=gcc"
- 指定外部链接器。如果使用
-extldflags
- 传递特定标志给外部链接器。例如,可以使用这个标志传递优化参数或其他链接选项。
1
go build -ldflags="-linkmode=external -extldflags='-static'"
示例
移除符号表和调试信息
1
go build -ldflags="-s -w"
设置编译时变量
1
go build -ldflags="-X 'main.version=1.2.3' -X 'main.commitHash=abcdefg'"
使用外部链接器并传递标志
1
go build -ldflags="-linkmode=external -extldflags='-static'"
使用 -X
设置编译时变量的完整示例
假设有一个 Go 程序需要在编译时注入版本号和构建时间:
main.go
:
1 |
|
构建命令:
1 |
|
执行生成的可执行文件将输出:
1 |
|
通过使用 -ldflags
,你可以在构建时自定义许多编译和链接行为,以满足特定的需求。
gcflags
-gcflags
基本语法
-gcflags
参数用于向 Go 语言的编译器传递特定的标志。这个参数可以控制编译器的行为,例如禁用优化、禁用内联、设置特定的编译选项等。
1 |
|
常用的 -gcflags
标志
-N
- 禁用优化。这个选项对于调试代码非常有用,因为优化可能会使得调试器难以跟踪代码的执行。
1
go build -gcflags="-N"
- 禁用优化。这个选项对于调试代码非常有用,因为优化可能会使得调试器难以跟踪代码的执行。
-l
- 禁用内联。内联是编译器优化的一部分,它将函数的代码直接插入调用它的地方。这也可以让调试更容易。
1
go build -gcflags="-l"
- 禁用内联。内联是编译器优化的一部分,它将函数的代码直接插入调用它的地方。这也可以让调试更容易。
-m
- 输出优化的详细信息。这个选项可以帮助理解编译器进行了哪些优化。
1
go build -gcflags="-m"
- 输出优化的详细信息。这个选项可以帮助理解编译器进行了哪些优化。
-e
- 即使有编译错误,继续进行编译。这在希望查看所有编译错误时很有用。
1
go build -gcflags="-e"
- 即使有编译错误,继续进行编译。这在希望查看所有编译错误时很有用。
-S
- 输出编译的汇编代码。可以帮助了解 Go 代码如何被编译成机器码。
1
go build -gcflags="-S"
- 输出编译的汇编代码。可以帮助了解 Go 代码如何被编译成机器码。
-B
- 禁用边界检查。可以使得运行时跳过数组和切片的边界检查,但是可能导致不安全的访问。
1
go build -gcflags="-B"
- 禁用边界检查。可以使得运行时跳过数组和切片的边界检查,但是可能导致不安全的访问。
针对特定包设置 -gcflags
可以使用 all=
前缀应用于所有包,也可以对特定包应用不同的标志。
应用于所有包
1
go build -gcflags="all=-N -l"
应用于特定包
1
go build -gcflags="path/to/package=-N -l"
示例
禁用所有包的优化和内联
1
go build -gcflags="all=-N -l"
输出优化信息
1
go build -gcflags="-m"
输出编译的汇编代码
1
go build -gcflags="-S"
禁用特定包的边界检查
1
go build -gcflags="path/to/package=-B"
gcflag
传入的方式为:-gcflag="pattern= args
,其中pattern
代表取值分别为 main,all,std,...,
用于指定编译参数作用的范围,args
则为对应的编译参数。
main
: 表示main
函数所在的顶级包路径;all
: 表示GOPATH
中的所有包。如果在modules
模式下,则表示主模块和它所有的依赖,包括test
文件的依赖;std
: 表示Go
标准库中的所有包;...
:...
是一个通配符,可以匹配任意字符串(包括空字符串)。例如:- 例如:
net/...
表示net
模块和它的所有子模块 ./...
表示当前主模块和所有子模块- 注意: 如果
pattern
中包含了/
和...
,那么就不会匹配vendor
目录- 例如:
./...
不会匹配./vendor
目录。可以使用./vendor/..
. 匹配vendor
目录和它的子模块。
- 例如:
- 例如:
使用 -gcflags
的完整示例
假设有一个 Go 程序 main.go
:
1 |
|
你希望在调试过程中禁用优化和内联:
1 |
|
通过这个命令构建的可执行文件将不会进行优化和内联,使得调试器更容易跟踪代码的执行。
通过使用 -gcflags
,你可以灵活地控制编译器的行为,从而更好地调试和优化你的 Go 程序。