When to use runtime.GOOS vs. build flags/file suffixes?

Skip to first unread message

Tom Payne

Apr 8, 2020, 7:13:27 PM4/8/20
to golang-nuts
Go allows OS-specific code to be selected two different ways, either using the runtime.GOOS constant or with file-level build tags like "//+build linux" or (equivalently) OS-specific source file suffixes like _linux.

What's the recommended way to decide when to use which?

As far as I can tell:
- There is no runtime advantage to either. runtime.GOOS is a constant, so the compiler eliminates any unreachable branches. File-level build tags mean that irrelevant files don't even reach the compiler. Either way, the irrelevant code is not included in the final binary and incurs no runtime cost.
- When using build tags, the fact that irrelevant code doesn't reach the compiler means that errors can creep in. For example, compile errors in foo_linux.go will be unnoticed if you only ever compile on Windows. In contrast, using runtime.GOOS will mean that compile errors are found whatever OS you compile on.
- Only build flags and OS-specific source file suffixes give you control over imports.

Therefore, it would seem that the recommendation of when to use runtime.GOOS vs. build flags/file suffixes is:
- Use runtime.GOOS unless you need OS-specific imports or your OS-specific code is so different that it really deserves to be in a separate source file.

Is this recommendation reasonable? What could be improved?


Ian Lance Taylor

Apr 8, 2020, 7:40:59 PM4/8/20
to Tom Payne, golang-nuts
What you say sounds right to me. I would just add that code that
tests runtime.GOOS a lot can be hard to follow. So another reason to
use a separate file is to avoid having to write a lot of potentially
confusing if statements.

Also I'll note that Go's cross-compilation support makes it
straightforward to write tests that ensure that OS-specific code
continues to compile. Ensuring that the code continues to work
correctly is admittedly more difficult.

Reply all
Reply to author
0 new messages