168

The docs say nothing about what build vs install does

My expectation was that it's like make install; i.e. it takes the compiled stuff and puts in its final location (/usr/local/bin/my_new_toy or whatever) but it seems that it puts things in GOROOT/bin

Can I tell go to do a make install - i.e. put things elsewhere? Or do I just write a makefile (please tell me no)?

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
pm100
  • 48,078
  • 23
  • 82
  • 145

2 Answers2

116

go build vs go install:

go build just compiles the executable file and moves it to the destination. go install does a little bit more. It moves the executable file to $GOPATH/bin and caches all non-main packages which are imported to $GOPATH/pkg. The cache will be used during the next compilation provided the source did not change yet.


A package tree after go build and go install:

.
├── bin
│   └── hello  # by go install
└── src 
    └── hello
        ├── hello  # by go build
        └── hello.go

More detailed information.

Benyamin Jafari
  • 27,880
  • 26
  • 135
  • 150
  • 4
    Does `go install` also builds? Or do I need to run `go build` before installing? – Rafael Eyng Mar 11 '19 at 01:33
  • 4
    @RafaelEyng No, `go install` is enough, but its exec file creates in `bin/` directory – Benyamin Jafari Mar 11 '19 at 05:52
  • 3
    I have a project where I type 'go install' and nothing happens. No error message, just nothing. What's going on? – user2023370 Jan 27 '21 at 22:04
  • 3
    Whats the usecase for `go install`? As I understand the result of `go build` can be distributed and run on different machines whereas `go install` needs the sourcecode and installs the go program locally. – fabs Jun 14 '21 at 13:20
  • 6
    @fabs The usecase is that you have written a tool in Go that you want to use yourself. You want to just be able to do `mytool foo` at the terminal, so you add `$GOPATH/bin` to your terminal's `PATH` and then `go install` makes the magic happen. – Keeley Hoek Jan 05 '22 at 13:45
  • @KeeleyHoek thanks for this, so you would not use `go install` in a build pipeline for example, only `go build`. – Amc_rtty Jan 17 '22 at 21:39
  • My experience on Linux (Mint/Ubuntu) is that it goes to ~/go/bin without any $GO* variables – Software Prophets May 26 '22 at 19:16
  • `go env` helps debugging: I forgot that I was using Asdf, which needs a "reshim" call after binary installs. @user2023370: it logs nothing if the package is already installed. The first install call should show some downloads. – Eric Burel Apr 26 '23 at 09:51
  • Clean explanation. TY – Jukka Newkampton Jun 23 '23 at 15:01
98

If you want binary files to go to a specific location, you can use the environment variable GOBIN :

The bin/ directory holds compiled commands. Each command is named for its source directory, but only the final element, not the entire path. That is, the command with source in DIR/src/foo/quux is installed into DIR/bin/quux, not DIR/bin/foo/quux. The foo/ is stripped so that you can add DIR/bin to your PATH to get at the installed commands. If the GOBIN environment variable is set, commands are installed to the directory it names instead of DIR/bin.

Source : http://golang.org/cmd/go/#hdr-GOPATH_environment_variable

GOBIN=/usr/local/bin/ go install

If you want per-project bin/ directory then you can simply append your project path to GOPATH, however you must have your code under $project-path/src/ and go install will put all the binaries in $project-path/bin.

export GOPATH=/dir1:/dir2:/dir3

If GOBIN is not set, binaries from /dir1/src end up in /dir1/bin, binaries from /dir2/src end up in /dir2/bin, and so on (and binaries from $GOROOT/src end up in $GOROOT/bin).

Source : https://groups.google.com/forum/#!topic/golang-nuts/-mN8R_Fx-7M

And you can also just use (thanks JimB):

go build -o /path/binary-name
init_js
  • 4,143
  • 2
  • 23
  • 53
OneOfOne
  • 95,033
  • 20
  • 184
  • 185