Skip to content

Instantly share code, notes, and snippets.

@jouyouyun
Last active April 18, 2018 06:18
Show Gist options
  • Save jouyouyun/a0a0a05b239e3cc2aa24 to your computer and use it in GitHub Desktop.
Save jouyouyun/a0a0a05b239e3cc2aa24 to your computer and use it in GitHub Desktop.
Golang Condition Compile

GoLang Condition Compile

最近因为要支持其它平台, 但那个平台的电源管理做的不完全, 电池的状态不能通过 upower 获取到, 只能通过读文件来得到. 开始的时候是通过 patch 的方式来处理这个问题的, 就是每次在编译那个平台的程序时都会先打上这个 patch.

这种方式一来编译麻烦, 二来如果以后代码更新了, 就又需要更新 patch 了, 不方便代码维护, 所以开始查找 Go 条件编译的相关方法. 结果发现 Go 本身并不支持条件编译, 它只支持 tags 和文件名后缀的方式, 这两种方法的使用参考: Go Buildvarding . 继续了解后发现可以在 build 时通过 ldflags -X importpathg.variable=xxx 的方式传变量的值到程序中, 这种方式经测试后可以满足需求. 下面就简单介绍下这三种方式:

TAGS

tags 就是在文件开头加入 // +build TAGS, 在编译时编译器会自动处理, 例如:

// +build !linux

package main

func main() {
        fmt.Println("Not in linux system")
}

这段代码就只会在非 linux 下被编译, 其中 build 后面一定要有空行, 不然就会被当成注释.

文件后缀

如某段代码只希望在 windows 上执行, 就可以把这段代码放到名为 xxx_windows.go 的文件中, 这样编译器就会自动处理了.

LDFLAGS

go build 时加上 -ldflags 参数就可以传递变量值到指定的 package 中, 用法如下:

# 其中 'importpackage' 是变量所在的 'package' 名,相对路径无效,可能不支持吧
# 'variable' 则是指定的全局变量
go build -ldflags "-X importpackage.variable=xxx"

一个简单的例子如下:

test.go

package main

import (
        "fmt"
)

var (
        PLATFORM = "unknown"
        VERSION  = "1.0"
)

func main() {
        fmt.Println("Platform:", PLATFORM)
        fmt.Println("Version:", VERSION)
}

未指定变量的运行结果:

wen@Yun Test/condition-compile  (develop)->go build test.go
wen@Yun Test/condition-compile  (develop)->./test
Platform: unknown
Version: 1.0
wen@Yun Test/condition-compile  (develop)->

指定变量编译及运行结果:

wen@Yun Test/condition-compile  (develop)->go build -ldflags "-X main.PLATFORM=alpha_sw -X main.VERSION=0.5" test.go
wen@Yun Test/condition-compile  (develop)->./test
Platform: alpha_sw
Version: 0.5
wen@Yun Test/condition-compile  (develop)->

Go 的条件编译就介绍到这儿了, 若有错误之处, 欢迎指正.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment