Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude go source files by architecture when compiling

Tags:

compilation

go

I am writing a Go program for Windows which contains several packages. One of these packages is using CGo to call a few functions defined in some .h and .c files. These .c files are dependent on windows.h .

Since developing on the Windows platform is incredibly tedious I would like to make a mockup of the functions in this file and develop on Linux instead. But when I try to compile I get:

fatal error: windows.h: No such file or directory

Since the go tool tries to compile my Windows dependent files. Is there some way around this? I know that putting something like

#ifdef ..
import x
#endif

is not best practice but in this case I need something to allow compiling only the "Linux" files.

like image 793
Johan Wikström Avatar asked Sep 02 '13 11:09

Johan Wikström


People also ask

What is GOOS in go?

GOOS=windows go build.

Does go compile to binary?

To complete the list, go run compiles your application into a temporary folder, and starts that executable binary. When the app exits, it properly cleans up the temporary files.


1 Answers

Quoting from the build constraints documentation:

A build constraint is a line comment beginning with the directive +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.

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
  • 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) or the literals:

GOOS
GOARCH

(example: windows.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.

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.

like image 176
zzzz Avatar answered Oct 21 '22 07:10

zzzz