Go的两种构建约束

743 阅读2分钟
什么是构建约束

构建约束也称之为条件编译,就是可以对某些源代码文件指定在特定的平台,架构,编译器甚至Go版本下面进行编译,在其他环境中会自动忽略这些文件

为什么需要构建约束呢

go是支持交叉编译的,也就是说,可以在linux平台编译生成windows下的可执行程序的;但是,有些API在不同的平台和架构中是不一样的,比如:

syscall.NewLazyDLL("test.dll")

加载dll的程序在Linux平台中就没有,所以当你写程序时就需要指定包含这个API的文件只能在Windows下面编译,在其他平台自动忽略,这样就不会代码移植到别的平台出现编译时错误了

golang支持的两种构建约束
  1. 使用文件后缀进行约束

    这种方式就是通过文件的后缀名来对要指定平台的编译的文件进行约束,文件格式如下:

    sourcefilename_GOOS_GOARCH.go
    

    上面的格式就是文件名_系统名_架构名.goGOOSGOARCH可以通过go env看到,也可以在环境变量中指定;下面举个例子:

    user_windows_amd64.go  //在 windows 中 amd64 架构下才会编译,其他的环境中会自动忽略
    user_linux_arm.go     // 在 linux 中的 arm 架构下才会编译,其他环境中会自动忽略
    
  2. 通过代码文件中添加注释进行约束

    该方式就是通过在代码文件中的第一行添加注释来标明该文件是否参与该上下文环境的编译,比如:

    // +build linux,amd64  package user
    ​
    func User(){}
    

    注释编译首先就是在文件头部添加注释 // +build 然后后面添加编译条件,该注释要和下面的代码空一行,否则就会被作为普通的注释对待;当然,也可以使用如下的注释

    //go:build linux,amd64
    

    这两种注释的区别在于前者可以存在多个,比如:

    // +build linux
    // +build amd64
    

    它们两个之间是“与”的关系,即linux && amd64;而 //go:build这种注释在同一个文件当中只能存在一行

    注释支持五种已有的标签,有:

    1. 操作系统,环境变量中GOOS的值,如:linux、darwin、windows等等
    2. 操作系统的架构,环境变量中GOARCH的值,如:arch64、x86、i386等等
    3. 使用的编译器,如:gc或者gccgo,是否开启CGO,cgo
    4. golang版本号,如:Go Version 1.5, Go Version 1.13,以此类推
    5. 自定义标签,这种标签就需要在编译时指定,如:通过 go build -tags 自定义tag名称 指定tag值
    6. // +build ignore,编译时自动忽略该文件

    标签之间有如下几种运算关系:

    空格表示:AND 
    逗号表示:OR 
    !表示:NOT 
    换行表示:AND
    

    比如:

    // +build linux,386 darwin,!cgo 
    运算表达式为:(linux && 386) || (darwin && !cgo)