我可以根据我正在构建的 OS 导入 Golang 包吗?

Can I import a Golang package based on the OS I'm building for?

假设我有一个基于 OS 的 go 项目,在某些情况下是哪个发行版,我想使用 Systemd 客户端包与 Upstart 客户端包与 sysv 客户端包与 launchd客户端包。是否可以有选择地导入每个包,以便我只导入我正在构建的 OS/distro 我需要的包?还是我必须为每个 OS/distro 导入每个包?

Package build

Build Constraints

A build constraint, also known as a build tag, is a line comment that begins

// +build

that lists the conditions under which a file should be included in the package. Constraints may appear in any kind of source file (not just Go), but they must appear near the top of the file, preceded only by blank lines and other line comments. These rules mean that in Go files a build constraint must appear before the package clause.

To distinguish build constraints from package documentation, a series of build constraints must be followed by a blank line.

A build constraint is evaluated as the OR of space-separated options; each option evaluates as the AND of its comma-separated terms; and each term is an alphanumeric word or, preceded by !, its negation. That is, the build constraint:

// +build linux,386 darwin,!cgo

corresponds to the boolean formula:

(linux AND 386) OR (darwin AND (NOT cgo))

A file may have multiple build constraints. The overall constraint is the AND of the individual constraints. That is, the build constraints:

// +build linux darwin
// +build 386

corresponds to the boolean formula:

(linux OR darwin) AND 386

During a particular build, the following words are satisfied:

- the target operating system, as spelled by runtime.GOOS
- the target architecture, as spelled by runtime.GOARCH
- the compiler being used, either "gc" or "gccgo"
- "cgo", if ctxt.CgoEnabled is true
- "go1.1", from Go version 1.1 onward
- "go1.2", from Go version 1.2 onward
- "go1.3", from Go version 1.3 onward
- "go1.4", from Go version 1.4 onward
- "go1.5", from Go version 1.5 onward
- "go1.6", from Go version 1.6 onward
- any additional words listed in ctxt.BuildTags

If a file's name, after stripping the extension and a possible _test suffix, matches any of the following patterns:

*_GOOS
*_GOARCH
*_GOOS_GOARCH

(example: source_windows_amd64.go) where GOOS and GOARCH represent any known operating system and architecture values respectively, then the file is considered to have an implicit build constraint requiring those terms (in addition to any explicit constraints in the file).

To keep a file from being considered for the build:

// +build ignore

(any other unsatisfied word will work as well, but “ignore” is conventional.)

To build a file only when using cgo, and only on Linux and OS X:

// +build linux,cgo darwin,cgo

Such a file is usually paired with another file implementing the default functionality for other systems, which in this case would carry the constraint:

// +build !linux,!darwin !cgo

Naming a file dns_windows.go will cause it to be included only when building the package for Windows; similarly, math_386.s will be included only when building the package for 32-bit x86.

Using GOOS=android matches build tags and files as for GOOS=linux in addition to android tags and files.

使用构建约束。

使用包含多个文件的单个包。每个文件专门用于特定的 OS、体系结构等组合。

A build constraint is evaluated as the OR of space-separated options; each option evaluates as the AND of its comma-separated terms; and each term is an alphanumeric word or, preceded by !

实际上,这会改变 with Go 1.17(2021 年第 3 季度)

//go:build lines

The go command now understands //go:build lines and prefers them over // +build lines.

The new syntax uses boolean expressions, just like Go, and should be less error-prone.

As of this release, the new syntax is fully supported, and all Go files should be updated to have both forms with the same meaning.
To aid in migration, gofmt now automatically synchronizes the two forms.
For more details on the syntax and migration plan, see https://golang.org/design/draft-gobuild.

来自设计文档:

The core idea of the design is to replace the current // +build lines for build tag selection with new //go:build lines that use more familiar boolean expressions.

For example, the old syntax

// +build linux
// +build 386

would be replaced by the new syntax

//go:build linux && 386