I’ve been writing Go for a while now – according to my git log I committed my first go code in August of 2013. Go 1.0 was released in March of 2012. So things have changed quite a bit since I first started writing.
I’m not one to say that any language is perfect, where there exists code and time there will be warts. But I have genuinely enjoyed my experience with the language and still consider it my go-to nearly 9 years later.
Yet!
Things have changed significantly since I first started slinging errs.
Dep is no more and go mod
rules the land of dependencies. GOROOT
is
no longer recommended to be set – in fact it’s best not to. go get
is no longer the standard way to install binary packages, rendering much
of the documentation on the web, and quite a few Makefiles, as no longer
working.
This article is about the no longer needed environment variable GOPATH
.
If you are familiar with Go development from the days of yore, you may
remember setting it with every project. It was, honestly, kind of
annoying. I’m quite happy to see it no longer necessary.
But it does leave new package layouts in a bit of a quandary. So let’s look at a sample project’s layout to see how to make this work as expected.
cschmidt@kitai ~/src/myproj_src ❄ tree
.
├── go.mod
├── mylib
│ ├── libfile1.go
│ └── libfile2.go
├── Makefile
└── cmd
├── cmd.go
in my go.mod file, you find:
cschmidt@kitai ~/src/myproj_src ❄ cat go.mod
module myproj_src
go 1.18
Now something that tripped me up is that you might expect this to work:
go build cmd/
package cmd is not in GOROOT (/home/cschmidt/go/go1.18.1/src/cmd)
but it doesn’t because it’s assuming the prefix is where I installed go, since there’s no GOPATH.
So then I think this might work:
cschmidt@kitai ~/src/myproj_src ❄ go build ./cmd/
go: build output "cmd" already exists and is a directory
but it doesn’t because the binary that it builds is output to the same name as the existing directory, and the compiler refuses to do that.
One option at this point is to drop to a Makefile. This simple Makefile looks like:
cschmidt@kitai ~/src/myproj_src ❄ cat Makefile
default:
cd cmd/ && go build
clean:
rm -rf cmd/cmd
which will certainly work.
Another cleaner option is to do
mkdir -p bin/
go build -o bin ./...
and that will build all the binaries that are in the packages in this
directory, and put them in bin. This is the closest to what we had
with $GOPATH
, so this is what I want.
🎉