Vendoring in Go 1.13+ probably doesn't work the way you expect, and neither do environment variables in Makefiles. If you maintain a Terraform provider, it's likely your vendor/
directory is being completely ignored during builds and releases.
Add this to the top of your Makefile/GNUMakefile:
.EXPORT_ALL_VARIABLES:
GOFLAGS=-mod=vendor
As of Go 1.13, the go
command runs in module mode by default. When in module mode, it completely ignores vendor/
directories (https://tip.golang.org/cmd/go/#hdr-Modules_and_vendoring).
To override this, use the -mod=vendor
flag on commands like go build
, or set GOFLAGS=-mod=vendor
in the environment.
Variables set in the standard way (FOO=bar
) at the top of Makefiles are not automatically exported to child processes, although they can be interpolated into commands run in that Makefile's targets.
Variables can be exported to child processes by setting the .EXPORT_ALL_VARIABLES
pseudo-target, as described in the manual:
https://www.gnu.org/software/make/manual/make.html#index-_002eEXPORT_005fALL_005fVARIABLES
Consider the following Makefile
:
.EXPORT_ALL_VARIABLES:
GOFLAGS=-mod=vendor
target:
go env | grep GOFLAGS
When make
is run, the following output will appear:
$ make
go env | grep GOFLAGS
GOFLAGS="-mod=vendor"
Now remove the .EXPORT_ALL_VARIABLES:
line. Run make
again:
$ make
go env | grep GOFLAGS
GOFLAGS=""
Shouldn't the lines after .EXPORT_ALL_VARIABLES
be tab-indented? Why lay it out like that if it's not a real target?
The lines following the .EXPORT_ALL_VARIABLES:
pseudo-target are not a recipe, and should not be indented. In fact, if they are then the variables will not be exported.
While .EXPORT_ALL_VARIABLES
can in fact appear anywhere in the Makefile and will apply the export behaviour to all variables, we recommend the convention of including those variables for which we specifically need the export behaviour directly underneath the pseudo-target.
This convention, although I have not found it discussed anywhere, seems to be in use in the Makefiles of popular Go projects, e.g.: https://github.com/kubernetes/kubernetes/blob/598c279ecc078df87e745afdb5ef1279adfa4014/build/root/Makefile#L40
Yes, this works, except it causes a syntax error in old versions of make, so the manual recommends use of .EXPORT_ALL_VARIABLES
instead. Realistically, both are probably fine for your situation.
A special mention goes out to terraform-provider-powerdns
for being the only provider in the terraform-providers
org to have set up the Makefile correctly prior to this memo.