GO条件编译
go build 参数
| 附加参数 | 备注 |
|---|---|
| -v | 编译时显示包名 |
| -p n | 开启并发编译,默认情况下为CPU核数 |
| -a | 强制重新构建所有的文件 |
| -n | 打印编译时会用的所有命令,但不真正执行 |
| -x | 打印编译时会用到的所有命令 |
| -race | 开启竞态检测,支持linux/amd64,freebsd/amd64,darwin/amd64,windows/amd64 |
| -work | 打印临时工作目录的名称 |
| -o | 指定输出文件 |
| -tags | 构建出带tag的版本 |
| -gccgoflags | gccgo 编译/链接器参数(少用) |
条件编译方式一:编译标签
在源码添加标注,通常称之为编译标签(build tag),编译标签是在尽量靠近源代码文件顶部的地方用注释的方式添加,如下所示:
// +build darwin freebsd netbsd openbsd
这个将会让这个源文件只能在支持kqueue的BSD系统中编译
// +build linux darwin
// +build 386
// +build !linux
package main // <- it's wrong
// +build !linux
package main // <- it's right
条件编译方式二:文件后缀
这个方法通过改变文件名的后缀来提供条件编译,这种方案比编译标签要简单, go/build可以在不读取源文件的情况下就可以决定哪些文件不需要参与编译
_$GOOS.go_$GOARCH.go_$GOOS_$GOARCH.go
编译标签和文件后缀的选择
- 通常情况来讲,如果源文件与平台或者CPU架构完全匹配,那么用文件后缀
- 相反,如果这个源文件可以在超过一个平台/CPU架构下使用,或者去除指定平台,那么使用编译标签
CGO条件编译
CGO也可以使用上述GO的条件编译方式来进行条件编译。这里只针对与对于跨平台情况下需要链接不同的库的注释写法:
条件链接依赖库
先来看一段正常的cgo代码:
// #cgo CFLAGS: -DPNG_DEBUG=1 -I./include
// #cgo LDFLAGS: -L/usr/local/lib -lpng
// #include <png.h>
import "C"
#cgo
#cgo
#cgoCFLAGSCPPFLAGSCXXFLAGSFFLAGSLDFLAGSLDFLAGSCFLAGS
条件选择
#cgo
// #cgo windows CFLAGS: -DX86=1
// #cgo !windows LDFLAGS: -lm
// #cgo amd64 CFLAGS: -lpthread
// #cgo arm64 CFLAGS: -lpng
如上就是在不同操作系统预定义宏,链接不同库的操作。
#cgo
package main
/*
#cgo windows CFLAGS: -DCGO_OS_WINDOWS=1
#cgo darwin CFLAGS: -DCGO_OS_DARWIN=1
#cgo linux CFLAGS: -DCGO_OS_LINUX=1
#if defined(CGO_OS_WINDOWS)
const char* os = "windows";
#elif defined(CGO_OS_DARWIN)
const char* os = "darwin";
#elif defined(CGO_OS_LINUX)
const char* os = "linux";
#else
# error(unknown os)
#endif
*/
import "C"
func main() {
print(C.GoString(C.os))
}