golang项目中使用条件编译
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang项目中使用条件编译相关的知识,希望对你有一定的参考价值。
参考技术Agolang中没有类似C语言中条件编译的写法,比如在C代码中可以使用如下语法做一些条件编译,结合宏定义来使用可以实现诸如按需编译release和debug版本代码的需求
build tags 是通过代码注释的形式实现的,要写在文件的最顶端;
go build指令在编译项目的时候会检查每一个文件的build tags,用来决定是编译还是跳过该文件
build tags遵循以下规则
示例:
约束此文件只能在支持kqueue的BSD系统上编译
一个文件可能包含多行条件编译注释,比如:
约束该文件在linux/386 或 darwin/386平台编译
需要注意的点
正确的写法如下:
编译方法:
具有_$GOOS.go后缀的go文件在编译的时候会根据当前平台来判断是否将该文件导入并编译;同样适用于处理器架构判断 _$GOARCH.go。
两者可以结合起来使用,形式为: _$GOOS_$GOARCH.go
示例:
文件名必须提供,如果只由后缀的文件名会被编译器忽略,比如:
这两个文件会被编译器忽略,因为以下划线开头的文件都会被忽略
学习golang的条件编译
昨天学习了go generate,今天学习另外一个知识点,一样是跟注释有关的知识点。golang的条件编译,也叫编译约束(build constraints)。应用场景
条件编译可以在适应不同平台操作系统的代码上体现。不同的操作系统平台,对某些特性的支持不太一样,但是往往在业务层面上的代码不会去关注,所以需要对底层的代码进行一些封装。比如,Windows和Linux的home目录是不一样的,而我们的业务需要读取home目录,那此时我们就可以用条件编译来达到效果。
条件编译的两种形式
条件编译可以通过两种方式实现:
- 在源文件开头添加注释;
- 以文件名后缀的方式实现。
以添加注释的方式
注释的格式如下:
// +build tags
tags可以是操作系统,也可以是编译器选项,具体有什么可以填的,请往后面看,我们先看个例子来有个大概的印象:
// +build windows
package main
import "fmt"
func echo() {
fmt.Print("windows")
}
// +build linux
package main
import "fmt"
func echo() {
fmt.Print("linux")
}
package main
func main() {
echo()
}
我写了两个文件,都有echo方法,并在main函数中调用了echo方法,现在运行的话,在Windows环境下会打印“windows”,在Linux环境下会打印“linux”。看到这应该就能大致懂了什么是条件编译以及它的应用场景。
那么我们当我们有多个编译条件呢?比如,Linux下的amd64环境,那应该怎么定义tags?在源文件开头的注释中,可以有多个build的定义,比如:
// +build linux
// +build amd64
也可以这么写
// +build linux,amd64
用逗号分隔表示的是“与”的逻辑,用空格分隔表示“或”的逻辑,看下面的例子:
// +build linux,cgo darwin,cgo
这表示在Linux或苹果的环境下,用cgo编译。
还有一点挺重要的要注意就是在注释之后一定要空一行。如果是想表示只要不在Windows环境下都可以编译,应该这么写:
// +build !windows
如果+build后面的tags是没有定义的,那么编译时会忽略,比如:
// +build abc
现在我们看看有那些tags是我们能填的,从官方文档可以看到以下选项:
- the target operating system, as spelled by runtime.GOOS
- the target architecture, as spelled by runtime.GOARCH
- the compiler being used, either "gc" or "gccgo"
- "cgo", if ctxt.CgoEnabled is true
- "go1.1", from Go version 1.1 onward
- "go1.2", from Go version 1.2 onward
- "go1.3", from Go version 1.3 onward
- "go1.4", from Go version 1.4 onward
- "go1.5", from Go version 1.5 onward
- "go1.6", from Go version 1.6 onward
- "go1.7", from Go version 1.7 onward
- "go1.8", from Go version 1.8 onward
- "go1.9", from Go version 1.9 onward
- "go1.10", from Go version 1.10 onward
- "go1.11", from Go version 1.11 onward
- "go1.12", from Go version 1.12 onward
- "go1.13", from Go version 1.13 onward
- "go1.14", from Go version 1.14 onward
- any additional words listed in ctxt.BuildTags
以文件命名后缀的方式
文件命名的方式比较简单,可以以下面几种形式的命名来条件编译:
*_GOOS //如:file_linux.go,表示只在Linux下编译
*_GOARCH //如:file_amd64.go,表示只在amd64下编译
*_GOOS_GOARCH //如:file_linux_amd64.go,表示只在Linux且amd64下编译
欢迎关注我的公众号:onepunchgo,给我留言。
以上是关于golang项目中使用条件编译的主要内容,如果未能解决你的问题,请参考以下文章
golang简明入门进阶指南01golang基础变量函数条件控制