Go 支持按照条件编译,具体来说它是通过 go/build包 里定义的tags和命名约定来让Go的包可以管理不同平台的代码 。

我们这里以下面这个开源项目为例,来看Go的按条件编译, 这个开源项目是把Go的os包进行了扩展。

https://bitbucket.org/kardianos/osext/src 

 

osext 是获得当前执行程序的执行目录和文件信息。

执行情况如下:

 

查看编译文件

我们用go list来查看在当前平台下 os/exec包里有哪些文件将会被编译

看当前项目下,有哪些文件会被编译,命令如下:

这里的 {{.GoFiles}} 是text/template里的模板代码

 

go list 命令的信息如下:
查看包名、路径、依赖项等等信息。
参数:
-json: 使用 json 格式输出包的相关信息,包括下面的依赖和导⼊。
-f{{.Deps}}: 查看依赖包,包括直接或间接依赖。
-f{{.Imports}}: 查看导入的包。

 

D:\mycodes\golang\src\bitbucket.org\kardianos\osext>go list -f
flag needs an argument: -f
usage: list [-e] [-f format] [-json] [build flags] [packages]

List lists the packages named by the import paths, one per line.

The default output shows the package import path:

    code.google.com/p/google-api-go-client/books/v1
    code.google.com/p/goauth2/oauth
    code.google.com/p/sqlite

The -f flag specifies an alternate format for the list, using the
syntax of package template.  The default output is equivalent to -f
'{{.ImportPath}}'. The struct being passed to the template is:

    type Package struct {
        Dir           string // directory containing package sources
        ImportPath    string // import path of package in dir
        ImportComment string // path in import comment on package statement
        Name          string // package name
        Doc           string // package documentation string
        Target        string // install path
        Goroot        bool   // is this package in the Go root?
        Standard      bool   // is this package part of the standard Go library?

        Stale         bool   // would 'go install' do anything for this package?

        Root          string // Go root or Go path dir containing this package

        // Source files
        GoFiles        []string // .go source files (excluding CgoFiles, TestGoF
iles, XTestGoFiles)
        CgoFiles       []string // .go sources files that import "C"
        IgnoredGoFiles []string // .go sources ignored due to build constraints
        CFiles         []string // .c source files
        CXXFiles       []string // .cc, .cxx and .cpp source files
        MFiles         []string // .m source files
        HFiles         []string // .h, .hh, .hpp and .hxx source files
        SFiles         []string // .s source files
        SwigFiles      []string // .swig files
        SwigCXXFiles   []string // .swigcxx files
        SysoFiles      []string // .syso object files to add to archive

        // Cgo directives
        CgoCFLAGS    []string // cgo: flags for C compiler
        CgoCPPFLAGS  []string // cgo: flags for C preprocessor
        CgoCXXFLAGS  []string // cgo: flags for C++ compiler
        CgoLDFLAGS   []string // cgo: flags for linker
        CgoPkgConfig []string // cgo: pkg-config names

        // Dependency information
        Imports []string // import paths used by this package
        Deps    []string // all (recursively) imported dependencies

        // Error information
        Incomplete bool            // this package or a dependency has an error
        Error      *PackageError   // error loading package
        DepsErrors []*PackageError // errors loading dependencies

        TestGoFiles  []string // _test.go files in package
        TestImports  []string // imports from TestGoFiles
        XTestGoFiles []string // _test.go files outside package
        XTestImports []string // imports from XTestGoFiles
    }

The template function "join" calls strings.Join.

The template function "context" returns the build context, defined as:

        type Context struct {
                GOARCH        string   // target architecture
                GOOS          string   // target operating system
                GOROOT        string   // Go root
                GOPATH        string   // Go path
                CgoEnabled    bool     // whether cgo can be used
                UseAllFiles   bool     // use files regardless of +build lines,
file names
                Compiler      string   // compiler to assume when computing targ
et paths
                BuildTags     []string // build constraints to match in +build l
ines
                ReleaseTags   []string // releases the current release is compat
ible with
                InstallSuffix string   // suffix to use in the name of the insta
ll dir
        }

For more information about the meaning of these fields see the documentation
for the go/build package's Context type.

The -json flag causes the package data to be printed in JSON format
instead of using the template format.

The -e flag changes the handling of erroneous packages, those that
cannot be found or are malformed.  By default, the list command
prints an error to standard error for each erroneous package and
omits the packages from consideration during the usual printing.
With the -e flag, the list command never prints errors to standard
error and instead processes the erroneous packages with the usual
printing.  Erroneous packages will have a non-empty ImportPath and
a non-nil Error field; other information may or may not be missing
(zeroed).

For more about build flags, see 'go help build'.

For more about specifying packages, see 'go help packages'.

 

编译标签

 

在源代码里添加标注,通常称之为编译标签( build tag) ,编译标签是在尽量靠近源代码文件顶部的地方用注释的方式添加
go build在构建一个包的时候会读取这个包里的每个源文件并且分析编译便签,这些标签决定了这个源文件是否参与本次编译

编译标签添加的规则(附上原文):

  1. a build tag is evaluated as the OR of space-separated options
  2. each option evaluates as the AND of its comma-separated terms
  3. each term is an alphanumeric word or, preceded by !, its negation
  • 编译标签由空格分隔的编译选项(options)以"或"的逻辑关系组成
  • 每个编译选项由逗号分隔的条件项以逻辑"与"的关系组成
  • 每个条件项的名字用字母+数字表示,在前面加!表示否定的意思

比如  https://bitbucket.org/kardianos/osext/src   这里的 osext_procfs.go 文件头上的 +build 部分就是。

这里标示 linux netbsd openbsd solaris 这些操作系统下会编译这个文件。

更复杂的编译标签 可以参考: http://blog.csdn.net/varding/article/details/12675971 

 

 

 

文件后缀

这个方法通过改变文件名的后缀来提供条件编译,这种方案比编译标签要简单,go/build可以在不读取源文件的情况下就可以决定哪些文件不需要参与编译

文件命名约定可以在go/build 包里找到详细的说明,简单来说如果你的源文件包含后缀:_$GOOS.go,那么这个源文件只会在这个平台下编译,_$GOARCH.go也是如此。这两个后缀可以结合在一起使用,但是要注意顺序:_$GOOS_$GOARCH.go,    不能反过来用:_$GOARCH_$GOOS.go

比如  https://bitbucket.org/kardianos/osext/src 这里的文件就是这个规则

osext_plan9.go        只会在 plan9 中编译。

osext_windows.go   只会在windows下编译。

 

更多请参考: http://blog.csdn.net/varding/article/details/12675971 

 

参考资料:

使用go build 进行条件编译
http://blog.csdn.net/varding/article/details/12675971

Go按照条件编译的更多相关文章

  1. C# 条件编译

    本文导读: C#的预处理器指令从来不会转化为可执行代码的命令,但是会影响编译过程的各个方面,常用的预处理器指令有#define.#undef.#if,#elif,#else和#endif等等,下面介绍 ...

  2. C#-#define条件编译

    本文导读: C#的预处理器指令从来不会转化为可执行代码的命令,但是会影响编译过程的各个方面,常用的预处理器指令有#define.#undef.#if,#elif,#else和#endif等等,下面介绍 ...

  3. 条件编译#if

    1.为什么需要条件编译 客户的需求在不停地发生变化,一会儿需要这个功能,一会儿不需要这个功能.我们可以使用条件编译来方便地裁剪功能. 2.条件编译语句#if 条件编译语句#if的形式是 #if exp ...

  4. 条件编译#if #ifdef

    近期由于一些莫名其妙的原因开始学c++,我觉得我哪天要是挂了也是被自己给折腾死的,算了,反正不是折腾死就是被淘汰,当是没事打发时间了,废话不多说,开始今天的主题. 之前接触的注释就是注释,条件语句就是 ...

  5. [AIR] as3 之条件编译多平台妙用

    http://bbs.9ria.com/thread-418864-1-1.html 一直希望as3 可以支持条件编译,即满足A时编译函数1,满足B时则编译函数2. 最佳百度了之后,发现原来是可以实现 ...

  6. 认识Visual Studio 条件编译

    一开始是在一些源代码中看到这些语法符号,了解到这就是" 条件编译"技术

  7. C# 条件编译备忘

    第一步:配置管理器中新建解决方案配置 第二步:定义条件编译符号: 第三步:在代码中使用自定义的条件编译 #if CustomDebug Console.WriteLine("dsads&qu ...

  8. Java条件编译

    学习过C语言或者C++语言的同学都知道它们支持条件编译,那么今天我们来学习下在Java语言中如何实现条件编译.Java语言本身没有提供条件编译,但是Java编译器对.java文件编译为.class文件 ...

  9. c#定义全局条件编译符号

    在"工程"上单机右键,"属性"--->"生成"--->"条件编译符号"后边的输入框中,输入自定义的条件编译变 ...

  10. 如何判断平台工具集去做条件编译(VC++目录、预处理器定义、$(PlatformToolsetVersion))

    作者:zyl910 从VS2010开始,提供了一个平台工作集(Platform ToolSet)选项用于配制vc编译版本.到了VS2012,更是因为默认平台工具集不支持WindowsXP,导致经常需要 ...

随机推荐

  1. jzoj3511

    设f[i][j][k] 表示第i行状态为j i+1行将要被放为状态k的最优解 每次枚举这行和上一行的状态来dfs,注意细节 不合法的状态会直接被赋值成为inf

  2. Python FLask Web 学习笔记:jinjia2的使用方法1

    # coding:utf-8 from jinja2 import Template x = """ <p>大爷的孙子</p> <ul> ...

  3. robot framework接口测试之一-完整的测试用例

    *** Settings *** Library Collections Library json Library requests Library RequestsLibrary Library H ...

  4. JAVA数组的遍历和取最值

    1.获取数组中的所有元素,会用到数组的遍历 数组的遍历,通常用for循环. public class ArrayDemo { public static void main(String[] args ...

  5. Security-OAuth2.0 密码模式之客户端实现

    我的OAuth2.0 客户端项目目录 pom 的配置 <?xml version="1.0" encoding="UTF-8"?> <proj ...

  6. 使用TortoiseSVN客户端管理IntelliJ IDEA项目的方法

    使用TortoiseSVN客户端管理IntelliJ IDEA项目的方法 今天在打开一个使用SVN管理的项目时,IntelliJ IDEA提示: Can't use Subversion comman ...

  7. 关于Hibernate的一个简单小程序

    本人根据视频学习了一下三大框架中比较简单的一个Hibernate,并简单完成了一个运用Hibernate的小程序 Hibernate是一个简化web程序Dao层的一个框架,应用他,可以完全脱离sql语 ...

  8. CUDA安装

    1.CUDA是什么? CUDA(Compute Unified Device Architecture),显卡厂商NVidia推出的运算平台. 随着显卡的发展,GPU越来越强大,而且GPU为显示图像做 ...

  9. jmeter的non-gui模式的使用

    jmeter的non-gui模式的使用,待补充

  10. IntelliJ IDEA 2018.3(Ultimate Edition)激活方法

    本因博主Windos10系统上IDEA 2017会出现自带输入法候选框不跟随光标的问题,故更新了IntelliJ IDEA 2018,当时官方发布虽然还是Beta版本,但是迫于输入中文累死眼睛的窘态下 ...