anatoly techtonik
anatoly techtonik

Reputation: 20549

Detect GOPATH from project Makefile

If GOPATH is not set, compilation for go programs is impossible. But many go projects are built using Makefiles, because go also miss capabilities to extract git revision, set version etc. So it should be possible to detect GOPATH from Makefile automatically.

Suppose I set my GOPATH manually one time for go get -d:

go get -d github.com/zyedidia/micro/cmd/micro

Now if I open another session, cd into github.com/zyedidia/micro/cmd/micro and do make build, the build fails:

...
cmd/micro/micro.go:20:2: cannot find package "layeh.com/gopher-luar" in any of:
    /usr/lib/go-1.7/src/layeh.com/gopher-luar (from $GOROOT)
    ($GOPATH not set)
Makefile:15: recipe for target 'build' failed
make: *** [build] Error 1

So, if GOPATH is not set, how can I set it from the Makefile and make sure that there is go environment at this point?

This doesn't work:

GOPATH ?= ../../../..

UPDATE: The following code works, but it doesn't detect that parent directory contains src, bin and pkg dirs.

export GOPATH ?= $(abspath $(dir ../../../../..))

export is needed to transform make variable into environment variable, ?= sets make variable only of it is not set, abspath and dir are described here:

Upvotes: 1

Views: 5160

Answers (2)

ianwoolf
ianwoolf

Reputation: 109

I met the same problem, here is my solution:

ifndef $(GOPATH)
    GOPATH=$(shell go env GOPATH)
    export GOPATH
endif

Upvotes: 11

anatoly techtonik
anatoly techtonik

Reputation: 20549

Here is the solution.

# detect GOPATH if not set
ifndef $(GOPATH)
    $(info GOPATH is not set, autodetecting..)
    TESTPATH := $(dir $(abspath ../../..))
    DIRS := bin pkg src
    # create a ; separated line of tests and pass it to shell
    MISSING_DIRS := $(shell $(foreach entry,$(DIRS),test -d "$(TESTPATH)$(entry)" || echo "$(entry)";))
    ifeq ($(MISSING_DIRS),)
        $(info Found GOPATH: $(TESTPATH))
        export GOPATH := $(TESTPATH)
    else
        $(info ..missing dirs "$(MISSING_DIRS)" in "$(TESTDIR)")
        $(info GOPATH autodetection failed)
    endif
endif

What I've learned:

  • variables are defines in a separate block
  • tabs are not allowed in the block that defines variables
  • echo doesn't work in this block, need to use $(info)

Upvotes: 0

Related Questions