Using Go build for conditional compilation

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

When we write a go code that relies on a specific platform or CPU architecture, we need to give different implementations

C language has a preprocessor that can be compiled by macro or # define containing code specified by a specific platform

But go does not have a preprocessor, and he is using tags and naming conventions defined in the Go/build package to allow go packages to manage code for different platforms

This article will tell you how the conditional compilation system for Go is implemented, and illustrates how to use the

1. Preliminary knowledge: The use of the Go List command

Need to understand the simple usage of Go list before speaking conditional compilation

Go list accesses the data structures within the source file that can affect the compilation process

Go list and go build, Test,install most of the parameters are the same, but go list does not perform the compilation operation. Using the-f parameter allows us to provide the code in the text/template containing the go/build. The package context is executed correctly (that is, let go/build. The context in the package is formatted with this format ' {{. text/template. Gofiles}} ' in the placeholder, the classmate who wrote the HTTP server program should be familiar with it.

Using the format parameter, we can get the file name that will be compiled via go list

    1. % Go list-f ' {{. Gofiles}} ' Os/exec
    2. [Exec.go Lp_unix.go]

In this example, we use Go list to see which files in the Os/exec package will be compiled under the Linux/arm platform.

The results show that exec.go contains common code that is available on all platforms, and Lp_unix.go contains the exec in the *nix system. Lookpath

Running the same command under Windows System results in the following:

    1. C:\go> Go list-f ' {{. Gofiles}} ' Os/exec
    2. [Exec.go Lp_windows.go]

The above example is the two part of the Go Conditional compilation system, which is called: Compile constraints, which are described in detail below

2. First conditional compilation method: Compile label

Add annotations to the source code, often referred to as compilation tags (build tag)

The compilation tag is added as a comment as close as possible to the top of the source code file

Go build reads each source file in the package while building a package and parses the compiled note, which determines whether the source file participates in this compilation

Add rules for compiling tags (attach original text):

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. Alphanumeric word or, preceded by!, it negation

1). The compilation tab consists of a space-delimited compilation option (options) with a logical relationship of "or"

2). Each compilation option consists of a comma-delimited list of conditional items in a logical "and" relationship

3). The name of each condition item is denoted by the letter + number, in front Plus! means negative.

Example (compile tags to be placed at the top of the source file)

    1. +build Darwin FreeBSD NetBSD OpenBSD

This will allow the source file to be compiled only in the BSD system that supports Kqueue.

A source file can have more than one compilation tag, the relationship between multiple compiled tags is logical "and"

    1. +build Linux Darwin
    2. +build 386

This will restrict this source file to be compiled only on linux/386 or darwin/386 platforms.

Notes about annotations

Starting with a compile tag often makes the following error

    1. +build!linux
    2. Package mypkg//Wrong

In this example, there is no blank line between the compiler tag and the package declaration, so that the compilation tag is ignored as a comment on the package declaration rather than a compile tag.

The following is the correct way to write the label, add a blank line at the end of the label so that the label does not comment on the other statement

    1. +build!linux
    2. Package mypkg//correct

The Go Vet command also detects this missing blank line error, which can be used initially to avoid missing empty rows.

    1. % Go vet mypkg
    2. Mypkg.go:1: +build comment appears too late in file
    3. Exit Status 1

As a reference, the following example puts licence declaration, compile label and package declaration together, please pay attention to distinguish

    1. % Head Headspin.go
    2. Copyright Enterprises. All rights reserved.
    3. Use of this source code was governed by a Bsd-style
    4. License that can is found in the license file.
    5. +build Someos Someotheros Thirdos,!amd64
    6. Package Headspin implements calculates numbers so large
    7. They'll make your head spin.
    8. Package Headspin


3. Second conditional compilation method: File suffix

This method provides conditional compilation by changing the suffix of the file name, which is simpler than compiling the tag, and Go/build can decide which files do not need to participate in the compilation without reading the source file.

File naming conventions can be found in the Go/build package detailed instructions, simply say if your source file contains the suffix: _$goos.go, then the source file will only be compiled under this platform, _$goarch.go. The two suffixes can be used together, but note the order: _$goos_$goarch.go, cannot be reversed with: _$goarch_$goos.go

Examples are as follows:

    1. Mypkg_freebsd_arm.go//Only builds on freebsd/arm systems
    2. Mypkg_plan9.go//Only builds on Plan9

The source file cannot provide only conditional compilation suffixes, and must also have a file name:

    1. _linux.go
    2. _freebsd_386.go

These two source files are ignored on all platforms because Go/build will ignore all source files with the following underscore or dot

4. Compilation of tags and file suffix selection

There is overlap in the functionality of the compiled label and the file suffix, such as a file name: Mypkg_linux.go contains//+build Linux will appear redundant

Typically, if the source file matches the platform or CPU architecture exactly, use the file suffix, for example:

    1. Mypkg_linux.go//Only builds on Linux systems
    2. Mypkg_windows_amd64.go//builds on Windows 64bit platforms

Conversely, if the source file can be used on more than one platform or more than one CPU architecture, or if the specified platform needs to be removed, then compile tags, such as the following compile tags, can be compiled on all *nix platforms:

    1. % grep ' +build ' $HOME/go/src/pkg/os/exec/lp_unix.go
    2. +build Darwin Dragonfly FreeBSD Linux NetBSD OpenBSD

Below is a compilation that can be compiled on all platforms except Windows

    1. % grep ' +build ' $HOME/go/src/pkg/os/types_notwin.go
    2. +build!windows

5. Summary

This article focuses on all go source files that can be compiled by the Go tool, compiling tags and file suffix names (also including. C and. s files)

The Go standard library contains a number of examples, especially Runtime,syscall,os and net packages, that readers can use to learn from these packages.

The test file also supports compiling tags and file suffix conditional compilation, and works the same way as the go source file. There are some test samples that can be conditionally included under different platforms. Also, the standard library contains a number of examples

Finally, this document is about how to use the Go tool to achieve conditional compilation, but conditional compilation is not limited to go tool, you can use the Go/build package to write your own conditional compilation tool

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.