-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
proposal: cmd/go: record default build tags in go.mod #43288
Comments
I think we've fairly consistently said that we aren't going to put build configurations into go.mod. That's not what it's for. In particular it wouldn't make sense to do so for anything other than a main package. |
Do you have any other ideas on how to solve this particular problem @ianlancetaylor, or do you not think it's a big enough problem worth solving and that "do nothing" is the best solution? Thinking again, go.mod may actually not be the best location – at least not with the syntax in the example – as At any rate, it's a problem I've run in to on various occasions, and IMO it's something that can probably be improved in some way – I don't really care about the exact method as such. |
how about a new file |
The go command is not a complete build system that can handle all different cases. It's a real problem, and perhaps someday Go will provide a real solution, but today it does not. So my current recommendation would be using a shell script to build your program. |
This seems like a duplicate of #42343. Please see the discussion there. |
Any assumption of specific build tags break the ease-of-use of “ |
That's why we have |
Yeah, I read that (and #39005, which is even more similar) but I don't either are really a duplicate as this is much more limited. I don't think having complete build configuration is really necessary, but build tags are different as they can affect the runtime behaviour of a program, and can be viewed as a "dependency" of a program. This is different from some convenience shortcuts to build on your program on Windows or omitting debug symbols in your binary: these don't affect the control flow of your program. There are some other flags to do this, but they're comparatively obscure are rarely needed to correctly build a program.
They can't propagate up (i.e. from a dependency to main), but that's okay; it's about propagating down to dependencies which have build tags to change the behaviour (such as the |
That seems like it would be better addressed by making the JSON functionality a separate importable Go package — for example, by compiling the JSON extension as a separate library and statically linking it into the binary as described in https://www.sqlite.org/loadext.html#statically_linking_a_run_time_loadable_extension. But that's a separate issue that you should probably take up as an issue in the |
I would argue that that is an abuse of build tags. Build tags should change the implementation or optimization of a program (as in the case of |
Thanks; I'll have to look at that; I solved it in the meantime by just maintaining a "fork" (it's just a single This indeed isn't the best use of build tags; I see your point, but sometimes alternatives are hard, especially when you're interfacing with third-party stuff. To be honest I don't know how common this pattern is (and not something that's easy to grep for). |
Oh, absolutely! But before we go too far down the build-tag route, I would like to better understand what it is that makes those alternatives hard, and whether we can address that difficulty more directly. I'm guessing that in this case a lot of the difficulty comes from the C linking model and/or the interaction between If anything, the fact that the package is provided by a third party makes it more important not to rely on build tags: we have a mechanism (MVS) to reconcile differences in package-import requirements across modules, but no such mechanism to reconcile differences in build tags. |
Yes, that makes perfect sense; above all this is a "I this problem that I believe is hard to solve, and I propose we see if there's a way to solve it"-kind of proposal. I probably could have written the proposal better instead of focusing too much on a specific mechanism, but ah well. The way it works now is like this;
And then files such as
From a user perspective, one nice way to get this might be to put this in
But the Similarly, there is also no way that I can do something like this in
Or something like that (you can add it via CFLAGS, but then we're back to where we started). The "Statically Linking A Run-Time Loadable Extension" SQLite docs begins with "simply add the -DSQLITE_CORE compile-time option" – but that's not really all that simple. Any package modifying any build flag for anything else would not be the best of ideas, but I wonder if there isn't a limited way to give a little bit more flexibility with this, such as subpackages being able to add to the CFLAGS of their parent, a main package being able to define CFLAGS, or something else entirely. I don't know what the ramifications of that would be from a compiler internals perspective though. |
I agree that it's not really all that simple, but I still suspect that most or even all of the complexity can be encapsulated within the The first approach I would investigate would be something like:
Then a Go consumer can indicate which extensions to link (and initialize) by importing (or blank-importing) specific packages, rather than setting build tags, and Go libraries that each need different SQLite extensions without the maintainer of the resulting binary needing to set any build tags explicitly. |
This does appear to be a duplicate of #42343. |
Duplicate of #42343 |
I have a project which depends on https://github.com/mattn/go-sqlite3. I'd like to use SQLite's JSON extensions, which requires settings the
sqlite_json
build tag:In my opinion, having to specify this for every build invocation is not very good UX, either for myself or for $random_users of my program.
There are no real good solutions for this as far as I can find:
A wrapper Makefile or shell script isn't too hard, but it breaks the ease-of-use of "go build will always build your project", may be hard to get working fully correct on all platforms, and adds an external dependency (I don't typically have
make
installed, as I don't really need it).It works, but "
go build
always correctly builds your project" seems like a worthwhile behaviour to have.I can fork the go-sqlite3 repo, modify it to remove the build constraints, and add
replace github.com/mattn/go-sqlite3 => example.com/mysqlite
in go.mod, but keeping this updated and maintained is some amount of work.Previously there wasn't really any place to specify these kind of things, but now that we have a
go.mod
it's something that could potentially be added there; for example:In this example it also adds
osusergo
,netgo
, andsqlite_omit_load_extension
to avoid dynamic linking, which is probably another common use case. Right now people often useCGO_ENABLED=0 go build
for this.There are some previous proposals to make
go build
look at some build-time configuration (#39005, #42343) which have the problems of potential arbitrary code execution and large amount of complexity. This proposal is much more limited and only about build tags, which should avoid those problems.The
-tags
flag is somewhat special as it affects the control flow of the program and that any errors from using the wrong flags may not be seen at runtime (e.g. when using an SQL query with JSON functions), and can be seen as a "dependency" of a program. I think it may be worth thinking about tracking this "dependency" in thego.mod
file; I think it fits the purpose of the file without stuffing too much "cruft" in there.Open questions:
What to do if someone uses
go build -tags=othertag
? Do we merge the tags? Override the default ones?What if a dependency has a
tags
directive? What if two dependencies have differenttags
directives? It probably makes the most sense to only look at this for the main project you're building, and ignoretags
directive from dependencies.The text was updated successfully, but these errors were encountered: