Address Makefile issues around the cgo build #1446
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Ok y’all, I’m pulling something out of the rabbit hole here.
I’ve noticed an issue with the Makefile for step-ca, where we use the variable
GOFLAGS
.Actually, this has been confusing to me for a long time and I finally discovered why.
In the Makefile, we run, for example
$(GOOS_OVERRIDE) $(GOFLAGS) go build -v -o $(PREFIX)bin/$(BINNAME) $(LDFLAGS) $(PKG)
By default,
GOFLAGS
is set to the valueCGO_ENABLED=0
But if I run
make build GOFLAGS="CGO_ENABLED=1"
, I get:In this case,
GOFLAGS
is being used both by the Makefile (as go env variables) and by go itself (as “A space-separated list of -flag=value settings to apply to go commands by default”)So, then, how does the default case even work, since by default
GOFLAGS
is equal toCGO_ENABLED=0
, a non-flag?It works because by default
GOFLAGS
is set locally in the Makefile, and it won’t get exported to go as an env.The only valid value for
GOFLAGS
that satisfies both go and the Makefile is “”And this is the only value we use in automations and docs, because it creates a cgo build.
Or, it’s supposed to.
But sometimes it results in a non-cgo build.
Quick sideshow:
Normally, Go creates cgo binaries by default.
But (I think this is a recent change to Go), if
gcc
is not in$PATH
, it will silently not use cgo.So, the second issue is that our instructions for cgo builds might silently create a non-cgo build, as a user just encountered.
So we need to tell people to run make with
CGO_ENABLED=1
set explicitly.But there isn’t a way to do that. For some reason, make build
CGO_ENABLED=1
does not passCGO_ENABLED=1
to go.Bottom line:
GOFLAGS
should be calledGO_ENVS
CGO_ENABLED=1
if we want a cgo binary, so that whengcc
doesn't exist,go
will fail to compile instead of falling back to non-cgoGOFLAGS
should be reserved forgo
A couple backward-compatible options for getting out of this:
GOFLAGS
toGO_ENVS
to represent go build flags; and ifGOFLAGS
is passed in as""
, silently setGO_ENVS
toCGO_ENABLED=1
. Otherwise, default it toCGO_ENABLED=0
. This is what I did in this PR.GO_ENVS
, just acceptCGO_ENABLED=1
intomake
and export it togo
. IfGOFLAGS
is passed in as""
, silently setCGO_ENABLED=1
.Alternatively, we could make a breaking change and just update the docs and cgo-related automations.