Skip to content

proposal: cmd/go: record default build tags in go.mod #43288

@arp242

Description

@arp242

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:

$ go build -tags=sqlite_json

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:

module test

go 1.13

tags osusergo netgo sqlite_omit_load_extension sqlite_json

require (
	github.com/mattn/go-sqlite3 v1.14.5
)

In this example it also adds osusergo, netgo, and sqlite_omit_load_extension to avoid dynamic linking, which is probably another common use case. Right now people often use CGO_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 the go.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 different tags directives? It probably makes the most sense to only look at this for the main project you're building, and ignore tags directive from dependencies.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions