golang项目中使用条件编译

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang项目中使用条件编译相关的知识,希望对你有一定的参考价值。

参考技术A

golang中没有类似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的条件编译

golang 条件编译

golang简明入门进阶指南01golang基础变量函数条件控制

golang简明入门进阶指南01golang基础变量函数条件控制

构建整个解决方案,但仅为一个项目添加全局条件编译符号

基于SQL Server版本的SQL CLR条件编译