Golang 编译约束/条件编译 ( // +build <tags> )
通常对程序进行编译的时候,可能带一些条件(如不同平台、架构有不同的代码实现),让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译。golang中,称之为编译约束,进行编译约束的方式有2种分别:
- 编译标签(build tag)
- 文件后缀
编译标签 (build tag)#
在源码文件顶部添加注释,来决定文件是否参与编译
// +build <tags>
- 以逗号分开表示
AND
- 以空格分开表示
OR
!
表示NOT
- 一个文件可以有多个
+build
构建标记,它们之间的关系是逻辑与
的关系
标签可以指定为以下内容:
- 操作系统,环境变量中
GOOS
的值,如:linux
、darwin
、windows
等等。可以通过go env
查看GOOS
环境变量的值。 - 操作系统的架构,环境变量中
GOARCH
的值,如:arch64
、x86
、i386
等等。可以通过go env
查看GOARCH
环境变量的值。 - 使用的编译器,
gc
或者gccgo
。 - 是否开启CGO,
cgo
。 - golang版本号: 比如Go Version 1.1为
go1.1
,Go Version 1.12版本为go1.12
,以此类推。 - 其它自定义标签,通过
go build -tags
指定的值。
例如,编译条件为(linux AND 386) OR (darwin AND (NOT cgo))
// +build linux,386 darwin,!cgo
另外一个文件可以有多个编译约束,比如条件为(linux OR darwin) AND amd64
// +build linux darwin
// +build amd64
也可以将一个文件从编译中排除,使用ignore
标签。
// +build ignore
注意:// +build
的下一行必须是空行。
// +build linux
// main package comment
package main
下面的写法不会识别为build tag
,而会解析为包注释:
// +build linux
package main
文件后缀#
除了编译标签,编译器也会根据文件后缀来自动选择编译文件,格式如下:
$filename_$GOOS.go
$filename_$GOARCH.go
$filename_$GOOS_$GOARCH.go
$filename
: 源文件名称。$GOOS
: 表示操作系统,从环境变量中获取。$GOARCH
: 表示系统架构,从环境变量中获取。
如在项目中有tcp.go
和tcp_linux_x86.go
两个文件,执行:
GOOS=linux GOARCH=x86 go build
将选择 tcp_linux_x86.go
进行编译。
利用ldflags在编译过程中为变量赋值#
本节为附加说明,不属于条件编译的范畴。有时我们需要在编译过程中为变量赋值,此时可以利用ldflags参数完成。ldflags
是go build
的一个参数,使用方式如下:
go build -ldflags "-w -s -X main.Version=${VERSION} -X github.com/demo/version.BuildNo=${BUILD_NO}"
参数说明:
-w 删除DWARF信息:编译出来的程序无法用gdb进行调试。
-s 删除符号表:panic的stack trace没有文件名/行号信息,等价于C/C++程序被strip。
-X 替换包中的变量的值。
加上-w -s可以有效减少编译出来地程序的大小,但不利于进行调试和日志追踪。
参考文章#
本文转载自:Go 知识点(18)— 条件编译(编译标签、文件后缀)_wohu1104的博客-CSDN博客_go 条件编译
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
2020-12-14 使docker命令不用加sudo的方法