On Wed, Feb 19, 2025 at 9:36 AM 'Bushnell, Thomas' via golang-nuts
<[email protected]> wrote:
>
> The module https://github.com/confluentinc/confluent-kafka-go takes advantage
> of a custom build tag to change its behavior. (Specifically, the “dynamic”
> build tag forces it to use a dynamic shared library -lrdkafka instead of a
> built-in one; this is needed sometimes because the built-in one does not
> support GSSAPI/Kerberos, while the dynamic one might [and on Linux distros,
> generally does].)
>
>
>
> Suppose I am writing my own package foo which uses confluent-kafka-go under
> the hood to implement functionality, and I require the “dynamic” behavior
> from confluent-kafka-go. My package must then in turn tell its users that
> they must build their application with the “dynamic” build tag. This in turn
> propagates arbitrarily far; as well, it is easy for it to become stale
> (suppose Confluent changes the behavior of their module to no longer use this
> build tag—then all these transitive users will still have a “dynamic” build
> tag perhaps annoyingly hanging around for a long time).
>
>
>
> Notice that the “dynamic” build tag goes together with linking with
> -lrdkafka, but that can be specified once, in the code close to the
> confluent-kafka-go package, rather than in an unbounded set of transitive
> reverse dependencies.
>
>
>
> Relatedly, there is nothing to prevent some unrelated package from also
> changing its behavior based on the “dynamic” build tag, and applications in
> general may want the altered behavior from confluent-kafka-go but not from
> some unrelated package—which may even be obscure or entirely unknown.
>
>
>
> I think there are several solutions to this difficulty; one might be a way to
> say in the go.mod file that a direct dependency should be built with a
> particular build tag, so that the application of the tag can be applied only
> to a portion of the build and not the whole. (This still leaves the
> possibility that a module might be used by two separate parts of a build, one
> with the tag and one without; this is fundamentally no different than a
> version conflict, but it might have some implications for other parts of the
> build system I haven’t considered.)
>
>
>
> I think it’s obvious that it would be better for Confluent not to have built
> their tooling this way, but here we are. Any use of a non-standard custom
> build tag in a generally imported module has this problem, so I think it’s
> important to solve for the Go ecosystem; if the feature really is “don’t use
> this feature” then arguably the feature should be abandoned. If it’s to be
> kept as a feature, then there should be some way to use it safely.
Hi Thomas. I think the issue here is that build tags are basically a
global mechanism. They work OK as long as they are describing
something that applies across the entire program. Besides the standard
build tags, this includes popular semi-standardized tags like purego.
Package-specific build tags don't really work. I guess I'm saying
"don't use this feature," at least not in this way.
The standard library does have at least some package-specific build
tag, but at least it puts the package name in the build tag name, like
netgo, netcgo, timetzdata.
Given where we are today, my best suggestion for a package that
requires an imported package to use a build tag would be something
like
package mypackage
//go:build !dynamic
func init() {
log.Fatal("program must be built with -tags=dynamic")
}
I agree that that is really not satisfactory.
Ian
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVKxPG%2BO_89YAv0rOaCDBrNPJLeKS2Bagniux_Y6dtJhw%40mail.gmail.com.