-
Notifications
You must be signed in to change notification settings - Fork 17.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/tools/gopls: use cases for build tags #33389
Comments
I have used build tags in a library so that it only depends on stdlib by default but usage of 3rd party libraries like |
In TinyGo (which should eventually support IDEs), we use build tags to select various things:
To manage all this, special JSON files are used that can be selected with a single compiler flag (similar to GCC spec files). More uses may be added in the future. |
Build tags are commonly used for go generate - so that generators can be stored alongside the package in which they are used |
We have used build tags mainly in two places:
That being said, we don't use build tags very much. |
Two files, named something like
This way, we can run with the extra testing sometimes, but omit expensive tests entirely at compile time. (Some of the tests are inside hot loops, so being able to get rid of even the cost of the branch is actually relevant.) Have also used them for what would typically be #defines in C; functionality changes which are innately program-wide and must be resolved at compile time because array sizes (for instance) depend on them. I've seen a package (hajimehoshi/ebiten) ship with a number of examples in subdirectories, marked with |
I used build tags to add enhanced debugging that goes into tight loops. Using an if statement much like @seebs . One file id They each define a debug constant. then if I need to debug tight loops I'll eighter flip the const in This being said, this is probably not the best way to do this. |
In google.golang.org/protobuf:
|
We use build tags to separate the almost identical input and output files of Specifically, we have an input file that is valid Go code, and has a build tag
The code generator takes this file and spits out a nearly identical file with
The code generator (
The desired experience here is for users to code in the input file like it's a |
I use build tags to separate integration tests and examples (depending on external resources such as database) from unit tests (no external dependencies).
|
In the Tegola project we also use it select which features are enabled or not.
This is important as some environments that Tegola is deployed into they do not want all the features, and turning them off or not configuring it is not good enough. So, having the ability to compile them out is important. |
for building part of a program as a seperate binary. eg:part of a program parses some file, this would be used as an API by default, but with an alternate main file you can use the same codebase to build a parser(or any other modular thing) that would output to stdout or another file. I used something like this in a "bigger" project where the program also had to use some modules(not go modules) as external binary and communicate over std in/out. |
The gioui.org/ui/app package is like package os, but for GUI programs: it uses build tags to distinguish between GOOS. Some examples:
I also use the standard GOOS build tags in file names: os_js.go, gl_android.go, egl_windows.go etc. |
Just to expand on the WASM example from my persective. The typical setup is that a subpackage/subtree of packages within a module (a module that has both backend and frontend code) has a preferred build configuration, specifically |
Adding a separate comment about where this support for understanding the universe of build configurations for a module is required:
This list is likely incomplete |
The wire dependency injection tool uses
to prevent Go code used for configuration from being included in the actual build. |
Use of |
@breml - that's a particularly interesting example because such a file will never compile. |
I have used build tags to enforce that a package is being built with a particular version of Go: https://github.com/zombiezen/gg/blob/13b5a059c5addfa7543b2b572650d9544bfcb729/internal/git/force_go19.go This use case is likely obsolete now that the go.mod file includes language version information, but such code may exist out in the wild. Anecdotally, I most often use build tag (or the filename equivalent thereof) mechanisms in order to provide Unix-y and Windows equivalent functions. Happy to answer specifics about Wire's usage of build tags if needed, but the docs are a pretty good place to start understanding. From the perspective of gopls-like static analysis, it should be pretty similar to the OS-specific code use case in that the same symbols get redefined. |
Thanks all for your detailed replies! I will be working on compiling your answers into a document, and hopefully soon we'll be able to make some progress on supporting build tags in |
I teach and use Go for programming labs, and keep solutions and skeleton code for the students in the same folder to ensure consistency with common files and to remember to change both if necessary. I use I run tests using I then copy the skeleton code to a separate repo to share with the students. |
Build tags are crucial for projects that have open source and enterprise variants. |
gobbi, a package that provides bindings to GTK GUI toolkit, uses Go build tags to allow targeting of specific library versions. See here for more details. |
Thanks all for the detailed replies! This information will be very valuable as we continue work on #29202. Closing this issue in favor of that one. Please feel free to comment here if you have a different use case for build tags. |
I have one file with '// +build debug', and an almost identical file in the same folder with '// +build !debug'. gopls flagged every constant, variable and function as being redefined between the two files. The debug file just prints log messages to replace functions that make major changes to the running state of the system. |
What use cases do users have for build tags? Please post your own examples.
To start:
The text was updated successfully, but these errors were encountered: